summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community')
-rw-r--r--ansible_collections/community/aws/.github/workflows/docs-pr.yml3
-rw-r--r--ansible_collections/community/aws/.github/workflows/sanity.yml1
-rw-r--r--ansible_collections/community/aws/CHANGELOG.rst52
-rw-r--r--ansible_collections/community/aws/FILES.json87
-rw-r--r--ansible_collections/community/aws/MANIFEST.json8
-rw-r--r--ansible_collections/community/aws/README.md6
-rw-r--r--ansible_collections/community/aws/changelogs/changelog.yaml120
-rw-r--r--ansible_collections/community/aws/docs/docsite/links.yml2
-rw-r--r--ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst52
-rw-r--r--ansible_collections/community/aws/meta/runtime.yml2
-rw-r--r--ansible_collections/community/aws/plugins/module_utils/common.py2
-rw-r--r--ansible_collections/community/aws/plugins/modules/autoscaling_launch_config.py2
-rw-r--r--ansible_collections/community/aws/plugins/modules/ecs_cluster.py6
-rw-r--r--ansible_collections/community/aws/plugins/modules/ecs_service.py4
-rw-r--r--ansible_collections/community/aws/plugins/modules/efs.py3
-rw-r--r--ansible_collections/community/aws/plugins/modules/elb_network_lb.py22
-rw-r--r--ansible_collections/community/aws/plugins/modules/glue_connection.py8
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/config/tasks/main.yaml14
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/ec2_launch_template/tasks/iam_instance_role.yml20
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/ecs_cluster/tasks/20_ecs_service.yml16
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/eks_cluster/tasks/full_test.yml10
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/create_eks_cluster.yml2
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/full_test.yml38
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/aliases3
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/dependecies.yml2
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/full_test.yml70
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/elb_network_lb/tasks/test_modifying_nlb_listeners.yml80
-rw-r--r--ansible_collections/community/aws/tests/integration/targets/elb_target/tasks/lambda_target.yml2
-rw-r--r--ansible_collections/community/aws/tests/sanity/ignore-2.10.txt0
-rw-r--r--ansible_collections/community/aws/tests/sanity/ignore-2.11.txt0
-rw-r--r--ansible_collections/community/aws/tests/sanity/ignore-2.12.txt0
-rw-r--r--ansible_collections/community/aws/tests/sanity/ignore-2.13.txt0
-rw-r--r--ansible_collections/community/aws/tests/sanity/ignore-2.9.txt0
-rw-r--r--ansible_collections/community/azure/.azure-pipelines/README.md3
-rw-r--r--ansible_collections/community/azure/.azure-pipelines/azure-pipelines.yml61
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/aggregate-coverage.sh20
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/combine-coverage.py60
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/process-results.sh24
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/publish-codecov.sh27
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/report-coverage.sh15
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/run-tests.sh34
-rwxr-xr-xansible_collections/community/azure/.azure-pipelines/scripts/time-command.py25
-rw-r--r--ansible_collections/community/azure/.azure-pipelines/templates/coverage.yml39
-rw-r--r--ansible_collections/community/azure/.azure-pipelines/templates/matrix.yml55
-rw-r--r--ansible_collections/community/azure/.azure-pipelines/templates/test.yml45
-rw-r--r--ansible_collections/community/azure/CHANGELOG.rst108
-rw-r--r--ansible_collections/community/azure/COPYING675
-rw-r--r--ansible_collections/community/azure/FILES.json334
-rw-r--r--ansible_collections/community/azure/MANIFEST.json32
-rw-r--r--ansible_collections/community/azure/README.md39
-rw-r--r--ansible_collections/community/azure/changelogs/changelog.yaml228
-rw-r--r--ansible_collections/community/azure/changelogs/config.yaml29
-rw-r--r--ansible_collections/community/azure/changelogs/fragments/.keep0
-rw-r--r--ansible_collections/community/azure/meta/action_groups.yml27
-rw-r--r--ansible_collections/community/azure/meta/runtime.yml596
-rw-r--r--ansible_collections/community/azure/shippable.yml37
-rw-r--r--ansible_collections/community/azure/tests/.gitignore1
-rw-r--r--ansible_collections/community/azure/tests/sanity/ignore-2.10.txt2
-rw-r--r--ansible_collections/community/azure/tests/sanity/ignore-2.11.txt2
-rw-r--r--ansible_collections/community/azure/tests/sanity/ignore-2.12.txt2
-rw-r--r--ansible_collections/community/azure/tests/sanity/ignore-2.13.txt2
-rw-r--r--ansible_collections/community/azure/tests/sanity/ignore-2.14.txt2
-rwxr-xr-xansible_collections/community/azure/tests/utils/ado/ado.sh124
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/azure.sh19
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/check_matrix.py120
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/cloud.sh19
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/sanity.sh27
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/shippable.sh203
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/timing.py16
-rwxr-xr-xansible_collections/community/azure/tests/utils/shippable/timing.sh5
-rw-r--r--ansible_collections/community/ciscosmb/.github/workflows/CI.yml81
-rw-r--r--ansible_collections/community/ciscosmb/.github/workflows/FastCI.yml74
-rw-r--r--ansible_collections/community/ciscosmb/CHANGELOG.rst52
-rw-r--r--ansible_collections/community/ciscosmb/FILES.json20
-rw-r--r--ansible_collections/community/ciscosmb/MANIFEST.json4
-rw-r--r--ansible_collections/community/ciscosmb/README.md9
-rw-r--r--ansible_collections/community/ciscosmb/changelogs/changelog.yaml38
-rw-r--r--ansible_collections/community/ciscosmb/changelogs/fragments/.keep2
-rw-r--r--ansible_collections/community/ciscosmb/plugins/modules/facts.py13
-rw-r--r--ansible_collections/community/ciscosmb/plugins/terminal/ciscosmb.py3
-rw-r--r--ansible_collections/community/ciscosmb/tests/unit/compat/mock.py6
-rw-r--r--ansible_collections/community/ciscosmb/tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py7
-rw-r--r--ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml2
-rw-r--r--ansible_collections/community/crypto/.github/workflows/ansible-test.yml3
-rw-r--r--ansible_collections/community/crypto/CHANGELOG.md617
-rw-r--r--ansible_collections/community/crypto/CHANGELOG.rst94
-rw-r--r--ansible_collections/community/crypto/FILES.json332
-rw-r--r--ansible_collections/community/crypto/MANIFEST.json4
-rw-r--r--ansible_collections/community/crypto/README.md2
-rw-r--r--ansible_collections/community/crypto/changelogs/changelog.yaml67
-rw-r--r--ansible_collections/community/crypto/changelogs/config.yaml3
-rw-r--r--ansible_collections/community/crypto/meta/runtime.yml1
-rw-r--r--ansible_collections/community/crypto/plugins/doc_fragments/acme.py178
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/acme.py91
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/backend_cryptography.py97
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/backend_openssl_cli.py95
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/backends.py102
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/challenges.py12
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/orders.py6
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/acme/utils.py58
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/argspec.py75
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/math.py31
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate.py4
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_entrust.py14
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py5
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py20
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_selfsigned.py20
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/common.py33
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/csr.py4
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey.py4
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey_convert.py6
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/crypto/support.py92
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py18
-rw-r--r--ansible_collections/community/crypto/plugins/module_utils/time.py171
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_account.py22
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_account_info.py22
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_ari_info.py142
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_certificate.py192
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_certificate_deactivate_authz.py119
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_certificate_renewal_info.py245
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_certificate_revoke.py18
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_challenge_cert_helper.py8
-rw-r--r--ansible_collections/community/crypto/plugins/modules/acme_inspect.py19
-rw-r--r--ansible_collections/community/crypto/plugins/modules/ecs_certificate.py4
-rw-r--r--ansible_collections/community/crypto/plugins/modules/get_certificate.py8
-rw-r--r--ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py8
-rw-r--r--ansible_collections/community/crypto/plugins/modules/x509_crl.py5
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/aliases10
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/meta/main.yml8
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/impl.yml154
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/main.yml40
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml17
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/aliases10
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/meta/main.yml8
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/impl.yml145
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/main.yml40
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/obtain-cert.yml159
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tests/validate.yml47
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/acme_inspect/tasks/impl.yml10
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/ownca.yml16
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/selfsigned.yml12
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_ownca.yml5
-rw-r--r--ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_selfsigned.yml5
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/backend_data.py89
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt38
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt.license3
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt57
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt.license3
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem19
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem.license3
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt56
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt.license3
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_cryptography.py57
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_openssl_cli.py59
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_utils.py97
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/crypto/test_math.py117
-rw-r--r--ansible_collections/community/crypto/tests/unit/plugins/module_utils/test_time.py323
-rw-r--r--ansible_collections/community/dns/.github/workflows/ansible-test.yml65
-rw-r--r--ansible_collections/community/dns/.github/workflows/ee.yml18
-rw-r--r--ansible_collections/community/dns/.github/workflows/extra-tests.yml9
-rw-r--r--ansible_collections/community/dns/CHANGELOG.md412
-rw-r--r--ansible_collections/community/dns/CHANGELOG.rst39
-rw-r--r--ansible_collections/community/dns/FILES.json74
-rw-r--r--ansible_collections/community/dns/MANIFEST.json8
-rw-r--r--ansible_collections/community/dns/README.md3
-rw-r--r--ansible_collections/community/dns/changelogs/changelog.yaml49
-rw-r--r--ansible_collections/community/dns/docs/docsite/rst/hetzner_guide.rst2
-rw-r--r--ansible_collections/community/dns/meta/runtime.yml6
-rw-r--r--ansible_collections/community/dns/plugins/doc_fragments/inventory_records.py7
-rw-r--r--ansible_collections/community/dns/plugins/doc_fragments/options.py5
-rw-r--r--ansible_collections/community/dns/plugins/inventory/hetzner_dns_records.py12
-rw-r--r--ansible_collections/community/dns/plugins/inventory/hosttech_dns_records.py11
-rw-r--r--ansible_collections/community/dns/plugins/lookup/lookup.py19
-rw-r--r--ansible_collections/community/dns/plugins/lookup/lookup_as_dict.py19
-rw-r--r--ansible_collections/community/dns/plugins/module_utils/conversion/converter.py16
-rw-r--r--ansible_collections/community/dns/plugins/module_utils/options.py2
-rw-r--r--ansible_collections/community/dns/plugins/module_utils/provider.py4
-rw-r--r--ansible_collections/community/dns/plugins/module_utils/resolver.py9
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py7
-rw-r--r--ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py7
-rw-r--r--ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py129
-rw-r--r--ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py26
-rw-r--r--ansible_collections/community/dns/plugins/public_suffix_list.dat132
-rw-r--r--ansible_collections/community/dns/tests/integration/targets/filter_txt/tasks/main.yml44
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/inventory/test_hetzner_dns_records.py4
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/inventory/test_hosttech_dns_records.py4
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup.py102
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup_as_dict.py97
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/module_utils/resolver_helper.py3
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/modules/test_hetzner_dns_record_set_info.py19
-rw-r--r--ansible_collections/community/dns/tests/unit/plugins/plugin_utils/test_unsafe.py133
-rw-r--r--ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml2
-rw-r--r--ansible_collections/community/docker/.github/workflows/ansible-test.yml3
-rw-r--r--ansible_collections/community/docker/CHANGELOG.md684
-rw-r--r--ansible_collections/community/docker/CHANGELOG.rst108
-rw-r--r--ansible_collections/community/docker/FILES.json114
-rw-r--r--ansible_collections/community/docker/MANIFEST.json4
-rw-r--r--ansible_collections/community/docker/README.md3
-rw-r--r--ansible_collections/community/docker/changelogs/changelog.yaml96
-rw-r--r--ansible_collections/community/docker/changelogs/config.yaml2
-rw-r--r--ansible_collections/community/docker/docs/docsite/rst/scenario_guide.rst7
-rw-r--r--ansible_collections/community/docker/meta/runtime.yml7
-rw-r--r--ansible_collections/community/docker/plugins/connection/docker.py2
-rw-r--r--ansible_collections/community/docker/plugins/connection/docker_api.py1
-rw-r--r--ansible_collections/community/docker/plugins/connection/nsenter.py4
-rw-r--r--ansible_collections/community/docker/plugins/doc_fragments/docker.py9
-rw-r--r--ansible_collections/community/docker/plugins/inventory/docker_containers.py1
-rw-r--r--ansible_collections/community/docker/plugins/inventory/docker_swarm.py3
-rw-r--r--ansible_collections/community/docker/plugins/module_utils/_api/transport/basehttpadapter.py12
-rw-r--r--ansible_collections/community/docker/plugins/module_utils/module_container/base.py2
-rw-r--r--ansible_collections/community/docker/plugins/module_utils/module_container/docker_api.py18
-rw-r--r--ansible_collections/community/docker/plugins/module_utils/selectors.py21
-rw-r--r--ansible_collections/community/docker/plugins/module_utils/util.py15
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_compose.py5
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_container.py19
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_container_exec.py3
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_image_build.py247
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_network.py35
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_prune.py60
-rw-r--r--ansible_collections/community/docker/plugins/modules/docker_swarm_service.py16
-rw-r--r--ansible_collections/community/docker/plugins/plugin_utils/socket_handler.py2
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/main.yml3
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_compose_v2_pull/tasks/main.yml6
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/test.yml12
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/tests/options.yml85
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_image_build/templates/SecretsDockerfile7
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_prune/tasks/main.yml22
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/docker_swarm_service/vars/main.yml1
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/generic_connection_tests/tasks/main.yml3
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/setup_docker/tasks/main.yml3
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/setup_docker_cli_compose/tasks/main.yml3
-rw-r--r--ansible_collections/community/docker/tests/integration/targets/setup_docker_compose_v1/vars/Alpine.yml2
-rw-r--r--ansible_collections/community/docker/tests/sanity/ignore-2.11.txt1
-rw-r--r--ansible_collections/community/docker/tests/sanity/ignore-2.12.txt1
-rw-r--r--ansible_collections/community/docker/tests/sanity/ignore-2.13.txt1
-rw-r--r--ansible_collections/community/docker/tests/sanity/ignore-2.14.txt1
-rw-r--r--ansible_collections/community/docker/tests/sanity/ignore-2.15.txt1
-rw-r--r--ansible_collections/community/docker/tests/sanity/ignore-2.16.txt1
-rw-r--r--ansible_collections/community/docker/tests/unit/plugins/plugin_utils/test_unsafe.py133
-rw-r--r--ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml6
-rw-r--r--ansible_collections/community/general/.github/BOTMETA.yml60
-rw-r--r--ansible_collections/community/general/.github/workflows/ansible-test.yml3
-rw-r--r--ansible_collections/community/general/.gitignore4
-rw-r--r--ansible_collections/community/general/CHANGELOG.md916
-rw-r--r--ansible_collections/community/general/CHANGELOG.rst848
-rw-r--r--ansible_collections/community/general/CONTRIBUTING.md4
-rw-r--r--ansible_collections/community/general/FILES.json629
-rw-r--r--ansible_collections/community/general/MANIFEST.json4
-rw-r--r--ansible_collections/community/general/README.md9
-rw-r--r--ansible_collections/community/general/changelogs/changelog.yaml1808
-rw-r--r--ansible_collections/community/general/changelogs/config.yaml3
-rw-r--r--ansible_collections/community/general/meta/runtime.yml4099
-rw-r--r--ansible_collections/community/general/plugins/become/machinectl.py13
-rw-r--r--ansible_collections/community/general/plugins/become/run0.py128
-rw-r--r--ansible_collections/community/general/plugins/callback/opentelemetry.py94
-rw-r--r--ansible_collections/community/general/plugins/callback/timestamp.py127
-rw-r--r--ansible_collections/community/general/plugins/callback/yaml.py10
-rw-r--r--ansible_collections/community/general/plugins/doc_fragments/consul.py1
-rw-r--r--ansible_collections/community/general/plugins/doc_fragments/django.py53
-rw-r--r--ansible_collections/community/general/plugins/doc_fragments/proxmox.py10
-rw-r--r--ansible_collections/community/general/plugins/doc_fragments/rackspace.py120
-rw-r--r--ansible_collections/community/general/plugins/lookup/merge_variables.py7
-rw-r--r--ansible_collections/community/general/plugins/module_utils/cmd_runner.py11
-rw-r--r--ansible_collections/community/general/plugins/module_utils/django.py85
-rw-r--r--ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py8
-rw-r--r--ansible_collections/community/general/plugins/module_utils/gitlab.py5
-rw-r--r--ansible_collections/community/general/plugins/module_utils/homebrew.py115
-rw-r--r--ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py47
-rw-r--r--ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py6
-rw-r--r--ansible_collections/community/general/plugins/module_utils/mh/module_helper.py42
-rw-r--r--ansible_collections/community/general/plugins/module_utils/module_helper.py10
-rw-r--r--ansible_collections/community/general/plugins/module_utils/puppet.py1
-rw-r--r--ansible_collections/community/general/plugins/module_utils/python_runner.py34
-rw-r--r--ansible_collections/community/general/plugins/module_utils/rax.py334
-rw-r--r--ansible_collections/community/general/plugins/module_utils/redhat.py240
-rw-r--r--ansible_collections/community/general/plugins/module_utils/rundeck.py4
-rw-r--r--ansible_collections/community/general/plugins/module_utils/vardict.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/aix_lvol.py19
-rw-r--r--ansible_collections/community/general/plugins/modules/ansible_galaxy_install.py60
-rw-r--r--ansible_collections/community/general/plugins/modules/apt_rpm.py30
-rw-r--r--ansible_collections/community/general/plugins/modules/btrfs_subvolume.py9
-rw-r--r--ansible_collections/community/general/plugins/modules/cloudflare_dns.py8
-rw-r--r--ansible_collections/community/general/plugins/modules/consul_policy.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/consul_role.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/consul_session.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/consul_token.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/cpanm.py26
-rw-r--r--ansible_collections/community/general/plugins/modules/django_command.py83
-rw-r--r--ansible_collections/community/general/plugins/modules/django_manage.py92
-rw-r--r--ansible_collections/community/general/plugins/modules/flowdock.py211
-rw-r--r--ansible_collections/community/general/plugins/modules/gandi_livedns.py37
-rw-r--r--ansible_collections/community/general/plugins/modules/gconftool2.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/gconftool2_info.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/gitlab_runner.py53
-rw-r--r--ansible_collections/community/general/plugins/modules/homebrew.py157
-rw-r--r--ansible_collections/community/general/plugins/modules/homebrew_cask.py70
-rw-r--r--ansible_collections/community/general/plugins/modules/hponcfg.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/installp.py13
-rw-r--r--ansible_collections/community/general/plugins/modules/irc.py31
-rw-r--r--ansible_collections/community/general/plugins/modules/kernel_blacklist.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/keycloak_client.py5
-rw-r--r--ansible_collections/community/general/plugins/modules/keycloak_identity_provider.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/keycloak_user_federation.py3
-rw-r--r--ansible_collections/community/general/plugins/modules/ldap_search.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/locale_gen.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/lvg.py22
-rw-r--r--ansible_collections/community/general/plugins/modules/lvol.py84
-rw-r--r--ansible_collections/community/general/plugins/modules/lxd_container.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/macports.py12
-rw-r--r--ansible_collections/community/general/plugins/modules/mksysb.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/opkg.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/parted.py9
-rw-r--r--ansible_collections/community/general/plugins/modules/pipx.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/pipx_info.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/pkg5.py15
-rw-r--r--ansible_collections/community/general/plugins/modules/pkgin.py25
-rw-r--r--ansible_collections/community/general/plugins/modules/portinstall.py26
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox.py47
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_disk.py3
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_domain_info.py4
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_group_info.py4
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_kvm.py17
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_nic.py3
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_node_info.py4
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_pool.py7
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_pool_member.py7
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_snap.py7
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_storage_contents_info.py4
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_storage_info.py4
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_tasks_info.py10
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_template.py3
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_user_info.py4
-rw-r--r--ansible_collections/community/general/plugins/modules/proxmox_vm_info.py10
-rw-r--r--ansible_collections/community/general/plugins/modules/puppet.py19
-rw-r--r--ansible_collections/community/general/plugins/modules/rax.py903
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_cbs.py235
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_cbs_attachments.py226
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_cdb.py266
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_cdb_database.py179
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_cdb_user.py227
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_clb.py320
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_clb_nodes.py291
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_clb_ssl.py289
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_dns.py180
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_dns_record.py358
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_facts.py152
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_files.py400
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_files_objects.py556
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_identity.py110
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_keypair.py179
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_meta.py182
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_mon_alarm.py235
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_mon_check.py329
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_mon_entity.py201
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_mon_notification.py182
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_mon_notification_plan.py191
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_network.py146
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_queue.py147
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_scaling_group.py441
-rw-r--r--ansible_collections/community/general/plugins/modules/rax_scaling_policy.py294
-rw-r--r--ansible_collections/community/general/plugins/modules/redfish_command.py17
-rw-r--r--ansible_collections/community/general/plugins/modules/redfish_config.py17
-rw-r--r--ansible_collections/community/general/plugins/modules/redfish_info.py17
-rw-r--r--ansible_collections/community/general/plugins/modules/redhat_subscription.py15
-rw-r--r--ansible_collections/community/general/plugins/modules/slackpkg.py18
-rw-r--r--ansible_collections/community/general/plugins/modules/snap.py5
-rw-r--r--ansible_collections/community/general/plugins/modules/snap_alias.py1
-rw-r--r--ansible_collections/community/general/plugins/modules/stackdriver.py228
-rw-r--r--ansible_collections/community/general/plugins/modules/svr4pkg.py2
-rw-r--r--ansible_collections/community/general/plugins/modules/swdepot.py17
-rw-r--r--ansible_collections/community/general/plugins/modules/webfaction_app.py213
-rw-r--r--ansible_collections/community/general/plugins/modules/webfaction_db.py209
-rw-r--r--ansible_collections/community/general/plugins/modules/webfaction_domain.py184
-rw-r--r--ansible_collections/community/general/plugins/modules/webfaction_mailbox.py152
-rw-r--r--ansible_collections/community/general/plugins/modules/webfaction_site.py223
-rw-r--r--ansible_collections/community/general/plugins/modules/xfconf.py3
-rw-r--r--ansible_collections/community/general/plugins/modules/xfconf_info.py3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_timestamp/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_timestamp/tasks/main.yml66
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/handlers/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/docker.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml1
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_inventory.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_play.yml21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml43
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.13.txt5
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.14.txt5
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.15.txt3
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.16.txt3
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.17.txt4
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.18.txt4
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/become/test_run0.py64
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/lookup/test_merge_variables.py182
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/module_utils/test_cmd_runner.py82
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/module_utils/test_python_runner.py223
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/modules/helper.py24
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/modules/test_cpanm.yaml5
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.py13
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.yaml38
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/modules/test_homebrew.py19
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/modules/test_puppet.yaml32
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/plugin_utils/test_unsafe.py133
-rw-r--r--ansible_collections/community/grafana/.github/workflows/ansible-test.yml6
-rw-r--r--ansible_collections/community/grafana/CHANGELOG.rst30
-rw-r--r--ansible_collections/community/grafana/FILES.json187
-rw-r--r--ansible_collections/community/grafana/MANIFEST.json4
-rw-r--r--ansible_collections/community/grafana/README.md3
-rw-r--r--ansible_collections/community/grafana/changelogs/changelog.yaml33
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/353-docs-add-influxdb-flux-example.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/354-fix-find-grafana-versions.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/355-rm-dashboard-message-argument.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/356-lookup-dashboards-add-custom-certs-verification-logic.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/357-module-grafana-silence.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/358-role-grafana-silence.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/362-plugin-umask.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/364-first-datasource-default.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/367-dashboard-undo-breaing-change-message.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/368-molecule-pin-requests.yml3
-rwxr-xr-xansible_collections/community/grafana/hacking/check_fragment.sh6
-rw-r--r--ansible_collections/community/grafana/hacking/find_grafana_versions.py31
-rw-r--r--ansible_collections/community/grafana/meta/runtime.yml1
-rw-r--r--ansible_collections/community/grafana/molecule/default/converge.yml11
-rw-r--r--ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py52
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_datasource.py23
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_plugin.py2
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_silence.py369
-rw-r--r--ansible_collections/community/grafana/roles/grafana/README.md7
-rw-r--r--ansible_collections/community/grafana/roles/grafana/defaults/main.yml1
-rw-r--r--ansible_collections/community/grafana/roles/grafana/meta/main.yml2
-rw-r--r--ansible_collections/community/grafana/roles/grafana/tasks/main.yml12
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml26
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml2
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_silence/defaults/main.yml5
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_silence/runme.sh5
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_silence/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_silence/tasks/main.yml89
-rw-r--r--ansible_collections/community/grafana/tests/sanity/ignore-2.15.txt3
-rw-r--r--ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt3
-rw-r--r--ansible_collections/community/grafana/tests/sanity/ignore-2.18.txt1
-rw-r--r--ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py2
-rw-r--r--ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_silence/test_grafana_silence.py211
-rw-r--r--ansible_collections/community/hrobot/.github/workflows/ansible-test.yml38
-rw-r--r--ansible_collections/community/hrobot/.github/workflows/ee.yml18
-rw-r--r--ansible_collections/community/hrobot/.github/workflows/extra-tests.yml9
-rw-r--r--ansible_collections/community/hrobot/CHANGELOG.md156
-rw-r--r--ansible_collections/community/hrobot/CHANGELOG.rst28
-rw-r--r--ansible_collections/community/hrobot/FILES.json20
-rw-r--r--ansible_collections/community/hrobot/MANIFEST.json8
-rw-r--r--ansible_collections/community/hrobot/README.md2
-rw-r--r--ansible_collections/community/hrobot/changelogs/changelog.yaml31
-rw-r--r--ansible_collections/community/hrobot/meta/runtime.yml2
-rw-r--r--ansible_collections/community/hrobot/plugins/inventory/robot.py54
-rw-r--r--ansible_collections/community/hrobot/tests/unit/plugins/inventory/test_robot.py2
-rw-r--r--ansible_collections/community/mongodb/CHANGELOG.rst13
-rw-r--r--ansible_collections/community/mongodb/FILES.json8
-rw-r--r--ansible_collections/community/mongodb/MANIFEST.json4
-rw-r--r--ansible_collections/community/mongodb/README.md1
-rw-r--r--ansible_collections/community/mongodb/changelogs/changelog.yaml5
-rw-r--r--ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py27
-rw-r--r--ansible_collections/community/okd/.config/ansible-lint.yml5
-rw-r--r--ansible_collections/community/okd/.github/patchback.yml4
-rw-r--r--ansible_collections/community/okd/.github/settings.yml6
-rw-r--r--ansible_collections/community/okd/.github/stale.yml60
-rw-r--r--ansible_collections/community/okd/.github/workflows/changelog.yml23
-rw-r--r--ansible_collections/community/okd/.github/workflows/linters.yml29
-rw-r--r--ansible_collections/community/okd/.github/workflows/sanity-tests.yml23
-rw-r--r--ansible_collections/community/okd/.github/workflows/unit-tests.yml21
-rw-r--r--ansible_collections/community/okd/.yamllint44
-rw-r--r--ansible_collections/community/okd/CHANGELOG.rst28
-rw-r--r--ansible_collections/community/okd/FILES.json770
-rw-r--r--ansible_collections/community/okd/MANIFEST.json6
-rw-r--r--ansible_collections/community/okd/Makefile4
-rw-r--r--ansible_collections/community/okd/OWNERS_ALIASES8
-rw-r--r--ansible_collections/community/okd/README.md33
-rw-r--r--ansible_collections/community/okd/changelogs/.plugin-cache.yaml92
-rw-r--r--ansible_collections/community/okd/changelogs/changelog.yaml25
-rw-r--r--ansible_collections/community/okd/changelogs/config.yaml32
-rw-r--r--ansible_collections/community/okd/ci/Dockerfile20
-rwxr-xr-xansible_collections/community/okd/ci/downstream.sh11
-rw-r--r--ansible_collections/community/okd/docs/community.okd.k8s_module.rst72
-rw-r--r--ansible_collections/community/okd/docs/community.okd.oc_connection.rst2
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_adm_groups_sync_module.rst107
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_adm_migrate_template_instances_module.rst67
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_auth_module.rst55
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_builds_module.rst2
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_deployments_module.rst57
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_images_module.rst55
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_auth_module.rst57
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_import_image_module.rst55
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_inventory.rst47
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_process_module.rst66
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_registry_info_module.rst57
-rw-r--r--ansible_collections/community/okd/docs/community.okd.openshift_route_module.rst67
-rw-r--r--ansible_collections/community/okd/meta/runtime.yml9
-rw-r--r--ansible_collections/community/okd/molecule/default/converge.yml14
-rw-r--r--ansible_collections/community/okd/molecule/default/files/pod-template.yaml16
-rw-r--r--ansible_collections/community/okd/molecule/default/files/simple-template.yaml36
-rw-r--r--ansible_collections/community/okd/molecule/default/molecule.yml9
-rw-r--r--ansible_collections/community/okd/molecule/default/prepare.yml12
-rw-r--r--ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py1
-rw-r--r--ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml444
-rw-r--r--ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml323
-rw-r--r--ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/main.yml47
-rw-r--r--ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml1
-rw-r--r--ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml907
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml575
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_roles.yml653
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_deployments.yml438
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_builds.yml477
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_import_images.yml335
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_prune_images.yml14
-rw-r--r--ansible_collections/community/okd/molecule/default/tasks/openshift_route.yml12
-rw-r--r--ansible_collections/community/okd/molecule/default/vars/main.yml22
-rw-r--r--ansible_collections/community/okd/plugins/connection/oc.py36
-rw-r--r--ansible_collections/community/okd/plugins/inventory/openshift.py137
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/k8s.py251
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_auth.py301
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_deployments.py55
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_images.py130
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_builds.py159
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_common.py18
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_docker_image.py59
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_groups.py209
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_images_common.py138
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_import_image.py134
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_ldap.py364
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_process.py14
-rw-r--r--ansible_collections/community/okd/plugins/module_utils/openshift_registry.py74
-rw-r--r--ansible_collections/community/okd/plugins/modules/k8s.py79
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_adm_groups_sync.py73
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_adm_migrate_template_instances.py28
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_adm_prune_auth.py43
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_adm_prune_builds.py36
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_adm_prune_deployments.py39
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_adm_prune_images.py44
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_auth.py237
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_build.py66
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_import_image.py41
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_process.py46
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_registry_info.py35
-rw-r--r--ansible_collections/community/okd/plugins/modules/openshift_route.py299
-rw-r--r--ansible_collections/community/okd/requirements.yml3
-rw-r--r--ansible_collections/community/okd/setup.cfg3
-rw-r--r--ansible_collections/community/okd/test-requirements.txt1
-rw-r--r--ansible_collections/community/okd/tests/config.yml3
-rw-r--r--ansible_collections/community/okd/tests/sanity/ignore-2.16.txt3
-rw-r--r--ansible_collections/community/okd/tests/sanity/ignore-2.17.txt3
-rw-r--r--ansible_collections/community/okd/tests/sanity/requirements.yml5
-rw-r--r--ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_dn.py42
-rw-r--r--ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_sync_config.py30
-rw-r--r--ansible_collections/community/okd/tests/unit/plugins/module_utils/test_openshift_docker_image.py74
-rw-r--r--ansible_collections/community/okd/tox.ini37
-rw-r--r--ansible_collections/community/postgresql/.azure-pipelines/azure-pipelines.yml41
-rw-r--r--ansible_collections/community/postgresql/CHANGELOG.rst18
-rw-r--r--ansible_collections/community/postgresql/CONTRIBUTING.md85
-rw-r--r--ansible_collections/community/postgresql/FILES.json25
-rw-r--r--ansible_collections/community/postgresql/MANIFEST.json4
-rw-r--r--ansible_collections/community/postgresql/README.md37
-rw-r--r--ansible_collections/community/postgresql/changelogs/changelog.yaml23
-rw-r--r--ansible_collections/community/postgresql/plugins/modules/postgresql_db.py2
-rw-r--r--ansible_collections/community/postgresql/plugins/modules/postgresql_ext.py5
-rw-r--r--ansible_collections/community/postgresql/plugins/modules/postgresql_idx.py5
-rw-r--r--ansible_collections/community/postgresql/plugins/modules/postgresql_privs.py2
-rw-r--r--ansible_collections/community/postgresql/tests/sanity/ignore-2.18.txt5
-rw-r--r--ansible_collections/community/sap/.github/ISSUE_TEMPLATE/bug_report.yml149
-rw-r--r--ansible_collections/community/sap/.github/ISSUE_TEMPLATE/config.yml27
-rw-r--r--ansible_collections/community/sap/.github/ISSUE_TEMPLATE/documentation_report.yml125
-rw-r--r--ansible_collections/community/sap/.github/ISSUE_TEMPLATE/feature_request.yml69
-rw-r--r--ansible_collections/community/sap/.github/workflows/ansible-test.yml126
-rw-r--r--ansible_collections/community/sap/.vscode/extensions.json5
-rw-r--r--ansible_collections/community/sap/CHANGELOG.rst87
-rw-r--r--ansible_collections/community/sap/CODE_OF_CONDUCT.md3
-rw-r--r--ansible_collections/community/sap/CONTRIBUTING.md3
-rw-r--r--ansible_collections/community/sap/FILES.json544
-rw-r--r--ansible_collections/community/sap/LICENSE674
-rw-r--r--ansible_collections/community/sap/MAINTAINERS2
-rw-r--r--ansible_collections/community/sap/MAINTAINING.md3
-rw-r--r--ansible_collections/community/sap/MANIFEST.json33
-rw-r--r--ansible_collections/community/sap/README.md181
-rw-r--r--ansible_collections/community/sap/REVIEW_CHECKLIST.md3
-rw-r--r--ansible_collections/community/sap/changelogs/changelog.yaml63
-rw-r--r--ansible_collections/community/sap/changelogs/config.yaml30
-rw-r--r--ansible_collections/community/sap/changelogs/fragments/.keep0
-rw-r--r--ansible_collections/community/sap/codecov.yml2
-rw-r--r--ansible_collections/community/sap/meta/runtime.yml33
-rw-r--r--ansible_collections/community/sap/plugins/doc_fragments/__init__.py0
-rw-r--r--ansible_collections/community/sap/plugins/module_utils/__init__.py0
-rw-r--r--ansible_collections/community/sap/plugins/modules/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/integration/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/integration/targets/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/sanity/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/compat/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/compat/builtins.py33
-rw-r--r--ansible_collections/community/sap/tests/unit/compat/mock.py122
-rw-r--r--ansible_collections/community/sap/tests/unit/compat/unittest.py38
-rw-r--r--ansible_collections/community/sap/tests/unit/mock/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/mock/loader.py102
-rw-r--r--ansible_collections/community/sap/tests/unit/mock/path.py8
-rw-r--r--ansible_collections/community/sap/tests/unit/mock/procenv.py76
-rw-r--r--ansible_collections/community/sap/tests/unit/mock/vault_helper.py27
-rw-r--r--ansible_collections/community/sap/tests/unit/mock/yaml_helper.py126
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/database/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/test_hana_query.py102
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/files/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/files/test_sapcar_extract.py53
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_company.py136
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_user.py189
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/system/__init__.py0
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_snote.py181
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_system_facts.py106
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_task_list_execute.py89
-rw-r--r--ansible_collections/community/sap/tests/unit/plugins/modules/utils.py52
-rw-r--r--ansible_collections/community/sap/tests/unit/requirements.txt7
-rw-r--r--ansible_collections/community/vmware/.github/workflows/ansible-test.yml4
-rw-r--r--ansible_collections/community/vmware/CHANGELOG.rst15
-rw-r--r--ansible_collections/community/vmware/FILES.json34
-rw-r--r--ansible_collections/community/vmware/MANIFEST.json4
-rw-r--r--ansible_collections/community/vmware/changelogs/changelog.yaml17
-rw-r--r--ansible_collections/community/vmware/plugins/module_utils/vmware.py8
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py2
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py2
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_datacenter_info.py2
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py1
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_dvs_portgroup.py7
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_dvswitch_info.py1
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_guest_info.py1
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_host_facts.py1
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_vcenter_settings_info.py2
-rw-r--r--ansible_collections/community/vmware/plugins/modules/vmware_vsan_health_info.py5
-rw-r--r--ansible_collections/community/vmware/requirements.txt2
-rw-r--r--ansible_collections/community/vmware/tests/integration/targets/vmware_content_library_manager/tasks/main.yml6
-rw-r--r--ansible_collections/community/vmware/tests/integration/targets/vmware_dvs_portgroup/tasks/main.yml82
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/agent.yml20
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/javagateway.yml12
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/plugins-integration.yml2
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/proxy.yml12
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/repo-sanity.yml2
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/server.yml12
-rw-r--r--ansible_collections/community/zabbix/.github/workflows/web.yml12
-rw-r--r--ansible_collections/community/zabbix/CHANGELOG.rst40
-rw-r--r--ansible_collections/community/zabbix/FILES.json257
-rw-r--r--ansible_collections/community/zabbix/MANIFEST.json4
-rw-r--r--ansible_collections/community/zabbix/README.md2
-rw-r--r--ansible_collections/community/zabbix/changelogs/.plugin-cache.yaml17
-rw-r--r--ansible_collections/community/zabbix/changelogs/changelog.yaml58
-rw-r--r--ansible_collections/community/zabbix/docs/ZABBIX_AGENT_ROLE.md5
-rw-r--r--ansible_collections/community/zabbix/docs/ZABBIX_JAVAGATEWAY_ROLE.md4
-rw-r--r--ansible_collections/community/zabbix/docs/ZABBIX_PROXY_ROLE.md5
-rw-r--r--ansible_collections/community/zabbix/docs/ZABBIX_SERVER_ROLE.md4
-rw-r--r--ansible_collections/community/zabbix/docs/ZABBIX_WEB_ROLE.md13
-rw-r--r--ansible_collections/community/zabbix/molecule/requirements.txt6
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_agent_tests/common/playbooks/prepare.yml1
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_javagateway/molecule.yml2
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_proxy/destroy.yml6
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_proxy/molecule.yml10
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_proxy/prepare.yml4
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_server/destroy.yml6
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_server/molecule.yml10
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_server/prepare.yml12
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_web/destroy.yml6
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_web/molecule.yml12
-rw-r--r--ansible_collections/community/zabbix/molecule/zabbix_web/prepare.yml4
-rw-r--r--ansible_collections/community/zabbix/plugins/httpapi/zabbix.py3
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_correlation.py587
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_host.py64
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_maintenance.py40
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_mediatype.py11
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_service_info.py149
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_template.py295
-rw-r--r--ansible_collections/community/zabbix/plugins/modules/zabbix_templategroup.py4
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/README.md5
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/defaults/main.yml6
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/molecule/with-server/prepare.yml1
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/tasks/Debian.yml32
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/tasks/main.yml16
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/tasks/userparameter.yml3
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_agent/vars/Debian.yml3
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_javagateway/README.md4
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_javagateway/defaults/main.yml4
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/Debian.yml35
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/main.yml16
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_javagateway/vars/Debian.yml3
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_proxy/README.md5
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_proxy/defaults/main.yml3
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/Debian.yml35
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/main.yml11
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_proxy/vars/Debian.yml3
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/README.md4
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/defaults/main.yml6
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/Debian.yml156
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/RedHat.yml92
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-mysql.yml155
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-pgsql.yml (renamed from ansible_collections/community/zabbix/roles/zabbix_server/tasks/postgresql.yml)136
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/main.yml32
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/mysql.yml213
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/tasks/selinux.yml2
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/vars/Debian.yml17
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_server/vars/RedHat.yml24
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/README.md13
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/defaults/main.yml12
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/tasks/Debian.yml35
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/tasks/RedHat.yml5
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/tasks/main.yml11
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/tasks/selinux.yml22
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/templates/nginx_vhost.conf.j210
-rw-r--r--ansible_collections/community/zabbix/roles/zabbix_web/vars/Debian.yml3
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/meta/main.yml3
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/tasks/main.yml328
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml72
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_maintenance/tasks/main.yml50
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_mediatype/tasks/main.yml23
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/meta/main.yml3
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/tasks/main.yml57
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.json49
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.xml48
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.yaml23
-rw-r--r--ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/tasks/main.yml77
733 files changed, 20517 insertions, 31232 deletions
diff --git a/ansible_collections/community/aws/.github/workflows/docs-pr.yml b/ansible_collections/community/aws/.github/workflows/docs-pr.yml
index 35b58df24..e1f6ac1f6 100644
--- a/ansible_collections/community/aws/.github/workflows/docs-pr.yml
+++ b/ansible_collections/community/aws/.github/workflows/docs-pr.yml
@@ -5,7 +5,6 @@ concurrency:
on:
pull_request_target:
types: [opened, synchronize, reopened, closed]
-
env:
GHP_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}
@@ -22,6 +21,8 @@ jobs:
intersphinx-links: |
amazon_aws:https://ansible-collections.github.io/amazon.aws/branch/main/
ansible_devel:https://docs.ansible.com/ansible-core/devel/
+ artifact-name: ${{ github.event.repository.name }}_validate_docs_${{ github.event.pull_request.head.sha }}
+
build-docs:
permissions:
diff --git a/ansible_collections/community/aws/.github/workflows/sanity.yml b/ansible_collections/community/aws/.github/workflows/sanity.yml
index 161dabfe2..1cd6a6ba3 100644
--- a/ansible_collections/community/aws/.github/workflows/sanity.yml
+++ b/ansible_collections/community/aws/.github/workflows/sanity.yml
@@ -8,3 +8,4 @@ jobs:
uses: ansible-network/github_actions/.github/workflows/sanity.yml@main
with:
matrix_include: "[]"
+ collection_pre_install: '-r source/tests/sanity/requirements.yml'
diff --git a/ansible_collections/community/aws/CHANGELOG.rst b/ansible_collections/community/aws/CHANGELOG.rst
index b47d79fe4..5e7208f47 100644
--- a/ansible_collections/community/aws/CHANGELOG.rst
+++ b/ansible_collections/community/aws/CHANGELOG.rst
@@ -4,6 +4,58 @@ community.aws Release Notes
.. contents:: Topics
+v8.0.0
+======
+
+Release Summary
+---------------
+
+This major release brings several new features, bug fixes, and deprecated features. It also includes the removal of several modules that have been migrated to the ``amazon.aws`` collection. We have also removed support for ``ansible-core<2.15``.
+
+Minor Changes
+-------------
+
+- api_gateway - use fstrings where appropriate (https://github.com/ansible-collections/amazon.aws/pull/1962).
+- api_gateway_info - use fstrings where appropriate (https://github.com/ansible-collections/amazon.aws/pull/1962).
+- community.aws collection - apply isort code formatting to ensure consistent formatting of code (https://github.com/ansible-collections/community.aws/pull/1962)
+- ecs_taskdefinition - Add parameter ``runtime_platform`` (https://github.com/ansible-collections/community.aws/issues/1891).
+- eks_nodegroup - ensure wait also waits for deletion to complete when ``wait==True`` (https://github.com/ansible-collections/community.aws/pull/1994).
+- elb_network_lb - add support for Application-Layer Protocol Negotiation (ALPN) policy ``AlpnPolicy`` for TLS listeners (https://github.com/ansible-collections/community.aws/issues/1566).
+- elb_network_lb - add the possibly to update ``SslPolicy`` and ``Certificates`` for TLS listeners ().
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- The community.aws collection has dropped support for ``botocore<1.29.0`` and ``boto3<1.26.0``. Most modules will continue to work with older versions of the AWS SDK, however compatability with older versions of the SDK is not guaranteed and will not be tested. When using older versions of the SDK a warning will be emitted by Ansible (https://github.com/ansible-collections/amazon.aws/pull/1763).
+- aws_region_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.aws_region_info``.
+- aws_s3_bucket_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.aws_s3_bucket_info``.
+- community.aws collection - Support for ansible-core < 2.15 has been dropped (https://github.com/ansible-collections/community.aws/pull/2074).
+- community.aws collection - due to the AWS SDKs announcing the end of support for Python less than 3.7 (https://aws.amazon.com/blogs/developer/python-support-policy-updates-for-aws-sdks-and-tools/) support for Python less than 3.7 by this collection wss been deprecated in release 6.0.0 and removed in release 7.0.0. (https://github.com/ansible-collections/amazon.aws/pull/1763).
+- iam_access_key - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_access_key``.
+- iam_access_key_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_access_key_info``.
+- iam_group - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_group`` (https://github.com/ansible-collections/community.aws/pull/1945).
+- iam_managed_policy - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_managed_policy`` (https://github.com/ansible-collections/community.aws/pull/1954).
+- iam_mfa_device_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_mfa_device_info`` (https://github.com/ansible-collections/community.aws/pull/1953).
+- iam_password_policy - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_password_policy``.
+- iam_role - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_role`` (https://github.com/ansible-collections/community.aws/pull/1948).
+- iam_role_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_role_info`` (https://github.com/ansible-collections/community.aws/pull/1948).
+- s3_bucket_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.s3_bucket_info``.
+- sts_assume_role - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.sts_assume_role``.
+
+Deprecated Features
+-------------------
+
+- aws_glue_connection - updated the deprecation for removal of the ``connection_parameters`` return key from ``after 2024-06-01`` to release version ``9.0.0``, it is being replaced by the ``raw_connection_parameters`` key (https://github.com/ansible-collections/community.aws/pull/518).
+- ecs_cluster - updated the deprecation for updated default of ``purge_capacity_providers``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_capacity_providers=False`` (https://github.com/ansible-collections/community.aws/pull/1640).
+- ecs_service - updated the deprecation for updated default of ``purge_placement_constraints``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_placement_constraints=False`` (https://github.com/ansible-collections/community.aws/pull/1716).
+- ecs_service - updated the deprecation for updated default of ``purge_placement_strategy``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_placement_strategy=False`` (https://github.com/ansible-collections/community.aws/pull/1716).
+
+Bugfixes
+--------
+
+- mq_broker - ensure broker is created with ``tags`` when passed (https://github.com/ansible-collections/community.aws/issues/1832).
+- opensearch - Don't try to read a non existing key from the domain config (https://github.com/ansible-collections/community.aws/pull/1910).
+
v7.2.0
======
diff --git a/ansible_collections/community/aws/FILES.json b/ansible_collections/community/aws/FILES.json
index 58ea3a1a7..10e78ca13 100644
--- a/ansible_collections/community/aws/FILES.json
+++ b/ansible_collections/community/aws/FILES.json
@@ -81,7 +81,7 @@
"name": ".github/workflows/docs-pr.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "797c205c9482914beb2d806d0ce6cbd5e77beaadfbea32841ae4f873b7c6b0db",
+ "chksum_sha256": "ce0987aeaf6d9a48a7d97e282b8aa9ed3683b7c15cc9bb4f13fbcad8755de67c",
"format": 1
},
{
@@ -116,7 +116,7 @@
"name": ".github/workflows/sanity.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "371f8aed1f995954dce749b4017b61c7aabac004e0d3123db97e691b48bca918",
+ "chksum_sha256": "3a65efca8ca7b3821ed9ce45fe2b4a4a5f075c801445a8d9d29ff9fbdb5a79d1",
"format": 1
},
{
@@ -179,7 +179,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a4a404a462b4858f815f4cdd2b1651a4301a2cc2f868ac9f1ca14bfcec74d313",
+ "chksum_sha256": "b93e59b4985eef906a9ccb5e895aa6c6ef3dfc261d57e8f824888a3a84c18113",
"format": 1
},
{
@@ -214,7 +214,7 @@
"name": "docs/docsite/rst/CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "56d5b1f84c1fe53d65c7450a967427dd1e64a5ae6f5029e786b617686a98eb69",
+ "chksum_sha256": "9144b2cb0ea190269c4f4a0ac8bea114e7792a32974eab29e638f18d3806506f",
"format": 1
},
{
@@ -228,7 +228,7 @@
"name": "docs/docsite/links.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d0d10fb4e0294eb17b32c582b70a50aa39d01c0a272c01818f7044ce92b77196",
+ "chksum_sha256": "23a207a5372afdc2a4d1b7ac32edda6d5a44942ff2407d75c5c82cdb771f2cf6",
"format": 1
},
{
@@ -242,7 +242,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "73da55c9ac6fc4170daa33c7085e944bb0c61bfa045bd8f0794f66c27bacfb36",
+ "chksum_sha256": "0fdf412df4ad8b270934990e284254265136adfd2983f46611180d9b1ebc8530",
"format": 1
},
{
@@ -305,7 +305,7 @@
"name": "plugins/module_utils/common.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0f464ad15f459dc646c9596544ec189cf67ff07225c4a22fdba46b0daae73cdc",
+ "chksum_sha256": "0ba2337c1a2a08e6e29d15638fc590102ad99317a7b934255c0480cc265a5ce1",
"format": 1
},
{
@@ -459,7 +459,7 @@
"name": "plugins/modules/autoscaling_launch_config.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "30a3e098336211e85205b737758c55c7b5fb6913d9f1e5edcb24d899199a6239",
+ "chksum_sha256": "abe2019af8b3dc1433bb75f628f8319bb27f789122d51d531c35ea5635ecd12d",
"format": 1
},
{
@@ -872,7 +872,7 @@
"name": "plugins/modules/ecs_cluster.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "717a804b4d98129db71c2dbca9ec78a10c7415e57f8ed3a9811bf114cd7c247d",
+ "chksum_sha256": "e240a2a7c90f123f85e1e632d1c798333b07ff9bf2f761bc9691604e9f5feb67",
"format": 1
},
{
@@ -886,7 +886,7 @@
"name": "plugins/modules/ecs_service.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ffb7dd1444fdbaa495d7429b4aaeed4ac117cf04a54430b33493b28b7d6da389",
+ "chksum_sha256": "d7ab454817b508af19b0a7374a28294bd19e427bb76fca3075eb7660b851b135",
"format": 1
},
{
@@ -928,7 +928,7 @@
"name": "plugins/modules/efs.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b5dc61da6d44ae7f0268f19dbd7556a210fbcf67292e7ec9ef2c5e7818a19de0",
+ "chksum_sha256": "d7bc2a6995b409a71bd3480d1670a2a7f013f57d79b357f2ab312642410014e8",
"format": 1
},
{
@@ -1026,7 +1026,7 @@
"name": "plugins/modules/elb_network_lb.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ae3cf0fe9f7072739bf7828b89dce1586b1e042a064c7aa7908e0db68e1e3077",
+ "chksum_sha256": "e1ce3a1372cd72bf0487d0e01519d0c6ffc51d4c9d0509000f179f9f507fe108",
"format": 1
},
{
@@ -1061,7 +1061,7 @@
"name": "plugins/modules/glue_connection.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8808e4e2e90365eb34abd7d5496058406abee0e8a7f83241b88ddeeaab66c316",
+ "chksum_sha256": "ca10ed85814c5ce188a7eef319c8fa33427108a31672acd6742b17eaf57c118c",
"format": 1
},
{
@@ -2832,7 +2832,7 @@
"name": "tests/integration/targets/config/tasks/main.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2daab797eb69d23bff5a3d30e0f05384d037c650dda9f83f12e3d932be107178",
+ "chksum_sha256": "556fe10a1f2c4767e915ead7ae49c863ab5b5a9d7361e6dc5ec62bc3ef5fa1d0",
"format": 1
},
{
@@ -3763,7 +3763,7 @@
"name": "tests/integration/targets/ec2_launch_template/tasks/iam_instance_role.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f7761b4244b3a2abaf07cb36e48f7c736a8da062542fbce5a63bd030dbda2b3e",
+ "chksum_sha256": "7f35ef180a55a6260a58f6b7696324c7925367db487f380060fbcdfb48ad8eba",
"format": 1
},
{
@@ -4400,7 +4400,7 @@
"name": "tests/integration/targets/ecs_cluster/tasks/20_ecs_service.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e7c2cef87ceeb6202914dd1e3afab3d965bc3309037e08f0e96bfbd273583674",
+ "chksum_sha256": "76fb818fd8ec89673da120d5b341ac4a563e6fcd77de232e89872e43c2e5f4b2",
"format": 1
},
{
@@ -4652,7 +4652,7 @@
"name": "tests/integration/targets/eks_cluster/tasks/full_test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4eb39903b378d06cb7f278a0df8f58d36a168a97a412407d3ea73e299c37d1ad",
+ "chksum_sha256": "5f1622993af6f614b524155cf767b888cf9d28c8818825992736f419e810bbae",
"format": 1
},
{
@@ -4743,14 +4743,14 @@
"name": "tests/integration/targets/eks_fargate_profile/tasks/create_eks_cluster.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "568f82698281c509f6b951355dc20ccd4e119533a10a53c0fc8b3d24887a599c",
+ "chksum_sha256": "10cafe1f4d9ae726ab812399c5c29732f2f167211e732f92533dceb74d3e0968",
"format": 1
},
{
"name": "tests/integration/targets/eks_fargate_profile/tasks/full_test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d3ae89012d746b87dc80b23d7ca863261f883f4a3c918379eb5a7abb0c76ecad",
+ "chksum_sha256": "d1de8e30e82ebbc18ac3a83b31b268690840eb266723cbaf99af36993843edd4",
"format": 1
},
{
@@ -4827,14 +4827,14 @@
"name": "tests/integration/targets/eks_nodegroup/tasks/dependecies.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a878bdf097055ba6a0007ec40d00ec9371c99f1a306eea6e8f3b87b06f9ee7dc",
+ "chksum_sha256": "04b27e809851b82e0d08f900f1126271749e2ed45ce8c197b6af9f709608b14c",
"format": 1
},
{
"name": "tests/integration/targets/eks_nodegroup/tasks/full_test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e82734eafe0d1922e57f535fcf82ddb27b485d2bf21e14814f569a622501b0ef",
+ "chksum_sha256": "28fa83a08c7d590b0e8b7e780846615e95af0d3eff5a91579619acf7e883e4c4",
"format": 1
},
{
@@ -4848,7 +4848,7 @@
"name": "tests/integration/targets/eks_nodegroup/aliases",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "aab55ff735b17633ec85d2050fea115ef0082e8246cba061964b335a60765b93",
+ "chksum_sha256": "f9fe17586a25ccaae77eb0ed119358964b244bef37696d37152ef3964a0a7afe",
"format": 1
},
{
@@ -5289,7 +5289,7 @@
"name": "tests/integration/targets/elb_network_lb/tasks/test_modifying_nlb_listeners.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1553456cadcd682ea026756c61d8a54d442fdde03502d4df21a3c7a35f4814b4",
+ "chksum_sha256": "3b0103af8fa9307d50b9447b0883a3f59d0b468ed0f5c2979b7c5577535b93c8",
"format": 1
},
{
@@ -5415,7 +5415,7 @@
"name": "tests/integration/targets/elb_target/tasks/lambda_target.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a17e3f3cbd23a65e7aec0ffb1da5e15ea7241d33d5a0ea2323ec9eccd15c349c",
+ "chksum_sha256": "68d4b1df43e41c0f7760570c5714031d52d6fbfd255000b44ce6b9e7459de525",
"format": 1
},
{
@@ -9094,34 +9094,6 @@
"format": 1
},
{
- "name": "tests/sanity/ignore-2.10.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.11.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.12.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.13.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
"name": "tests/sanity/ignore-2.14.txt",
"ftype": "file",
"chksum_type": "sha256",
@@ -9150,13 +9122,6 @@
"format": 1
},
{
- "name": "tests/sanity/ignore-2.9.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
"name": "tests/sanity/requirements.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -13318,7 +13283,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "56d5b1f84c1fe53d65c7450a967427dd1e64a5ae6f5029e786b617686a98eb69",
+ "chksum_sha256": "9144b2cb0ea190269c4f4a0ac8bea114e7792a32974eab29e638f18d3806506f",
"format": 1
},
{
@@ -13339,7 +13304,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "258051287346af763659d20980984c8c5689e0b5d3e6ce2bdaa1f597a2013ded",
+ "chksum_sha256": "24929e84cb0cb18c0ff453ff508760b7b512054dacfbae2603af14db645b2195",
"format": 1
},
{
diff --git a/ansible_collections/community/aws/MANIFEST.json b/ansible_collections/community/aws/MANIFEST.json
index 514454326..e42c37f99 100644
--- a/ansible_collections/community/aws/MANIFEST.json
+++ b/ansible_collections/community/aws/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "aws",
- "version": "7.2.0",
+ "version": "8.0.0",
"authors": [
"Ansible (https://github.com/ansible)"
],
@@ -17,10 +17,10 @@
"license": [],
"license_file": "COPYING",
"dependencies": {
- "amazon.aws": ">=7.0.0,<8.0.0"
+ "amazon.aws": ">=8.0.0,<9.0.0"
},
"repository": "https://github.com/ansible-collections/community.aws",
- "documentation": "https://ansible-collections.github.io/community.aws/branch/stable-7/collections/community/aws/index.html",
+ "documentation": "https://ansible-collections.github.io/community.aws/branch/main/collections/community/aws/index.html",
"homepage": "https://github.com/ansible-collections/community.aws",
"issues": "https://github.com/ansible-collections/community.aws/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc"
},
@@ -28,7 +28,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "160883c33483553569816c9173e6073c59ded3c77bc8fdab656e7c72b1794d3a",
+ "chksum_sha256": "8b9fd0dd6d7d043e416b725482663568d8b4292445e17865acdad90551de476a",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/aws/README.md b/ansible_collections/community/aws/README.md
index ba02cf6db..dbdb43d4c 100644
--- a/ansible_collections/community/aws/README.md
+++ b/ansible_collections/community/aws/README.md
@@ -6,7 +6,7 @@ AWS related modules and plugins supported by the Ansible Cloud team are in the [
## Ansible version compatibility
-Tested with the Ansible Core >= 2.12.0 versions, and the current development version of Ansible. Ansible Core versions before 2.12.0 are not supported.
+Tested with the Ansible Core >= 2.15.0 versions, and the current development version of Ansible. Ansible Core versions before 2.15.0 are not supported.
Use community.aws 4.x.y if you are using Ansible 2.9 or Ansible Core 2.10.
@@ -46,7 +46,7 @@ All support for the original AWS SDK `boto` was removed in release 4.0.0.
## Included content
<!--start collection content-->
-See the complete list of collection content in the [Plugin Index](https://ansible-collections.github.io/community.aws/branch/stable-7/collections/community/aws/index.html#plugin-index).
+See the complete list of collection content in the [Plugin Index](https://ansible-collections.github.io/community.aws/branch/stable-8/collections/community/aws/index.html#plugin-index).
<!--end collection content-->
@@ -126,7 +126,7 @@ You can also join us on:
## Release notes
-See the [rendered changelog](https://ansible-collections.github.io/community.aws/branch/stable-7/collections/community/aws/docsite/CHANGELOG.html) or the [raw generated changelog](https://github.com/ansible-collections/community.aws/tree/stable-7/CHANGELOG.rst).
+See the [rendered changelog](https://ansible-collections.github.io/community.aws/branch/stable-8/collections/community/aws/docsite/CHANGELOG.html) or the [raw generated changelog](https://github.com/ansible-collections/community.aws/tree/stable-8/CHANGELOG.rst).
## Roadmap
diff --git a/ansible_collections/community/aws/changelogs/changelog.yaml b/ansible_collections/community/aws/changelogs/changelog.yaml
index e299d000e..beb6b030c 100644
--- a/ansible_collections/community/aws/changelogs/changelog.yaml
+++ b/ansible_collections/community/aws/changelogs/changelog.yaml
@@ -3755,3 +3755,123 @@ releases:
name: dynamodb_table_info
namespace: ''
release_date: '2024-04-05'
+ 8.0.0:
+ changes:
+ breaking_changes:
+ - The community.aws collection has dropped support for ``botocore<1.29.0`` and
+ ``boto3<1.26.0``. Most modules will continue to work with older versions of
+ the AWS SDK, however compatability with older versions of the SDK is not guaranteed
+ and will not be tested. When using older versions of the SDK a warning will
+ be emitted by Ansible (https://github.com/ansible-collections/amazon.aws/pull/1763).
+ - aws_region_info - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.aws_region_info``.
+ - aws_s3_bucket_info - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.aws_s3_bucket_info``.
+ - community.aws collection - Support for ansible-core < 2.15 has been dropped
+ (https://github.com/ansible-collections/community.aws/pull/2074).
+ - community.aws collection - due to the AWS SDKs announcing the end of support
+ for Python less than 3.7 (https://aws.amazon.com/blogs/developer/python-support-policy-updates-for-aws-sdks-and-tools/)
+ support for Python less than 3.7 by this collection wss been deprecated in
+ release 6.0.0 and removed in release 7.0.0. (https://github.com/ansible-collections/amazon.aws/pull/1763).
+ - iam_access_key - The module has been migrated from the ``community.aws`` collection.
+ Playbooks using the Fully Qualified Collection Name for this module should
+ be updated to use ``amazon.aws.iam_access_key``.
+ - iam_access_key_info - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.iam_access_key_info``.
+ - iam_group - The module has been migrated from the ``community.aws`` collection.
+ Playbooks using the Fully Qualified Collection Name for this module should
+ be updated to use ``amazon.aws.iam_group`` (https://github.com/ansible-collections/community.aws/pull/1945).
+ - iam_managed_policy - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.iam_managed_policy`` (https://github.com/ansible-collections/community.aws/pull/1954).
+ - iam_mfa_device_info - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.iam_mfa_device_info`` (https://github.com/ansible-collections/community.aws/pull/1953).
+ - iam_password_policy - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.iam_password_policy``.
+ - iam_role - The module has been migrated from the ``community.aws`` collection.
+ Playbooks using the Fully Qualified Collection Name for this module should
+ be updated to use ``amazon.aws.iam_role`` (https://github.com/ansible-collections/community.aws/pull/1948).
+ - iam_role_info - The module has been migrated from the ``community.aws`` collection.
+ Playbooks using the Fully Qualified Collection Name for this module should
+ be updated to use ``amazon.aws.iam_role_info`` (https://github.com/ansible-collections/community.aws/pull/1948).
+ - s3_bucket_info - The module has been migrated from the ``community.aws`` collection.
+ Playbooks using the Fully Qualified Collection Name for this module should
+ be updated to use ``amazon.aws.s3_bucket_info``.
+ - sts_assume_role - The module has been migrated from the ``community.aws``
+ collection. Playbooks using the Fully Qualified Collection Name for this module
+ should be updated to use ``amazon.aws.sts_assume_role``.
+ bugfixes:
+ - mq_broker - ensure broker is created with ``tags`` when passed (https://github.com/ansible-collections/community.aws/issues/1832).
+ - opensearch - Don't try to read a non existing key from the domain config (https://github.com/ansible-collections/community.aws/pull/1910).
+ deprecated_features:
+ - aws_glue_connection - updated the deprecation for removal of the ``connection_parameters``
+ return key from ``after 2024-06-01`` to release version ``9.0.0``, it is being
+ replaced by the ``raw_connection_parameters`` key (https://github.com/ansible-collections/community.aws/pull/518).
+ - ecs_cluster - updated the deprecation for updated default of ``purge_capacity_providers``,
+ the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To
+ maintain the current behaviour explicitly set ``purge_capacity_providers=False``
+ (https://github.com/ansible-collections/community.aws/pull/1640).
+ - ecs_service - updated the deprecation for updated default of ``purge_placement_constraints``,
+ the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To
+ maintain the current behaviour explicitly set ``purge_placement_constraints=False``
+ (https://github.com/ansible-collections/community.aws/pull/1716).
+ - ecs_service - updated the deprecation for updated default of ``purge_placement_strategy``,
+ the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To
+ maintain the current behaviour explicitly set ``purge_placement_strategy=False``
+ (https://github.com/ansible-collections/community.aws/pull/1716).
+ minor_changes:
+ - api_gateway - use fstrings where appropriate (https://github.com/ansible-collections/amazon.aws/pull/1962).
+ - api_gateway_info - use fstrings where appropriate (https://github.com/ansible-collections/amazon.aws/pull/1962).
+ - community.aws collection - apply isort code formatting to ensure consistent
+ formatting of code (https://github.com/ansible-collections/community.aws/pull/1962)
+ - ecs_taskdefinition - Add parameter ``runtime_platform`` (https://github.com/ansible-collections/community.aws/issues/1891).
+ - eks_nodegroup - ensure wait also waits for deletion to complete when ``wait==True``
+ (https://github.com/ansible-collections/community.aws/pull/1994).
+ - elb_network_lb - add support for Application-Layer Protocol Negotiation (ALPN)
+ policy ``AlpnPolicy`` for TLS listeners (https://github.com/ansible-collections/community.aws/issues/1566).
+ - elb_network_lb - add the possibly to update ``SslPolicy`` and ``Certificates``
+ for TLS listeners ().
+ release_summary: This major release brings several new features, bug fixes,
+ and deprecated features. It also includes the removal of several modules that
+ have been migrated to the ``amazon.aws`` collection. We have also removed
+ support for ``ansible-core<2.15``.
+ fragments:
+ - 1832-mq_broker_tags.yml
+ - 1891_ecs-task-definition-add-runtime-platform.yml
+ - 1904-route53_wait.yml
+ - 1962-isort.yml
+ - 20230623-black-cloudfront.yml
+ - 20230702-isort.yml
+ - 20230801-fix-linters.yml
+ - 20230906-galaxy.yml
+ - 20230906-route53_wait.yml
+ - 20230908-alias-cleanup.yml
+ - 20230915_migrate_iam_role_and_iam_role_info.yml
+ - 20231127-elb_network_lb-update-tls-listeners.yaml
+ - 20240408-efs-sanity_fix.yml
+ - 7.0.0-dev0.yml
+ - 8.0.0-increase-ansible-core-version.yml
+ - 8.0.0-release.yml
+ - 9-date-deprecations.yml
+ - boto3_equals.yml
+ - botocore.yml
+ - botocore_params-cleanup.yml
+ - eks_nodegroup-integration-wait-delete.yml
+ - galaxy_importer.yml
+ - migrate_aws_region_info.yml
+ - migrate_iam_access_key.yml
+ - migrate_iam_group.yml
+ - migrate_iam_managed_policy.yml
+ - migrate_iam_mfa_device_info.yml
+ - migrate_iam_password_policy.yml
+ - migrate_s3_bucket_info.yml
+ - migrate_sts_assume_role.yml
+ - opensearch_domainconfig_no_options.yaml
+ - python37.yml
+ - workflow-requirements.yml
+ release_date: '2024-05-20'
diff --git a/ansible_collections/community/aws/docs/docsite/links.yml b/ansible_collections/community/aws/docs/docsite/links.yml
index b38e48055..806723816 100644
--- a/ansible_collections/community/aws/docs/docsite/links.yml
+++ b/ansible_collections/community/aws/docs/docsite/links.yml
@@ -7,7 +7,7 @@
# functionality for your collection.
edit_on_github:
repository: ansible-collections/community.aws
- branch: stable-7
+ branch: stable-8
# If your collection root (the directory containing galaxy.yml) does not coincide with your
# repository's root, you have to specify the path to the collection root here. For example,
# if the collection root is in a subdirectory ansible_collections/community/REPO_NAME
diff --git a/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst b/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst
index b47d79fe4..5e7208f47 100644
--- a/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst
+++ b/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst
@@ -4,6 +4,58 @@ community.aws Release Notes
.. contents:: Topics
+v8.0.0
+======
+
+Release Summary
+---------------
+
+This major release brings several new features, bug fixes, and deprecated features. It also includes the removal of several modules that have been migrated to the ``amazon.aws`` collection. We have also removed support for ``ansible-core<2.15``.
+
+Minor Changes
+-------------
+
+- api_gateway - use fstrings where appropriate (https://github.com/ansible-collections/amazon.aws/pull/1962).
+- api_gateway_info - use fstrings where appropriate (https://github.com/ansible-collections/amazon.aws/pull/1962).
+- community.aws collection - apply isort code formatting to ensure consistent formatting of code (https://github.com/ansible-collections/community.aws/pull/1962)
+- ecs_taskdefinition - Add parameter ``runtime_platform`` (https://github.com/ansible-collections/community.aws/issues/1891).
+- eks_nodegroup - ensure wait also waits for deletion to complete when ``wait==True`` (https://github.com/ansible-collections/community.aws/pull/1994).
+- elb_network_lb - add support for Application-Layer Protocol Negotiation (ALPN) policy ``AlpnPolicy`` for TLS listeners (https://github.com/ansible-collections/community.aws/issues/1566).
+- elb_network_lb - add the possibly to update ``SslPolicy`` and ``Certificates`` for TLS listeners ().
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- The community.aws collection has dropped support for ``botocore<1.29.0`` and ``boto3<1.26.0``. Most modules will continue to work with older versions of the AWS SDK, however compatability with older versions of the SDK is not guaranteed and will not be tested. When using older versions of the SDK a warning will be emitted by Ansible (https://github.com/ansible-collections/amazon.aws/pull/1763).
+- aws_region_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.aws_region_info``.
+- aws_s3_bucket_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.aws_s3_bucket_info``.
+- community.aws collection - Support for ansible-core < 2.15 has been dropped (https://github.com/ansible-collections/community.aws/pull/2074).
+- community.aws collection - due to the AWS SDKs announcing the end of support for Python less than 3.7 (https://aws.amazon.com/blogs/developer/python-support-policy-updates-for-aws-sdks-and-tools/) support for Python less than 3.7 by this collection wss been deprecated in release 6.0.0 and removed in release 7.0.0. (https://github.com/ansible-collections/amazon.aws/pull/1763).
+- iam_access_key - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_access_key``.
+- iam_access_key_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_access_key_info``.
+- iam_group - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_group`` (https://github.com/ansible-collections/community.aws/pull/1945).
+- iam_managed_policy - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_managed_policy`` (https://github.com/ansible-collections/community.aws/pull/1954).
+- iam_mfa_device_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_mfa_device_info`` (https://github.com/ansible-collections/community.aws/pull/1953).
+- iam_password_policy - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_password_policy``.
+- iam_role - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_role`` (https://github.com/ansible-collections/community.aws/pull/1948).
+- iam_role_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.iam_role_info`` (https://github.com/ansible-collections/community.aws/pull/1948).
+- s3_bucket_info - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.s3_bucket_info``.
+- sts_assume_role - The module has been migrated from the ``community.aws`` collection. Playbooks using the Fully Qualified Collection Name for this module should be updated to use ``amazon.aws.sts_assume_role``.
+
+Deprecated Features
+-------------------
+
+- aws_glue_connection - updated the deprecation for removal of the ``connection_parameters`` return key from ``after 2024-06-01`` to release version ``9.0.0``, it is being replaced by the ``raw_connection_parameters`` key (https://github.com/ansible-collections/community.aws/pull/518).
+- ecs_cluster - updated the deprecation for updated default of ``purge_capacity_providers``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_capacity_providers=False`` (https://github.com/ansible-collections/community.aws/pull/1640).
+- ecs_service - updated the deprecation for updated default of ``purge_placement_constraints``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_placement_constraints=False`` (https://github.com/ansible-collections/community.aws/pull/1716).
+- ecs_service - updated the deprecation for updated default of ``purge_placement_strategy``, the current default of ``False`` will be changed to ``True`` in release ``9.0.0``. To maintain the current behaviour explicitly set ``purge_placement_strategy=False`` (https://github.com/ansible-collections/community.aws/pull/1716).
+
+Bugfixes
+--------
+
+- mq_broker - ensure broker is created with ``tags`` when passed (https://github.com/ansible-collections/community.aws/issues/1832).
+- opensearch - Don't try to read a non existing key from the domain config (https://github.com/ansible-collections/community.aws/pull/1910).
+
v7.2.0
======
diff --git a/ansible_collections/community/aws/meta/runtime.yml b/ansible_collections/community/aws/meta/runtime.yml
index 4c6bc7291..ea50b0162 100644
--- a/ansible_collections/community/aws/meta/runtime.yml
+++ b/ansible_collections/community/aws/meta/runtime.yml
@@ -1,5 +1,5 @@
---
-requires_ansible: '>=2.12.0'
+requires_ansible: '>=2.15.0'
action_groups:
aws:
- accessanalyzer_validate_policy_info
diff --git a/ansible_collections/community/aws/plugins/module_utils/common.py b/ansible_collections/community/aws/plugins/module_utils/common.py
index 321349a1d..40c9c582b 100644
--- a/ansible_collections/community/aws/plugins/module_utils/common.py
+++ b/ansible_collections/community/aws/plugins/module_utils/common.py
@@ -5,4 +5,4 @@
COMMUNITY_AWS_COLLECTION_NAME = "community.aws"
-COMMUNITY_AWS_COLLECTION_VERSION = "7.2.0"
+COMMUNITY_AWS_COLLECTION_VERSION = "8.0.0"
diff --git a/ansible_collections/community/aws/plugins/modules/autoscaling_launch_config.py b/ansible_collections/community/aws/plugins/modules/autoscaling_launch_config.py
index 78b7ee233..cd411e576 100644
--- a/ansible_collections/community/aws/plugins/modules/autoscaling_launch_config.py
+++ b/ansible_collections/community/aws/plugins/modules/autoscaling_launch_config.py
@@ -533,7 +533,7 @@ def create_launch_config(connection, module):
module.fail_json_aws(e, msg="Failed to connect to AWS")
try:
security_groups = get_ec2_security_group_ids_from_names(
- module.params.get("security_groups"), ec2_connection, vpc_id=vpc_id, boto3=True
+ module.params.get("security_groups"), ec2_connection, vpc_id=vpc_id
)
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Failed to get Security Group IDs")
diff --git a/ansible_collections/community/aws/plugins/modules/ecs_cluster.py b/ansible_collections/community/aws/plugins/modules/ecs_cluster.py
index 7d427a58d..5a0470eea 100644
--- a/ansible_collections/community/aws/plugins/modules/ecs_cluster.py
+++ b/ansible_collections/community/aws/plugins/modules/ecs_cluster.py
@@ -72,7 +72,7 @@ options:
version_added: 5.2.0
description:
- Toggle overwriting of existing capacity providers or strategy. This is needed for backwards compatibility.
- - By default I(purge_capacity_providers=false). In a release after 2024-06-01 this will be changed to I(purge_capacity_providers=true).
+ - By default I(purge_capacity_providers=false). In release 9.0.0 this default will be changed to I(purge_capacity_providers=true).
required: false
type: bool
default: false
@@ -292,9 +292,9 @@ def main():
# Unless purge_capacity_providers is true, we will not be updating the providers or strategy.
if not purge_capacity_providers:
module.deprecate(
- "After 2024-06-01 the default value of purge_capacity_providers will change from false to true."
+ "In release 9.0.0 the default value of purge_capacity_providers will change from false to true."
" To maintain the existing behaviour explicitly set purge_capacity_providers=true",
- date="2024-06-01",
+ version="9.0.0",
collection_name="community.aws",
)
cps_update_needed = False
diff --git a/ansible_collections/community/aws/plugins/modules/ecs_service.py b/ansible_collections/community/aws/plugins/modules/ecs_service.py
index e832fa3b5..e6ecf736b 100644
--- a/ansible_collections/community/aws/plugins/modules/ecs_service.py
+++ b/ansible_collections/community/aws/plugins/modules/ecs_service.py
@@ -158,7 +158,7 @@ options:
version_added: 5.3.0
description:
- Toggle overwriting of existing placement constraints. This is needed for backwards compatibility.
- - By default I(purge_placement_constraints=false). In a release after 2024-06-01 this will be changed to I(purge_placement_constraints=true).
+ - By default I(purge_placement_constraints=false). In release 9.0.0 this will be changed to I(purge_placement_constraints=true).
required: false
type: bool
default: false
@@ -180,7 +180,7 @@ options:
version_added: 5.3.0
description:
- Toggle overwriting of existing placement strategy. This is needed for backwards compatibility.
- - By default I(purge_placement_strategy=false). In a release after 2024-06-01 this will be changed to I(purge_placement_strategy=true).
+ - By default I(purge_placement_strategy=false). In release 9.0.0 this will be changed to I(purge_placement_strategy=true).
required: false
type: bool
default: false
diff --git a/ansible_collections/community/aws/plugins/modules/efs.py b/ansible_collections/community/aws/plugins/modules/efs.py
index 6b9390f2b..32992c4a3 100644
--- a/ansible_collections/community/aws/plugins/modules/efs.py
+++ b/ansible_collections/community/aws/plugins/modules/efs.py
@@ -653,8 +653,7 @@ def iterate_all(attr, map_method, **kwargs):
while True:
try:
data = map_method(**args)
- for elm in data[attr]:
- yield elm
+ yield from data[attr]
if "NextMarker" in data:
args["Marker"] = data["Nextmarker"]
continue
diff --git a/ansible_collections/community/aws/plugins/modules/elb_network_lb.py b/ansible_collections/community/aws/plugins/modules/elb_network_lb.py
index 86d8f0872..22e419328 100644
--- a/ansible_collections/community/aws/plugins/modules/elb_network_lb.py
+++ b/ansible_collections/community/aws/plugins/modules/elb_network_lb.py
@@ -69,6 +69,17 @@ options:
description:
- The name of the target group.
- Mutually exclusive with I(TargetGroupArn).
+ AlpnPolicy:
+ description:
+ - The name of the Application-Layer Protocol Negotiation (ALPN) policy.
+ type: str
+ choices:
+ - HTTP1Only
+ - HTTP2Only
+ - HTTP2Optional
+ - HTTP2Preferred
+ - None
+ version_added: 7.1.0
name:
description:
- The name of the load balancer. This name must be unique within your AWS account, can have a maximum of 32 characters, must contain only alphanumeric
@@ -282,6 +293,13 @@ load_balancer:
returned: when state is present
type: str
sample: ""
+ alpn_policy:
+ description: The name of the Application-Layer Protocol Negotiation (ALPN) policy.
+ returned: when state is present
+ type: list
+ elements: str
+ version_added: 7.1.0
+ sample: ["HTTP1Only", "HTTP2Only"]
load_balancer_arn:
description: The Amazon Resource Name (ARN) of the load balancer.
returned: when state is present
@@ -448,6 +466,10 @@ def main():
SslPolicy=dict(type="str"),
Certificates=dict(type="list", elements="dict"),
DefaultActions=dict(type="list", required=True, elements="dict"),
+ AlpnPolicy=dict(
+ type="str",
+ choices=["HTTP1Only", "HTTP2Only", "HTTP2Optional", "HTTP2Preferred", "None"],
+ ),
),
),
name=dict(required=True, type="str"),
diff --git a/ansible_collections/community/aws/plugins/modules/glue_connection.py b/ansible_collections/community/aws/plugins/modules/glue_connection.py
index 18039a861..f44ca8bbf 100644
--- a/ansible_collections/community/aws/plugins/modules/glue_connection.py
+++ b/ansible_collections/community/aws/plugins/modules/glue_connection.py
@@ -110,7 +110,7 @@ RETURN = r"""
connection_properties:
description:
- (deprecated) A dict of key-value pairs (converted to lowercase) used as parameters for this connection.
- - This return key has been deprecated, and will be removed in a release after 2024-06-01.
+ - This return key has been deprecated, and will be removed in release 9.0.0.
returned: when state is present
type: dict
sample: {'jdbc_connection_url':'jdbc:mysql://mydb:3306/databasename','username':'x','password':'y'}
@@ -298,9 +298,7 @@ def create_or_update_glue_connection(connection, connection_ec2, module, glue_co
params["ConnectionInput"]["PhysicalConnectionRequirements"] = dict()
if module.params.get("security_groups") is not None:
# Get security group IDs from names
- security_group_ids = get_ec2_security_group_ids_from_names(
- module.params.get("security_groups"), connection_ec2, boto3=True
- )
+ security_group_ids = get_ec2_security_group_ids_from_names(module.params.get("security_groups"), connection_ec2)
params["ConnectionInput"]["PhysicalConnectionRequirements"]["SecurityGroupIdList"] = security_group_ids
if module.params.get("subnet_id") is not None:
params["ConnectionInput"]["PhysicalConnectionRequirements"]["SubnetId"] = module.params.get("subnet_id")
@@ -339,7 +337,7 @@ def create_or_update_glue_connection(connection, connection_ec2, module, glue_co
"The 'connection_properties' return key is deprecated and will be replaced"
" by 'raw_connection_properties'. Both values are returned for now."
),
- date="2024-06-01",
+ version="9.0.0",
collection_name="community.aws",
)
glue_connection["RawConnectionProperties"] = glue_connection["ConnectionProperties"]
diff --git a/ansible_collections/community/aws/tests/integration/targets/config/tasks/main.yaml b/ansible_collections/community/aws/tests/integration/targets/config/tasks/main.yaml
index 244c4b29b..540370803 100644
--- a/ansible_collections/community/aws/tests/integration/targets/config/tasks/main.yaml
+++ b/ansible_collections/community/aws/tests/integration/targets/config/tasks/main.yaml
@@ -173,7 +173,7 @@
config_recorder:
name: '{{ resource_prefix }}-recorder'
state: present
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
recording_group:
all_supported: true
include_global_types: true
@@ -236,7 +236,7 @@
account_sources: []
organization_source:
all_aws_regions: true
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
register: output
- name: assert success
@@ -251,7 +251,7 @@
account_sources: []
organization_source:
all_aws_regions: true
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
register: output
- name: assert not changed
@@ -266,7 +266,7 @@
config_recorder:
name: '{{ resource_prefix }}-recorder'
state: present
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
recording_group:
all_supported: false
include_global_types: false
@@ -348,7 +348,7 @@
all_aws_regions: false
aws_regions:
- '{{ aws_region }}'
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
register: output
- name: assert success
@@ -365,7 +365,7 @@
all_aws_regions: false
aws_regions:
- '{{ aws_region }}'
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
register: output
- name: assert success
@@ -380,7 +380,7 @@
config_recorder:
name: '{{ resource_prefix }}-recorder'
state: present
- role_arn: "{{ config_iam_role.arn }}"
+ role_arn: "{{ config_iam_role.iam_role.arn }}"
recording_group:
all_supported: false
include_global_types: false
diff --git a/ansible_collections/community/aws/tests/integration/targets/ec2_launch_template/tasks/iam_instance_role.yml b/ansible_collections/community/aws/tests/integration/targets/ec2_launch_template/tasks/iam_instance_role.yml
index c26b96d69..ad797fabb 100644
--- a/ansible_collections/community/aws/tests/integration/targets/ec2_launch_template/tasks/iam_instance_role.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/ec2_launch_template/tasks/iam_instance_role.yml
@@ -29,7 +29,7 @@
- assert:
that:
- - 'template_with_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.iam_role.arn.replace(":role/", ":instance-profile/")'
- name: Create template again, with no change to instance_role
ec2_launch_template:
@@ -41,7 +41,7 @@
- assert:
that:
- - 'template_with_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.iam_role.arn.replace(":role/", ":instance-profile/")'
- 'template_with_role is not changed'
- name: Update instance with new instance_role
@@ -54,8 +54,8 @@
- assert:
that:
- - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role_2.arn.replace(":role/", ":instance-profile/")'
- - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role_2.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role_2.iam_role.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role_2.iam_role.arn.replace(":role/", ":instance-profile/")'
- 'template_with_role.default_template.version_number < template_with_updated_role.default_template.version_number'
- 'template_with_updated_role is changed'
- 'template_with_updated_role is not failed'
@@ -71,7 +71,7 @@
- assert:
that:
- 'template_with_updated_role is not changed'
- - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role_2.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role_2.iam_role.arn.replace(":role/", ":instance-profile/")'
- name: Update instance with original instance_role (pass profile ARN)
ec2_launch_template:
@@ -79,13 +79,13 @@
image_id: "{{ ec2_ami_id }}"
instance_type: t2.micro
# By default an instance profile will be created with the same name as the role
- iam_instance_profile: '{{ iam_role.arn.replace(":role/", ":instance-profile/") }}'
+ iam_instance_profile: '{{ iam_role.iam_role.arn.replace(":role/", ":instance-profile/") }}'
register: template_with_updated_role
- assert:
that:
- - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.arn.replace(":role/", ":instance-profile/")'
- - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.iam_role.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.iam_role.arn.replace(":role/", ":instance-profile/")'
- 'template_with_role.default_template.version_number < template_with_updated_role.default_template.version_number'
- 'template_with_updated_role is changed'
- 'template_with_updated_role is not failed'
@@ -95,13 +95,13 @@
name: "{{ resource_prefix }}-test-instance-role"
image_id: "{{ ec2_ami_id }}"
instance_type: t2.micro
- iam_instance_profile: '{{ iam_role.arn.replace(":role/", ":instance-profile/") }}'
+ iam_instance_profile: '{{ iam_role.iam_role.arn.replace(":role/", ":instance-profile/") }}'
register: template_with_updated_role
- assert:
that:
- 'template_with_updated_role is not changed'
- - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.arn.replace(":role/", ":instance-profile/")'
+ - 'template_with_updated_role.default_template.launch_template_data.iam_instance_profile.arn == iam_role.iam_role.arn.replace(":role/", ":instance-profile/")'
always:
- name: delete launch template
diff --git a/ansible_collections/community/aws/tests/integration/targets/ecs_cluster/tasks/20_ecs_service.yml b/ansible_collections/community/aws/tests/integration/targets/ecs_cluster/tasks/20_ecs_service.yml
index 3c4bbcb28..e04cfe6ac 100644
--- a/ansible_collections/community/aws/tests/integration/targets/ecs_cluster/tasks/20_ecs_service.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/ecs_cluster/tasks/20_ecs_service.yml
@@ -547,7 +547,7 @@
>> "rolloutStateReason": "ECS deployment ecs-svc/5156684577543126023 in progress.",
constraints and placement strategies are only changeable if the rollout state is "COMPLETED"
-
+
a) ecs_service has currently no waiter function. so this is a DIY waiter
b) the state reached never "COMPLETED" because something if wrong with the ECS EC2 Instances
or the network setup. The EC2 instance never arrived as an active instance in the cluster.
@@ -555,9 +555,9 @@
>> no container instance met all of its requirements. Reason: No Container Instances were found in your cluster.
>> For more information, see the Troubleshooting section of the Amazon ECS Developer Guide.
>> ec2_instance networking does not work correctly, no instance available for the cluster
-
+
Because all of this, all following tasks, that test the change of a constraint or placement stragegy are
- using `force_new_deployment: true`. That ignores a) and b).
+ using `force_new_deployment: true`. That ignores a) and b).
ignore_errors: true
ecs_service_info:
name: "{{ ecs_service_name }}-constraint"
@@ -736,7 +736,7 @@
launch_type: FARGATE
cpu: 512
memory: 1024
- execution_role_arn: "{{ iam_execution_role.arn }}"
+ execution_role_arn: "{{ iam_execution_role.iam_role.arn }}"
state: present
vars:
ecs_task_host_port: 8080
@@ -750,7 +750,7 @@
launch_type: EC2
cpu: 512
memory: 1024
- execution_role_arn: "{{ iam_execution_role.arn }}"
+ execution_role_arn: "{{ iam_execution_role.iam_role.arn }}"
state: present
vars:
ecs_task_host_port: 8080
@@ -916,7 +916,7 @@
launch_type: FARGATE
cpu: 512
memory: 1024
- execution_role_arn: "{{ iam_execution_role.arn }}"
+ execution_role_arn: "{{ iam_execution_role.iam_role.arn }}"
state: present
runtime_platform:
cpuArchitecture: "ARM64"
@@ -938,7 +938,7 @@
launch_type: FARGATE
cpu: 512
memory: 1024
- execution_role_arn: "{{ iam_execution_role.arn }}"
+ execution_role_arn: "{{ iam_execution_role.iam_role.arn }}"
state: present
runtime_platform:
cpuArchitecture: "ARM64"
@@ -960,7 +960,7 @@
launch_type: FARGATE
cpu: 512
memory: 1024
- execution_role_arn: "{{ iam_execution_role.arn }}"
+ execution_role_arn: "{{ iam_execution_role.iam_role.arn }}"
state: present
runtime_platform:
cpuArchitecture: "ARM64"
diff --git a/ansible_collections/community/aws/tests/integration/targets/eks_cluster/tasks/full_test.yml b/ansible_collections/community/aws/tests/integration/targets/eks_cluster/tasks/full_test.yml
index 71cc1fc87..d3f7dfbe6 100644
--- a/ansible_collections/community/aws/tests/integration/targets/eks_cluster/tasks/full_test.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/eks_cluster/tasks/full_test.yml
@@ -79,7 +79,7 @@
name: "{{ eks_cluster_name }}"
security_groups: "{{ eks_security_groups | map(attribute='name') }}"
subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
- role_arn: "{{ iam_role.arn }}"
+ role_arn: "{{ iam_role.iam_role.arn }}"
tags:
Name: "{{ resource_prefix }}"
another: foobar
@@ -97,7 +97,7 @@
name: "{{ eks_cluster_name }}"
security_groups: "{{ eks_security_groups | map(attribute='name') }}"
subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
- role_arn: "{{ iam_role.arn }}"
+ role_arn: "{{ iam_role.iam_role.arn }}"
wait: yes
register: eks_create
@@ -117,7 +117,7 @@
name: "{{ eks_cluster_name }}"
security_groups: "{{ setup_security_groups.results | map(attribute='group_id') }}"
subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
- role_arn: "{{ iam_role.arn }}"
+ role_arn: "{{ iam_role.iam_role.arn }}"
register: eks_create
- name: check that EKS cluster did not change
@@ -143,7 +143,7 @@
name: "{{ eks_cluster_name }}"
security_groups: "{{ eks_security_groups | map(attribute='name') }}"
subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
- role_arn: "{{ iam_role.arn }}"
+ role_arn: "{{ iam_role.iam_role.arn }}"
wait: yes
register: eks_create
@@ -169,7 +169,7 @@
name: "{{ eks_cluster_short_name }}"
security_groups: "{{ eks_security_groups | map(attribute='name') }}"
subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
- role_arn: "{{ iam_role.arn }}"
+ role_arn: "{{ iam_role.iam_role.arn }}"
register: eks_create
- name: check that EKS cluster was created with short name
diff --git a/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/create_eks_cluster.yml b/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/create_eks_cluster.yml
index 48fbbef80..1402ad0a1 100644
--- a/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/create_eks_cluster.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/create_eks_cluster.yml
@@ -87,7 +87,7 @@
name: '{{ eks_cluster_name }}'
security_groups: '{{ eks_security_groups | map(attribute=''name'') }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
- role_arn: '{{ iam_role.arn }}'
+ role_arn: '{{ iam_role.iam_role.arn }}'
wait: true
register: eks_create
diff --git a/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/full_test.yml b/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/full_test.yml
index b992125b3..6b513b9b5 100644
--- a/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/full_test.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/eks_fargate_profile/tasks/full_test.yml
@@ -1,5 +1,5 @@
# Creating dependencies
-- name: create IAM instance role
+- name: create IAM instance role
iam_role:
name: 'ansible-test-aws_eks_fargate_profile'
assume_role_policy_document: '{{ lookup(''file'',''eks-fargate-profile-trust-policy.json'') }}'
@@ -19,7 +19,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: fake_cluster
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -38,7 +38,7 @@
name: fake_profile
cluster_name: '{{ eks_cluster_name }}'
state: absent
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -57,7 +57,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'public') | map(attribute='subnet.id') }}
@@ -72,13 +72,13 @@
- not eks_fargate_profile_create.changed
- eks_fargate_profile_create.msg.endswith("provided in Fargate Profile is not a private subnet")
-# Create Fargate_profile with wait
+# Create Fargate_profile with wait
- name: create Fargate Profile with wait (check mode)
eks_fargate_profile:
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -99,7 +99,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -120,7 +120,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -141,7 +141,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -162,7 +162,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -185,7 +185,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -207,7 +207,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -230,7 +230,7 @@
name: '{{ eks_fargate_profile_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -253,7 +253,7 @@
name: '{{ eks_fargate_profile_name_b }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -272,7 +272,7 @@
name: '{{ eks_fargate_profile_name_b }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -291,7 +291,7 @@
name: '{{ eks_fargate_profile_name_b }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -310,7 +310,7 @@
name: '{{ eks_fargate_profile_name_b }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- role_arn: '{{ iam_role_fargate.arn }}'
+ role_arn: '{{ iam_role_fargate.iam_role.arn }}'
subnets: >-
{{setup_subnets.results|selectattr('subnet.tags.Name', 'contains',
'private') | map(attribute='subnet.id') }}
@@ -389,7 +389,7 @@
that:
- eks_fargate_profile_b_delete.changed
-- name: delete a fargate profile b
+- name: delete a fargate profile b
eks_fargate_profile:
name: '{{ eks_fargate_profile_name_b }}'
cluster_name: '{{ eks_cluster_name }}'
@@ -426,4 +426,4 @@
- name: check that eks_fargate_profile did nothing (idempotency)
assert:
that:
- - not eks_fargate_profile_b_delete.changed \ No newline at end of file
+ - not eks_fargate_profile_b_delete.changed
diff --git a/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/aliases b/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/aliases
index 1809e989b..0b84301d7 100644
--- a/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/aliases
+++ b/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/aliases
@@ -1,2 +1 @@
-cloud/aws
-time=30m
+cloud/aws \ No newline at end of file
diff --git a/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/dependecies.yml b/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/dependecies.yml
index 882d45dd7..cd37239c4 100644
--- a/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/dependecies.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/dependecies.yml
@@ -67,7 +67,7 @@
name: '{{ eks_cluster_name }}'
security_groups: '{{ eks_security_groups | map(attribute=''name'') }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
- role_arn: '{{ iam_role.arn }}'
+ role_arn: '{{ iam_role.iam_role.arn }}'
wait: true
register: eks_create
diff --git a/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/full_test.yml b/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/full_test.yml
index 9accc8e8f..cb1d27340 100644
--- a/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/full_test.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/eks_nodegroup/tasks/full_test.yml
@@ -4,7 +4,7 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: fake_cluster
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
@@ -38,10 +38,10 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
wait: True
- launch_template:
+ launch_template:
id: 'lt-0824c69cafa69ac81'
disk_size: 30
register: eks_nodegroup_result
@@ -60,18 +60,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 3
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'test'
taints:
- key: 'env'
@@ -98,18 +98,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 3
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'test'
taints:
- key: 'env'
@@ -135,18 +135,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 3
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'test'
taints:
- key: 'env'
@@ -173,18 +173,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 3
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'test'
taints:
- key: 'env'
@@ -214,7 +214,7 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
wait: True
disk_size: 40
@@ -231,7 +231,7 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
wait: True
instance_types: ['t3.small']
@@ -251,18 +251,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 4
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'changeit'
taints:
- key: 'env'
@@ -289,18 +289,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 4
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'changeit'
taints:
- key: 'env'
@@ -326,18 +326,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 4
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'changeit'
taints:
- key: 'env'
@@ -364,18 +364,18 @@
name: '{{ eks_nodegroup_name_a }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
scaling_config:
min_size: 1
max_size: 4
desired_size: 2
- disk_size: 30
+ disk_size: 30
instance_types: ['t3.small']
ami_type: 'AL2_x86_64'
update_config:
max_unavailable_percentage: 50
- labels:
+ labels:
'env': 'changeit'
taints:
- key: 'env'
@@ -405,7 +405,7 @@
name: '{{ eks_nodegroup_name_a }}'
state: absent
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
register: eks_nodegroup_result
check_mode: True
@@ -459,7 +459,7 @@
name: '{{ eks_nodegroup_name_lt }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
launch_template:
name: '{{ lt.template.launch_template_name }}'
@@ -477,7 +477,7 @@
name: '{{ eks_nodegroup_name_lt }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
launch_template:
name: '{{ lt.template.launch_template_name }}'
@@ -494,7 +494,7 @@
name: '{{ eks_nodegroup_name_lt }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
launch_template:
name: '{{ lt.template.launch_template_name }}'
@@ -512,7 +512,7 @@
name: '{{ eks_nodegroup_name_lt }}'
state: present
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
subnets: '{{ setup_subnets.results | map(attribute=''subnet.id'') }}'
launch_template:
name: '{{ lt.template.launch_template_name }}'
@@ -533,7 +533,7 @@
name: '{{ eks_nodegroup_name_lt }}'
state: absent
cluster_name: '{{ eks_cluster_name }}'
- node_role: '{{ iam_role_eks_nodegroup.arn }}'
+ node_role: '{{ iam_role_eks_nodegroup.iam_role.arn }}'
wait: True
register: eks_nodegroup_result
check_mode: True
diff --git a/ansible_collections/community/aws/tests/integration/targets/elb_network_lb/tasks/test_modifying_nlb_listeners.yml b/ansible_collections/community/aws/tests/integration/targets/elb_network_lb/tasks/test_modifying_nlb_listeners.yml
index 9877e3f1b..9189fba28 100644
--- a/ansible_collections/community/aws/tests/integration/targets/elb_network_lb/tasks/test_modifying_nlb_listeners.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/elb_network_lb/tasks/test_modifying_nlb_listeners.yml
@@ -73,3 +73,83 @@
that:
- nlb.changed
- not nlb.listeners
+
+# TLS listeners
+- name: Add a TLS listener
+ elb_network_lb:
+ name: "{{ nlb_name }}"
+ subnets: "{{ nlb_subnets }}"
+ state: present
+ listeners:
+ - Protocol: TLS
+ Port: 443
+ Certificates:
+ - CertificateArn: "{{ cert.arn }}"
+ DefaultActions:
+ - Type: forward
+ TargetGroupName: "{{ tg_name }}"
+ SslPolicy: ELBSecurityPolicy-TLS-1-0-2015-04
+ AlpnPolicy: HTTP2Optional
+ register: _add
+
+- assert:
+ that:
+ - _add.listeners[0].alpn_policy == ["HTTP2Optional"]
+ - _add.listeners[0].ssl_policy == "ELBSecurityPolicy-TLS-1-0-2015-04"
+
+- name: Add a TLS listener (idempotency)
+ elb_network_lb:
+ name: "{{ nlb_name }}"
+ subnets: "{{ nlb_subnets }}"
+ listeners:
+ - Protocol: TLS
+ Port: 443
+ Certificates:
+ - CertificateArn: "{{ cert.arn }}"
+ DefaultActions:
+ - Type: forward
+ TargetGroupName: "{{ tg_name }}"
+ SslPolicy: ELBSecurityPolicy-TLS-1-0-2015-04
+ AlpnPolicy: HTTP2Optional
+ register: _idempotency
+
+- assert:
+ that:
+ - _idempotency is not changed
+ - _idempotency.listeners[0].alpn_policy == ["HTTP2Optional"]
+ - _idempotency.listeners[0].ssl_policy == "ELBSecurityPolicy-TLS-1-0-2015-04"
+
+- name: Update TLS listener of NLB
+ elb_network_lb:
+ name: "{{ nlb_name }}"
+ subnets: "{{ nlb_subnets }}"
+ listeners:
+ - Protocol: TLS
+ Port: 443
+ Certificates:
+ - CertificateArn: "{{ cert.arn }}"
+ DefaultActions:
+ - Type: forward
+ TargetGroupName: "{{ tg_name }}"
+ SslPolicy: ELBSecurityPolicy-TLS13-1-2-FIPS-2023-04
+ AlpnPolicy: HTTP1Only
+ register: _update
+
+- assert:
+ that:
+ - _update is changed
+ - _update.listeners[0].alpn_policy == ["HTTP1Only"]
+ - _update.listeners[0].ssl_policy == "ELBSecurityPolicy-TLS13-1-2-FIPS-2023-04"
+
+- name: remove listener from NLB
+ elb_network_lb:
+ name: "{{ nlb_name }}"
+ subnets: "{{ nlb_subnets }}"
+ state: present
+ listeners: []
+ register: nlb
+
+- assert:
+ that:
+ - nlb.changed
+ - not nlb.listeners
diff --git a/ansible_collections/community/aws/tests/integration/targets/elb_target/tasks/lambda_target.yml b/ansible_collections/community/aws/tests/integration/targets/elb_target/tasks/lambda_target.yml
index c4271cdd6..7e6b54cef 100644
--- a/ansible_collections/community/aws/tests/integration/targets/elb_target/tasks/lambda_target.yml
+++ b/ansible_collections/community/aws/tests/integration/targets/elb_target/tasks/lambda_target.yml
@@ -24,7 +24,7 @@
state: present
zip_file: /tmp/lambda.zip
runtime: python3.12
- role: "{{ ROLE_ARN.arn }}"
+ role: "{{ ROLE_ARN.iam_role.arn }}"
handler: ansible_lambda_target.lambda_handler
timeout: 30
register: lambda_function
diff --git a/ansible_collections/community/aws/tests/sanity/ignore-2.10.txt b/ansible_collections/community/aws/tests/sanity/ignore-2.10.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/aws/tests/sanity/ignore-2.10.txt
+++ /dev/null
diff --git a/ansible_collections/community/aws/tests/sanity/ignore-2.11.txt b/ansible_collections/community/aws/tests/sanity/ignore-2.11.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/aws/tests/sanity/ignore-2.11.txt
+++ /dev/null
diff --git a/ansible_collections/community/aws/tests/sanity/ignore-2.12.txt b/ansible_collections/community/aws/tests/sanity/ignore-2.12.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/aws/tests/sanity/ignore-2.12.txt
+++ /dev/null
diff --git a/ansible_collections/community/aws/tests/sanity/ignore-2.13.txt b/ansible_collections/community/aws/tests/sanity/ignore-2.13.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/aws/tests/sanity/ignore-2.13.txt
+++ /dev/null
diff --git a/ansible_collections/community/aws/tests/sanity/ignore-2.9.txt b/ansible_collections/community/aws/tests/sanity/ignore-2.9.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/aws/tests/sanity/ignore-2.9.txt
+++ /dev/null
diff --git a/ansible_collections/community/azure/.azure-pipelines/README.md b/ansible_collections/community/azure/.azure-pipelines/README.md
deleted file mode 100644
index 385e70bac..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## Azure Pipelines Configuration
-
-Please see the [Documentation](https://github.com/ansible/community/wiki/Testing:-Azure-Pipelines) for more information.
diff --git a/ansible_collections/community/azure/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/azure/.azure-pipelines/azure-pipelines.yml
deleted file mode 100644
index 48658e394..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/azure-pipelines.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-trigger:
- batch: true
- branches:
- include:
- - main
- - master
- - stable-*
-
-pr:
- autoCancel: true
- branches:
- include:
- - main
- - stable-*
-
-schedules:
- - cron: 0 9 * * *
- displayName: Nightly
- always: true
- branches:
- include:
- - main
- - stable-*
-
-variables:
- - name: checkoutPath
- value: ansible_collections/community/azure
- - name: coverageBranches
- value: main
- - name: pipelinesCoverage
- value: coverage
- - name: entryPoint
- value: tests/utils/shippable/shippable.sh
- - name: fetchDepth
- value: 0
-
-resources:
- containers:
- - container: default
- image: quay.io/ansible/azure-pipelines-test-container:3.0.0
-
-pool: Standard
-
-stages:
- - stage: Sanity_devel
- displayName: Sanity devel
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- nameFormat: Test {0}
- testFormat: devel/sanity/{0}
- targets:
- - test: 1
- - test: extra
- - stage: Summary
- condition: succeededOrFailed()
- dependsOn:
- - Sanity_devel
- jobs:
- - template: templates/coverage.yml
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/aggregate-coverage.sh b/ansible_collections/community/azure/.azure-pipelines/scripts/aggregate-coverage.sh
deleted file mode 100755
index f3113dd0a..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/aggregate-coverage.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env bash
-# Aggregate code coverage results for later processing.
-
-set -o pipefail -eu
-
-agent_temp_directory="$1"
-
-PATH="${PWD}/bin:${PATH}"
-
-mkdir "${agent_temp_directory}/coverage/"
-
-options=(--venv --venv-system-site-packages --color -v)
-
-ansible-test coverage combine --export "${agent_temp_directory}/coverage/" "${options[@]}"
-
-if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then
- # Only analyze coverage if the installed version of ansible-test supports it.
- # Doing so allows this script to work unmodified for multiple Ansible versions.
- ansible-test coverage analyze targets generate "${agent_temp_directory}/coverage/coverage-analyze-targets.json" "${options[@]}"
-fi
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/combine-coverage.py b/ansible_collections/community/azure/.azure-pipelines/scripts/combine-coverage.py
deleted file mode 100755
index 506ade646..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/combine-coverage.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-"""
-Combine coverage data from multiple jobs, keeping the data only from the most recent attempt from each job.
-Coverage artifacts must be named using the format: "Coverage $(System.JobAttempt) {StableUniqueNameForEachJob}"
-The recommended coverage artifact name format is: Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)
-Keep in mind that Azure Pipelines does not enforce unique job display names (only names).
-It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
-"""
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import os
-import re
-import shutil
-import sys
-
-
-def main():
- """Main program entry point."""
- source_directory = sys.argv[1]
-
- if '/ansible_collections/' in os.getcwd():
- output_path = "tests/output"
- else:
- output_path = "test/results"
-
- destination_directory = os.path.join(output_path, 'coverage')
-
- if not os.path.exists(destination_directory):
- os.makedirs(destination_directory)
-
- jobs = {}
- count = 0
-
- for name in os.listdir(source_directory):
- match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
- label = match.group('label')
- attempt = int(match.group('attempt'))
- jobs[label] = max(attempt, jobs.get(label, 0))
-
- for label, attempt in jobs.items():
- name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
- source = os.path.join(source_directory, name)
- source_files = os.listdir(source)
-
- for source_file in source_files:
- source_path = os.path.join(source, source_file)
- destination_path = os.path.join(destination_directory, source_file + '.' + label)
- print('"%s" -> "%s"' % (source_path, destination_path))
- shutil.copyfile(source_path, destination_path)
- count += 1
-
- print('Coverage file count: %d' % count)
- print('##vso[task.setVariable variable=coverageFileCount]%d' % count)
- print('##vso[task.setVariable variable=outputPath]%s' % output_path)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/process-results.sh b/ansible_collections/community/azure/.azure-pipelines/scripts/process-results.sh
deleted file mode 100755
index f3f1d1bae..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/process-results.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-# Check the test results and set variables for use in later steps.
-
-set -o pipefail -eu
-
-if [[ "$PWD" =~ /ansible_collections/ ]]; then
- output_path="tests/output"
-else
- output_path="test/results"
-fi
-
-echo "##vso[task.setVariable variable=outputPath]${output_path}"
-
-if compgen -G "${output_path}"'/junit/*.xml' > /dev/null; then
- echo "##vso[task.setVariable variable=haveTestResults]true"
-fi
-
-if compgen -G "${output_path}"'/bot/ansible-test-*' > /dev/null; then
- echo "##vso[task.setVariable variable=haveBotResults]true"
-fi
-
-if compgen -G "${output_path}"'/coverage/*' > /dev/null; then
- echo "##vso[task.setVariable variable=haveCoverageData]true"
-fi
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/publish-codecov.sh b/ansible_collections/community/azure/.azure-pipelines/scripts/publish-codecov.sh
deleted file mode 100755
index 6d184f0b8..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/publish-codecov.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-# Upload code coverage reports to codecov.io.
-# Multiple coverage files from multiple languages are accepted and aggregated after upload.
-# Python coverage, as well as PowerShell and Python stubs can all be uploaded.
-
-set -o pipefail -eu
-
-output_path="$1"
-
-curl --silent --show-error https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh > codecov.sh
-
-for file in "${output_path}"/reports/coverage*.xml; do
- name="${file}"
- name="${name##*/}" # remove path
- name="${name##coverage=}" # remove 'coverage=' prefix if present
- name="${name%.xml}" # remove '.xml' suffix
-
- bash codecov.sh \
- -f "${file}" \
- -n "${name}" \
- -X coveragepy \
- -X gcov \
- -X fix \
- -X search \
- -X xcode \
- || echo "Failed to upload code coverage report to codecov.io: ${file}"
-done
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/report-coverage.sh b/ansible_collections/community/azure/.azure-pipelines/scripts/report-coverage.sh
deleted file mode 100755
index 1bd91bdc9..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/report-coverage.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
-
-set -o pipefail -eu
-
-PATH="${PWD}/bin:${PATH}"
-
-if ! ansible-test --help >/dev/null 2>&1; then
- # Install the devel version of ansible-test for generating code coverage reports.
- # This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).
- # Since a version of ansible-test is required that can work the output from multiple older releases, the devel version is used.
- pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
-fi
-
-ansible-test coverage xml --stub --venv --venv-system-site-packages --color -v
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/run-tests.sh b/ansible_collections/community/azure/.azure-pipelines/scripts/run-tests.sh
deleted file mode 100755
index a947fdf01..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/run-tests.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-# Configure the test environment and run the tests.
-
-set -o pipefail -eu
-
-entry_point="$1"
-test="$2"
-read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
-
-export COMMIT_MESSAGE
-export COMPLETE
-export COVERAGE
-export IS_PULL_REQUEST
-
-if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
- IS_PULL_REQUEST=true
- COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD^2)
-else
- IS_PULL_REQUEST=
- COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
-fi
-
-COMPLETE=
-COVERAGE=
-
-if [ "${BUILD_REASON}" = "Schedule" ]; then
- COMPLETE=yes
-
- if printf '%s\n' "${coverage_branches[@]}" | grep -q "^${BUILD_SOURCEBRANCHNAME}$"; then
- COVERAGE=yes
- fi
-fi
-
-"${entry_point}" "${test}" 2>&1 | "$(dirname "$0")/time-command.py"
diff --git a/ansible_collections/community/azure/.azure-pipelines/scripts/time-command.py b/ansible_collections/community/azure/.azure-pipelines/scripts/time-command.py
deleted file mode 100755
index 5e8eb8d4c..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/scripts/time-command.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-import time
-
-
-def main():
- """Main program entry point."""
- start = time.time()
-
- sys.stdin.reconfigure(errors='surrogateescape')
- sys.stdout.reconfigure(errors='surrogateescape')
-
- for line in sys.stdin:
- seconds = time.time() - start
- sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
- sys.stdout.flush()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/azure/.azure-pipelines/templates/coverage.yml b/ansible_collections/community/azure/.azure-pipelines/templates/coverage.yml
deleted file mode 100644
index 1864e4441..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/templates/coverage.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-# This template adds a job for processing code coverage data.
-# It will upload results to Azure Pipelines and codecov.io.
-# Use it from a job stage that completes after all other jobs have completed.
-# This can be done by placing it in a separate summary stage that runs after the test stage(s) have completed.
-
-jobs:
- - job: Coverage
- displayName: Code Coverage
- container: default
- workspace:
- clean: all
- steps:
- - checkout: self
- fetchDepth: $(fetchDepth)
- path: $(checkoutPath)
- - task: DownloadPipelineArtifact@2
- displayName: Download Coverage Data
- inputs:
- path: coverage/
- patterns: "Coverage */*=coverage.combined"
- - bash: .azure-pipelines/scripts/combine-coverage.py coverage/
- displayName: Combine Coverage Data
- - bash: .azure-pipelines/scripts/report-coverage.sh
- displayName: Generate Coverage Report
- condition: gt(variables.coverageFileCount, 0)
- - task: PublishCodeCoverageResults@1
- inputs:
- codeCoverageTool: Cobertura
- # Azure Pipelines only accepts a single coverage data file.
- # That means only Python or PowerShell coverage can be uploaded, but not both.
- # Set the "pipelinesCoverage" variable to determine which type is uploaded.
- # Use "coverage" for Python and "coverage-powershell" for PowerShell.
- summaryFileLocation: "$(outputPath)/reports/$(pipelinesCoverage).xml"
- displayName: Publish to Azure Pipelines
- condition: gt(variables.coverageFileCount, 0)
- - bash: .azure-pipelines/scripts/publish-codecov.sh "$(outputPath)"
- displayName: Publish to codecov.io
- condition: gt(variables.coverageFileCount, 0)
- continueOnError: true
diff --git a/ansible_collections/community/azure/.azure-pipelines/templates/matrix.yml b/ansible_collections/community/azure/.azure-pipelines/templates/matrix.yml
deleted file mode 100644
index 4e9555dd3..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/templates/matrix.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-# This template uses the provided targets and optional groups to generate a matrix which is then passed to the test template.
-# If this matrix template does not provide the required functionality, consider using the test template directly instead.
-
-parameters:
- # A required list of dictionaries, one per test target.
- # Each item in the list must contain a "test" or "name" key.
- # Both may be provided. If one is omitted, the other will be used.
- - name: targets
- type: object
-
- # An optional list of values which will be used to multiply the targets list into a matrix.
- # Values can be strings or numbers.
- - name: groups
- type: object
- default: []
-
- # An optional format string used to generate the job name.
- # - {0} is the name of an item in the targets list.
- - name: nameFormat
- type: string
- default: "{0}"
-
- # An optional format string used to generate the test name.
- # - {0} is the name of an item in the targets list.
- - name: testFormat
- type: string
- default: "{0}"
-
- # An optional format string used to add the group to the job name.
- # {0} is the formatted name of an item in the targets list.
- # {{1}} is the group -- be sure to include the double "{{" and "}}".
- - name: nameGroupFormat
- type: string
- default: "{0} - {{1}}"
-
- # An optional format string used to add the group to the test name.
- # {0} is the formatted test of an item in the targets list.
- # {{1}} is the group -- be sure to include the double "{{" and "}}".
- - name: testGroupFormat
- type: string
- default: "{0}/{{1}}"
-
-jobs:
- - template: test.yml
- parameters:
- jobs:
- - ${{ if eq(length(parameters.groups), 0) }}:
- - ${{ each target in parameters.targets }}:
- - name: ${{ format(parameters.nameFormat, coalesce(target.name, target.test)) }}
- test: ${{ format(parameters.testFormat, coalesce(target.test, target.name)) }}
- - ${{ if not(eq(length(parameters.groups), 0)) }}:
- - ${{ each group in parameters.groups }}:
- - ${{ each target in parameters.targets }}:
- - name: ${{ format(format(parameters.nameGroupFormat, parameters.nameFormat), coalesce(target.name, target.test), group) }}
- test: ${{ format(format(parameters.testGroupFormat, parameters.testFormat), coalesce(target.test, target.name), group) }}
diff --git a/ansible_collections/community/azure/.azure-pipelines/templates/test.yml b/ansible_collections/community/azure/.azure-pipelines/templates/test.yml
deleted file mode 100644
index 5250ed802..000000000
--- a/ansible_collections/community/azure/.azure-pipelines/templates/test.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-# This template uses the provided list of jobs to create test one or more test jobs.
-# It can be used directly if needed, or through the matrix template.
-
-parameters:
- # A required list of dictionaries, one per test job.
- # Each item in the list must contain a "job" and "name" key.
- - name: jobs
- type: object
-
-jobs:
- - ${{ each job in parameters.jobs }}:
- - job: test_${{ replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_') }}
- displayName: ${{ job.name }}
- container: default
- workspace:
- clean: all
- steps:
- - checkout: self
- fetchDepth: $(fetchDepth)
- path: $(checkoutPath)
- - bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
- displayName: Run Tests
- - bash: .azure-pipelines/scripts/process-results.sh
- condition: succeededOrFailed()
- displayName: Process Results
- - bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
- condition: eq(variables.haveCoverageData, 'true')
- displayName: Aggregate Coverage Data
- - task: PublishTestResults@2
- condition: eq(variables.haveTestResults, 'true')
- inputs:
- testResultsFiles: "$(outputPath)/junit/*.xml"
- displayName: Publish Test Results
- - task: PublishPipelineArtifact@1
- condition: eq(variables.haveBotResults, 'true')
- displayName: Publish Bot Results
- inputs:
- targetPath: "$(outputPath)/bot/"
- artifactName: "Bot $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"
- - task: PublishPipelineArtifact@1
- condition: eq(variables.haveCoverageData, 'true')
- displayName: Publish Coverage Data
- inputs:
- targetPath: "$(Agent.TempDirectory)/coverage/"
- artifactName: "Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"
diff --git a/ansible_collections/community/azure/CHANGELOG.rst b/ansible_collections/community/azure/CHANGELOG.rst
deleted file mode 100644
index 8f24761cf..000000000
--- a/ansible_collections/community/azure/CHANGELOG.rst
+++ /dev/null
@@ -1,108 +0,0 @@
-=============================
-Community Azure Release Notes
-=============================
-
-.. contents:: Topics
-
-
-v2.0.0
-======
-
-Release Summary
----------------
-
-This release removes all deprecated content - which is all content in this collection. Please remove all FQCNs mentioning this collection and replace them with the appropriate modules from azure.azcollection.
-
-Removed Features (previously deprecated)
-----------------------------------------
-
-- azure_rm_aks_facts, azure_rm_aks_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_aks_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_aksversion_facts, azure_rm_aksversion_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_aksversion_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_applicationsecuritygroup_facts, azure_rm_applicationsecuritygroup_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_applicationsecuritygroup_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_appserviceplan_facts, azure_rm_appserviceplan_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_appserviceplan_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_automationaccount_facts, azure_rm_automationaccount_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_automationaccount_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_autoscale_facts, azure_rm_autoscale_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_autoscale_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_availabilityset_facts, azure_rm_availabilityset_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_availabilityset_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_cdnendpoint_facts, azure_rm_cdnendpoint_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_cdnendpoint_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_cdnprofile_facts, azure_rm_cdnprofile_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_cdnprofile_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_containerinstance_facts, azure_rm_containerinstance_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_containerinstance_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_containerregistry_facts, azure_rm_containerregistry_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_containerregistry_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_cosmosdbaccount_facts, azure_rm_cosmosdbaccount_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_cosmosdbaccount_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_deployment_facts, azure_rm_deployment_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_deployment_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlab_facts, azure_rm_devtestlab_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlab_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabarmtemplate_facts, azure_rm_devtestlabarmtemplate_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabarmtemplate_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabartifact_facts, azure_rm_devtestlabartifact_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabartifact_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabartifactsource_facts, azure_rm_devtestlabartifactsource_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabartifactsource_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabcustomimage_facts, azure_rm_devtestlabcustomimage_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabcustomimage_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabenvironment_facts, azure_rm_devtestlabenvironment_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabenvironment_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabpolicy_facts, azure_rm_devtestlabpolicy_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabpolicy_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabschedule_facts, azure_rm_devtestlabschedule_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabschedule_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabvirtualmachine_facts, azure_rm_devtestlabvirtualmachine_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabvirtualmachine_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_devtestlabvirtualnetwork_facts, azure_rm_devtestlabvirtualnetwork_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabvirtualnetwork_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_dnsrecordset_facts, azure_rm_dnsrecordset_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_dnsrecordset_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_dnszone_facts, azure_rm_dnszone_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_dnszone_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_functionapp_facts, azure_rm_functionapp_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_functionapp_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_hdinsightcluster_facts, azure_rm_hdinsightcluster_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_hdinsightcluster_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_image_facts, azure_rm_image_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_image_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_loadbalancer_facts, azure_rm_loadbalancer_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_loadbalancer_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_lock_facts, azure_rm_lock_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_lock_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_loganalyticsworkspace_facts, azure_rm_loganalyticsworkspace_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_loganalyticsworkspace_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_managed_disk, azure_rm_manageddisk - the deprecated modules have been removed. Use azure.azcollection.azure_rm_manageddisk instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_managed_disk_facts, azure_rm_manageddisk_facts, azure_rm_manageddisk_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_manageddisk_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mariadbconfiguration_facts, azure_rm_mariadbconfiguration_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mariadbconfiguration_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mariadbdatabase_facts, azure_rm_mariadbdatabase_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mariadbdatabase_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mariadbfirewallrule_facts, azure_rm_mariadbfirewallrule_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mariadbfirewallrule_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mariadbserver_facts, azure_rm_mariadbserver_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mariadbserver_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mysqlconfiguration_facts, azure_rm_mysqlconfiguration_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mysqlconfiguration_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mysqldatabase_facts, azure_rm_mysqldatabase_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mysqldatabase_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mysqlfirewallrule_facts, azure_rm_mysqlfirewallrule_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mysqlfirewallrule_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_mysqlserver_facts, azure_rm_mysqlserver_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_mysqlserver_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_networkinterface_facts, azure_rm_networkinterface_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_networkinterface_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_postgresqlconfiguration_facts, azure_rm_postgresqlconfiguration_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqlconfiguration_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_postgresqldatabase_facts, azure_rm_postgresqldatabase_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqldatabase_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_postgresqlfirewallrule_facts, azure_rm_postgresqlfirewallrule_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqlfirewallrule_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_postgresqlserver_facts, azure_rm_postgresqlserver_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqlserver_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_publicipaddress_facts, azure_rm_publicipaddress_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_publicipaddress_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_rediscache_facts, azure_rm_rediscache_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_rediscache_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_resource_facts, azure_rm_resource_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_resource_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_resourcegroup_facts, azure_rm_resourcegroup_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_resourcegroup_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_roleassignment_facts, azure_rm_roleassignment_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_roleassignment_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_roledefinition_facts, azure_rm_roledefinition_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_roledefinition_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_routetable_facts, azure_rm_routetable_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_routetable_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_securitygroup_facts, azure_rm_securitygroup_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_securitygroup_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_servicebus_facts, azure_rm_servicebus_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_servicebus_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_sqldatabase_facts, azure_rm_sqldatabase_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_sqldatabase_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_sqlfirewallrule_facts, azure_rm_sqlfirewallrule_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_sqlfirewallrule_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_sqlserver_facts, azure_rm_sqlserver_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_sqlserver_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_storageaccount_facts, azure_rm_storageaccount_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_storageaccount_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_subnet_facts, azure_rm_subnet_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_subnet_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_trafficmanagerendpoint_facts, azure_rm_trafficmanagerendpoint_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_trafficmanagerendpoint_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_trafficmanagerprofile_facts, azure_rm_trafficmanagerprofile_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_trafficmanagerprofile_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachine_extension, azure_rm_virtualmachineextension - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachineextension instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachine_facts, azure_rm_virtualmachine_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachine_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachine_scaleset, azure_rm_virtualmachinescaleset - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescaleset instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachine_scaleset_facts, azure_rm_virtualmachinescaleset_facts, azure_rm_virtualmachinescaleset_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescaleset_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachineextension_facts, azure_rm_virtualmachineextension_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachineextension_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachineimage_facts, azure_rm_virtualmachineimage_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachineimage_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachinescalesetextension_facts, azure_rm_virtualmachinescalesetextension_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescalesetextension_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualmachinescalesetinstance_facts, azure_rm_virtualmachinescalesetinstance_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescalesetinstance_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualnetwork_facts, azure_rm_virtualnetwork_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualnetwork_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_virtualnetworkpeering_facts, azure_rm_virtualnetworkpeering_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualnetworkpeering_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-- azure_rm_webapp_facts, azure_rm_webapp_info - the deprecated modules have been removed. Use azure.azcollection.azure_rm_webapp_info instead (https://github.com/ansible-collections/community.azure/pull/31).
-
-v1.1.0
-======
-
-Release Summary
----------------
-
-The community.azure Ansible collection is being deprecated in favor of azure.azcollection which provide the same modules in addition to maintenance and updates (https://github.com/ansible-collections/community.azure/pull/24).
-
-Deprecated Features
--------------------
-
-- All community.azure.azure_rm_<resource>_facts modules are deprecated. Use azure.azcollection.azure_rm_<resource>_info modules instead (https://github.com/ansible-collections/community.azure/pull/24).
-- All community.azure.azure_rm_<resource>_info modules are deprecated. Use azure.azcollection.azure_rm_<resource>_info modules instead (https://github.com/ansible-collections/community.azure/pull/24).
-- community.azure.azure_rm_managed_disk and community.azure.azure_rm_manageddisk are deprecated. Use azure.azcollection.azure_rm_manageddisk instead (https://github.com/ansible-collections/community.azure/pull/24).
-- community.azure.azure_rm_virtualmachine_extension and community.azure.azure_rm_virtualmachineextension are deprecated. Use azure.azcollection.azure_rm_virtualmachineextension instead (https://github.com/ansible-collections/community.azure/pull/24).
-- community.azure.azure_rm_virtualmachine_scaleset and community.azure.azure_rm_virtualmachinescaleset are deprecated. Use azure.azcollection.azure_rm_virtualmachinescaleset instead (https://github.com/ansible-collections/community.azure/pull/24).
diff --git a/ansible_collections/community/azure/COPYING b/ansible_collections/community/azure/COPYING
deleted file mode 100644
index 10926e87f..000000000
--- a/ansible_collections/community/azure/COPYING
+++ /dev/null
@@ -1,675 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
diff --git a/ansible_collections/community/azure/FILES.json b/ansible_collections/community/azure/FILES.json
deleted file mode 100644
index 77cc99511..000000000
--- a/ansible_collections/community/azure/FILES.json
+++ /dev/null
@@ -1,334 +0,0 @@
-{
- "files": [
- {
- "name": ".",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".azure-pipelines",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/aggregate-coverage.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "820353ffde6fd3ad655118772547549d84ccf0a7ba951e8fb1325f912ef640a0",
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/combine-coverage.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e34d4e863a65b9f53c4ca8ae37655858969898a949e050e9cb3cb0d5f02342d0",
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/process-results.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "c03d7273fe58882a439b6723e92ab89f1e127772b5ce35aa67c546dd62659741",
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/publish-codecov.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "70c795c8dbca2534b7909b17911630b7afaa693bbd7154e63a51340bc8b28dad",
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/report-coverage.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "f6a373322759ccc2736fb25d25d8c402dfe16b5d9a57cfccb1ca8cb136e09663",
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/run-tests.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "cb08a3ec5715b00d476ae6d63ca22e11a9ad8887239439937d2a7ea342e5a623",
- "format": 1
- },
- {
- "name": ".azure-pipelines/scripts/time-command.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "0232f415efeb583ddff907c058986963b775441eaf129d7162aee0acb0d36834",
- "format": 1
- },
- {
- "name": ".azure-pipelines/templates",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".azure-pipelines/templates/coverage.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "daf1930264760d47b54588f05c6339fd69ca2d239c77c44bc4cee3c4e9f76447",
- "format": 1
- },
- {
- "name": ".azure-pipelines/templates/matrix.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "4fb0d3ffb2125d5806c7597e4f9d4b2af69cf8c337e9d57803081eddd4a6b081",
- "format": 1
- },
- {
- "name": ".azure-pipelines/templates/test.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "2cfa1271f94c71f05ffa0b1f763d8946394b5636e14579cda8ee14bb38bbcf1c",
- "format": 1
- },
- {
- "name": ".azure-pipelines/README.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "61f20decd3c8fb34ac2cc6ff79f598fc5136e642130a7ba065ccc5aa37960cd2",
- "format": 1
- },
- {
- "name": ".azure-pipelines/azure-pipelines.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d3193a7a5803efaf917abedde39c2042ec02944bddd543282a2879b7f763ce29",
- "format": 1
- },
- {
- "name": "changelogs",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "changelogs/fragments",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "changelogs/fragments/.keep",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "changelogs/changelog.yaml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "58044ac766b9c97d21095147b81632265fdb0c7f314e91d8a4bebd54e78f1ec2",
- "format": 1
- },
- {
- "name": "changelogs/config.yaml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "725e6a5f873017468763ab099f7d218cafdeafdf5971130e2305c0de915e5285",
- "format": 1
- },
- {
- "name": "meta",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "meta/action_groups.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "17900c5cb6c043d1c90df45db9c3e6aafaf48e42869ec20b5c2fe97cae327b43",
- "format": 1
- },
- {
- "name": "meta/runtime.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d6ddd241bee2e5199a655700ca9582aa1e4be78b65d86ae330ef7e1be9354fd6",
- "format": 1
- },
- {
- "name": "tests",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/sanity",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.10.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.11.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.12.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.13.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.14.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
- "name": "tests/utils",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/utils/ado",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/utils/ado/ado.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "879019cb9fa8ea2ac1ae81197ebc880b20071f7e582407a7ba1d30002e9cb968",
- "format": 1
- },
- {
- "name": "tests/utils/shippable",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/utils/shippable/azure.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "dd953f7e779b9962e76492c389142e03174e84a8115f53e56628e2af9e66b818",
- "format": 1
- },
- {
- "name": "tests/utils/shippable/check_matrix.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "b228ec82e84aa69522362aa3f41c5b36e6f4e98553511362854456a474d99403",
- "format": 1
- },
- {
- "name": "tests/utils/shippable/cloud.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "dd953f7e779b9962e76492c389142e03174e84a8115f53e56628e2af9e66b818",
- "format": 1
- },
- {
- "name": "tests/utils/shippable/sanity.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "a01d92ca36ea457c0e7032ece03a0b485377eef8c8598d8f7c04a185fba279ed",
- "format": 1
- },
- {
- "name": "tests/utils/shippable/shippable.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "4cb1454fbf19a21fd59aba82b302e4df97e8960e2f243c3e9cc6410fd121b239",
- "format": 1
- },
- {
- "name": "tests/utils/shippable/timing.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "ebb7d3553349747ad41d80899ed353e13cf32fcbecbb6566cf36e9d2bc33703e",
- "format": 1
- },
- {
- "name": "tests/utils/shippable/timing.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "f3f3cc03a997cdba719b0542fe668fc612451841cbe840ab36865f30aa54a1bd",
- "format": 1
- },
- {
- "name": "tests/.gitignore",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "b5726d3ec9335a09c124469eca039523847a6b0f08a083efaefd002b83326600",
- "format": 1
- },
- {
- "name": "CHANGELOG.rst",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "a74258d7ee46a864abfe4793fee43fe90e1156a156fbbfee9c9230b5ee67dc9b",
- "format": 1
- },
- {
- "name": "COPYING",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "0ae0485a5bd37a63e63603596417e4eb0e653334fa6c7f932ca3a0e85d4af227",
- "format": 1
- },
- {
- "name": "README.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "3ec683d47faa8f5de129b70de6cba4adea8c80bd655dc3c56421a48bfcadbd58",
- "format": 1
- },
- {
- "name": "shippable.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "bf58f0d30ac91d3e80bd4217f433c2b1c5cba5e7702506ab72d245e0669d0f5b",
- "format": 1
- }
- ],
- "format": 1
-} \ No newline at end of file
diff --git a/ansible_collections/community/azure/MANIFEST.json b/ansible_collections/community/azure/MANIFEST.json
deleted file mode 100644
index ec7172262..000000000
--- a/ansible_collections/community/azure/MANIFEST.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "collection_info": {
- "namespace": "community",
- "name": "azure",
- "version": "2.0.0",
- "authors": [
- "Ansible (github.com/ansible)"
- ],
- "readme": "README.md",
- "tags": [
- "azure"
- ],
- "description": "The Community Azure Collection",
- "license": [],
- "license_file": "COPYING",
- "dependencies": {
- "azure.azcollection": ">=1.0.0"
- },
- "repository": "https://github.com/ansible-collections/community.azure",
- "documentation": "https://docs.ansible.com/ansible/2.10/collections/community/azure/",
- "homepage": "https://github.com/ansible-collections/community.azure",
- "issues": "https://github.com/ansible-collections/community.azure/issues"
- },
- "file_manifest_file": {
- "name": "FILES.json",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8e7ca871abb1ba686b6502e222d6aa4a8e5c4661a2e1cf437f86c0e945260c9e",
- "format": 1
- },
- "format": 1
-} \ No newline at end of file
diff --git a/ansible_collections/community/azure/README.md b/ansible_collections/community/azure/README.md
deleted file mode 100644
index 765e232f5..000000000
--- a/ansible_collections/community/azure/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Ansible Community Azure Collection
-
-THIS COLLECTION IS DEPRECATED, USE [azure.azcollection](https://github.com/ansible-collections/azure) INSTEAD!
-
-[![Build Status](https://dev.azure.com/ansible/community.azure/_apis/build/status/CI?branchName=master)](https://dev.azure.com/ansible/community.azure/_build?definitionId=30)
-[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.azure)](https://codecov.io/gh/ansible-collections/community.azure)
-
-Provides modules for [Ansible](https://www.ansible.com/community) for various Azure operations.
-
-## Requirements
-
-- ansible version >= 2.9
-
-## Installation
-
-To install Azure collection hosted in Galaxy:
-
-```bash
-ansible-galaxy collection install community.azure
-```
-
-To upgrade to the latest version of Azure collection:
-
-```bash
-ansible-galaxy collection install community.azure --force
-```
-
-## More information
-
-- [Ansible Collection overview](https://github.com/ansible-collections/overview)
-- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html)
-- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html)
-- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
-
-## Licensing
-
-GNU General Public License v3.0 or later.
-
-See [COPYING](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text.
diff --git a/ansible_collections/community/azure/changelogs/changelog.yaml b/ansible_collections/community/azure/changelogs/changelog.yaml
deleted file mode 100644
index 7af7fc5d1..000000000
--- a/ansible_collections/community/azure/changelogs/changelog.yaml
+++ /dev/null
@@ -1,228 +0,0 @@
-ancestor: null
-releases:
- 1.1.0:
- changes:
- deprecated_features:
- - All community.azure.azure_rm_<resource>_facts modules are deprecated. Use
- azure.azcollection.azure_rm_<resource>_info modules instead (https://github.com/ansible-collections/community.azure/pull/24).
- - All community.azure.azure_rm_<resource>_info modules are deprecated. Use azure.azcollection.azure_rm_<resource>_info
- modules instead (https://github.com/ansible-collections/community.azure/pull/24).
- - community.azure.azure_rm_managed_disk and community.azure.azure_rm_manageddisk
- are deprecated. Use azure.azcollection.azure_rm_manageddisk instead (https://github.com/ansible-collections/community.azure/pull/24).
- - community.azure.azure_rm_virtualmachine_extension and community.azure.azure_rm_virtualmachineextension
- are deprecated. Use azure.azcollection.azure_rm_virtualmachineextension instead
- (https://github.com/ansible-collections/community.azure/pull/24).
- - community.azure.azure_rm_virtualmachine_scaleset and community.azure.azure_rm_virtualmachinescaleset
- are deprecated. Use azure.azcollection.azure_rm_virtualmachinescaleset instead
- (https://github.com/ansible-collections/community.azure/pull/24).
- release_summary: The community.azure Ansible collection is being deprecated
- in favor of azure.azcollection which provide the same modules in addition
- to maintenance and updates (https://github.com/ansible-collections/community.azure/pull/24).
- fragments:
- - 1.1.0.yaml
- release_date: '2021-11-01'
- 2.0.0:
- changes:
- release_summary: This release removes all deprecated content - which is all
- content in this collection. Please remove all FQCNs mentioning this collection
- and replace them with the appropriate modules from azure.azcollection.
- removed_features:
- - azure_rm_aks_facts, azure_rm_aks_info - the deprecated modules have been removed.
- Use azure.azcollection.azure_rm_aks_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_aksversion_facts, azure_rm_aksversion_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_aksversion_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_applicationsecuritygroup_facts, azure_rm_applicationsecuritygroup_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_applicationsecuritygroup_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_appserviceplan_facts, azure_rm_appserviceplan_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_appserviceplan_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_automationaccount_facts, azure_rm_automationaccount_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_automationaccount_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_autoscale_facts, azure_rm_autoscale_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_autoscale_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_availabilityset_facts, azure_rm_availabilityset_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_availabilityset_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_cdnendpoint_facts, azure_rm_cdnendpoint_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_cdnendpoint_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_cdnprofile_facts, azure_rm_cdnprofile_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_cdnprofile_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_containerinstance_facts, azure_rm_containerinstance_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_containerinstance_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_containerregistry_facts, azure_rm_containerregistry_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_containerregistry_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_cosmosdbaccount_facts, azure_rm_cosmosdbaccount_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_cosmosdbaccount_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_deployment_facts, azure_rm_deployment_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_deployment_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlab_facts, azure_rm_devtestlab_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_devtestlab_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabarmtemplate_facts, azure_rm_devtestlabarmtemplate_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabarmtemplate_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabartifact_facts, azure_rm_devtestlabartifact_info - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabartifact_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabartifactsource_facts, azure_rm_devtestlabartifactsource_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabartifactsource_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabcustomimage_facts, azure_rm_devtestlabcustomimage_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabcustomimage_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabenvironment_facts, azure_rm_devtestlabenvironment_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabenvironment_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabpolicy_facts, azure_rm_devtestlabpolicy_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_devtestlabpolicy_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabschedule_facts, azure_rm_devtestlabschedule_info - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabschedule_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabvirtualmachine_facts, azure_rm_devtestlabvirtualmachine_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabvirtualmachine_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_devtestlabvirtualnetwork_facts, azure_rm_devtestlabvirtualnetwork_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_devtestlabvirtualnetwork_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_dnsrecordset_facts, azure_rm_dnsrecordset_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_dnsrecordset_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_dnszone_facts, azure_rm_dnszone_info - the deprecated modules have
- been removed. Use azure.azcollection.azure_rm_dnszone_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_functionapp_facts, azure_rm_functionapp_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_functionapp_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_hdinsightcluster_facts, azure_rm_hdinsightcluster_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_hdinsightcluster_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_image_facts, azure_rm_image_info - the deprecated modules have been
- removed. Use azure.azcollection.azure_rm_image_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_loadbalancer_facts, azure_rm_loadbalancer_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_loadbalancer_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_lock_facts, azure_rm_lock_info - the deprecated modules have been
- removed. Use azure.azcollection.azure_rm_lock_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_loganalyticsworkspace_facts, azure_rm_loganalyticsworkspace_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_loganalyticsworkspace_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_managed_disk, azure_rm_manageddisk - the deprecated modules have
- been removed. Use azure.azcollection.azure_rm_manageddisk instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_managed_disk_facts, azure_rm_manageddisk_facts, azure_rm_manageddisk_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_manageddisk_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mariadbconfiguration_facts, azure_rm_mariadbconfiguration_info -
- the deprecated modules have been removed. Use azure.azcollection.azure_rm_mariadbconfiguration_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mariadbdatabase_facts, azure_rm_mariadbdatabase_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_mariadbdatabase_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mariadbfirewallrule_facts, azure_rm_mariadbfirewallrule_info - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_mariadbfirewallrule_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mariadbserver_facts, azure_rm_mariadbserver_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_mariadbserver_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mysqlconfiguration_facts, azure_rm_mysqlconfiguration_info - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_mysqlconfiguration_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mysqldatabase_facts, azure_rm_mysqldatabase_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_mysqldatabase_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mysqlfirewallrule_facts, azure_rm_mysqlfirewallrule_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_mysqlfirewallrule_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_mysqlserver_facts, azure_rm_mysqlserver_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_mysqlserver_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_networkinterface_facts, azure_rm_networkinterface_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_networkinterface_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_postgresqlconfiguration_facts, azure_rm_postgresqlconfiguration_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqlconfiguration_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_postgresqldatabase_facts, azure_rm_postgresqldatabase_info - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqldatabase_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_postgresqlfirewallrule_facts, azure_rm_postgresqlfirewallrule_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_postgresqlfirewallrule_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_postgresqlserver_facts, azure_rm_postgresqlserver_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_postgresqlserver_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_publicipaddress_facts, azure_rm_publicipaddress_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_publicipaddress_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_rediscache_facts, azure_rm_rediscache_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_rediscache_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_resource_facts, azure_rm_resource_info - the deprecated modules have
- been removed. Use azure.azcollection.azure_rm_resource_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_resourcegroup_facts, azure_rm_resourcegroup_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_resourcegroup_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_roleassignment_facts, azure_rm_roleassignment_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_roleassignment_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_roledefinition_facts, azure_rm_roledefinition_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_roledefinition_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_routetable_facts, azure_rm_routetable_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_routetable_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_securitygroup_facts, azure_rm_securitygroup_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_securitygroup_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_servicebus_facts, azure_rm_servicebus_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_servicebus_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_sqldatabase_facts, azure_rm_sqldatabase_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_sqldatabase_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_sqlfirewallrule_facts, azure_rm_sqlfirewallrule_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_sqlfirewallrule_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_sqlserver_facts, azure_rm_sqlserver_info - the deprecated modules
- have been removed. Use azure.azcollection.azure_rm_sqlserver_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_storageaccount_facts, azure_rm_storageaccount_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_storageaccount_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_subnet_facts, azure_rm_subnet_info - the deprecated modules have
- been removed. Use azure.azcollection.azure_rm_subnet_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_trafficmanagerendpoint_facts, azure_rm_trafficmanagerendpoint_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_trafficmanagerendpoint_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_trafficmanagerprofile_facts, azure_rm_trafficmanagerprofile_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_trafficmanagerprofile_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachine_extension, azure_rm_virtualmachineextension - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachineextension
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachine_facts, azure_rm_virtualmachine_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_virtualmachine_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachine_scaleset, azure_rm_virtualmachinescaleset - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescaleset
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachine_scaleset_facts, azure_rm_virtualmachinescaleset_facts,
- azure_rm_virtualmachinescaleset_info - the deprecated modules have been removed.
- Use azure.azcollection.azure_rm_virtualmachinescaleset_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachineextension_facts, azure_rm_virtualmachineextension_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachineextension_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachineimage_facts, azure_rm_virtualmachineimage_info - the
- deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachineimage_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachinescalesetextension_facts, azure_rm_virtualmachinescalesetextension_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescalesetextension_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualmachinescalesetinstance_facts, azure_rm_virtualmachinescalesetinstance_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualmachinescalesetinstance_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualnetwork_facts, azure_rm_virtualnetwork_info - the deprecated
- modules have been removed. Use azure.azcollection.azure_rm_virtualnetwork_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_virtualnetworkpeering_facts, azure_rm_virtualnetworkpeering_info
- - the deprecated modules have been removed. Use azure.azcollection.azure_rm_virtualnetworkpeering_info
- instead (https://github.com/ansible-collections/community.azure/pull/31).
- - azure_rm_webapp_facts, azure_rm_webapp_info - the deprecated modules have
- been removed. Use azure.azcollection.azure_rm_webapp_info instead (https://github.com/ansible-collections/community.azure/pull/31).
- fragments:
- - 2.0.0.yml
- release_date: '2022-07-26'
diff --git a/ansible_collections/community/azure/changelogs/config.yaml b/ansible_collections/community/azure/changelogs/config.yaml
deleted file mode 100644
index 810dea1ad..000000000
--- a/ansible_collections/community/azure/changelogs/config.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-changelog_filename_template: ../CHANGELOG.rst
-changelog_filename_version_depth: 0
-changes_file: changelog.yaml
-changes_format: combined
-keep_fragments: false
-mention_ancestor: true
-new_plugins_after_name: removed_features
-notesdir: fragments
-prelude_section_name: release_summary
-prelude_section_title: Release Summary
-sections:
-- - major_changes
- - Major Changes
-- - minor_changes
- - Minor Changes
-- - breaking_changes
- - Breaking Changes / Porting Guide
-- - deprecated_features
- - Deprecated Features
-- - removed_features
- - Removed Features (previously deprecated)
-- - security_fixes
- - Security Fixes
-- - bugfixes
- - Bugfixes
-- - known_issues
- - Known Issues
-title: Community Azure
-trivial_section_name: trivial
diff --git a/ansible_collections/community/azure/changelogs/fragments/.keep b/ansible_collections/community/azure/changelogs/fragments/.keep
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/azure/changelogs/fragments/.keep
+++ /dev/null
diff --git a/ansible_collections/community/azure/meta/action_groups.yml b/ansible_collections/community/azure/meta/action_groups.yml
deleted file mode 100644
index 927052875..000000000
--- a/ansible_collections/community/azure/meta/action_groups.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-azure:
-- azure_rm_aks_facts
-- azure_rm_dnsrecordset_facts
-- azure_rm_dnszone_facts
-- azure_rm_networkinterface_facts
-- azure_rm_publicipaddress_facts
-- azure_rm_securitygroup_facts
-- azure_rm_storageaccount_facts
-- azure_rm_virtualmachine_facts
-- azure_rm_virtualnetwork_facts
-- azure_rm_mysqldatabase_facts
-- azure_rm_loadbalancer_facts
-- azure_rm_manageddisk_facts
-- azure_rm_mysqlserver_facts
-- azure_rm_resource_facts
-- azure_rm_virtualmachine_extension
-- azure_rm_availabilityset_facts
-- azure_rm_appserviceplan_facts
-- azure_rm_functionapp_facts
-- azure_rm_virtualmachineimage_facts
-- azure_rm_sqlserver_facts
-- azure_rm_postgresqldatabase_facts
-- azure_rm_virtualmachine_scaleset
-- azure_rm_managed_disk
-- azure_rm_managed_disk_facts
-- azure_rm_resourcegroup_facts
-- azure_rm_virtualmachine_scaleset_facts
diff --git a/ansible_collections/community/azure/meta/runtime.yml b/ansible_collections/community/azure/meta/runtime.yml
deleted file mode 100644
index 092a03569..000000000
--- a/ansible_collections/community/azure/meta/runtime.yml
+++ /dev/null
@@ -1,596 +0,0 @@
----
-requires_ansible: '>=2.9.10'
-plugin_routing:
- modules:
- azure_rm_aks_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_aks_info instead.
- azure_rm_dnsrecordset_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_dnsrecordset_info instead.
- azure_rm_dnszone_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_dnszone_info instead.
- azure_rm_networkinterface_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_networkinterface_info instead.
- azure_rm_publicipaddress_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_publicipaddress_info instead.
- azure_rm_securitygroup_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_securitygroup_info instead.
- azure_rm_storageaccount_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_storageaccount_info instead.
- azure_rm_virtualmachine_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachine_info instead.
- azure_rm_virtualnetwork_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualnetwork_info instead.
- azure_rm_roledefinition_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_roledefinition_info instead.
- azure_rm_autoscale_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_autoscale_info instead.
- azure_rm_mysqldatabase_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqldatabase_info instead.
- azure_rm_devtestlabschedule_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabschedule_info instead.
- azure_rm_virtualmachinescaleset_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescaleset_info instead.
- azure_rm_devtestlabcustomimage_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabcustomimage_info instead.
- azure_rm_cosmosdbaccount_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_cosmosdbaccount_info instead.
- azure_rm_subnet_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_subnet_info instead.
- azure_rm_aksversion_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_aksversion_info instead.
- azure_rm_hdinsightcluster_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_hdinsightcluster_info instead.
- azure_rm_virtualmachinescalesetextension_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescalesetextension_info instead.
- azure_rm_loadbalancer_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_loadbalancer_info instead.
- azure_rm_roleassignment_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_roleassignment_info instead.
- azure_rm_manageddisk_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_manageddisk_info instead.
- azure_rm_mysqlserver_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqlserver_info instead.
- azure_rm_servicebus_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_servicebus_info instead.
- azure_rm_rediscache_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_rediscache_info instead.
- azure_rm_resource_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_resource_info instead.
- azure_rm_routetable_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_routetable_info instead.
- azure_rm_virtualmachine_extension:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachineextension instead.
- azure_rm_loganalyticsworkspace_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_loganalyticsworkspace_info instead.
- azure_rm_sqldatabase_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_sqldatabase_info instead.
- azure_rm_devtestlabartifactsource_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabartifactsource_info instead.
- azure_rm_deployment_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_deployment_info instead.
- azure_rm_virtualmachineextension_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachineextension_info instead.
- azure_rm_applicationsecuritygroup_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_applicationsecuritygroup_info instead.
- azure_rm_availabilityset_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_availabilityset_info instead.
- azure_rm_mariadbdatabase_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbdatabase_info instead.
- azure_rm_devtestlabenvironment_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabenvironment_info instead.
- azure_rm_appserviceplan_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_appserviceplan_info instead.
- azure_rm_containerinstance_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_containerinstance_info instead.
- azure_rm_devtestlabarmtemplate_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabarmtemplate_info instead.
- azure_rm_devtestlabartifact_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabartifact_info instead.
- azure_rm_virtualmachinescalesetinstance_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescalesetinstance_info instead.
- azure_rm_cdnendpoint_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_cdnendpoint_info instead.
- azure_rm_trafficmanagerprofile_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_trafficmanagerprofile_info instead.
- azure_rm_functionapp_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_functionapp_info instead.
- azure_rm_virtualmachineimage_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachineimage_info instead.
- azure_rm_mariadbconfiguration_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbconfiguration_info instead.
- azure_rm_virtualnetworkpeering_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualnetworkpeering_info instead.
- azure_rm_sqlserver_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_sqlserver_info instead.
- azure_rm_mariadbfirewallrule_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbfirewallrule_info instead.
- azure_rm_mysqlconfiguration_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqlconfiguration_info instead.
- azure_rm_mysqlfirewallrule_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqlfirewallrule_info instead.
- azure_rm_postgresqlfirewallrule_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqlfirewallrule_info instead.
- azure_rm_mariadbserver_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbserver_info instead.
- azure_rm_postgresqldatabase_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqldatabase_info instead.
- azure_rm_devtestlabvirtualnetwork_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabvirtualnetwork_info instead.
- azure_rm_devtestlabpolicy_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabpolicy_info instead.
- azure_rm_trafficmanagerendpoint_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_trafficmanagerendpoint_info instead.
- azure_rm_sqlfirewallrule_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_sqlfirewallrule_info instead.
- azure_rm_containerregistry_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_containerregistry_info instead.
- azure_rm_postgresqlconfiguration_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqlconfiguration_info instead.
- azure_rm_postgresqlserver_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqlserver_info instead.
- azure_rm_devtestlab_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlab_info instead.
- azure_rm_cdnprofile_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_cdnprofile_info instead.
- azure_rm_virtualmachine_scaleset:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescaleset instead.
- azure_rm_webapp_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_webapp_info instead.
- azure_rm_devtestlabvirtualmachine_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabvirtualmachine_info instead.
- azure_rm_image_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_image_info instead.
- azure_rm_managed_disk:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_manageddisk instead.
- azure_rm_automationaccount_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_automationaccount_info instead.
- azure_rm_lock_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_lock_info instead.
- azure_rm_managed_disk_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_manageddisk_info instead.
- azure_rm_resourcegroup_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_resourcegroup_info instead.
- azure_rm_virtualmachine_scaleset_facts:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescaleset_info instead.
- azure_rm_virtualmachineextension:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachineextension instead.
- azure_rm_virtualmachinescaleset:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescaleset instead.
- azure_rm_mariadbserver_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbserver_info instead.
- azure_rm_devtestlabartifactsource_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabartifactsource_info instead.
- azure_rm_autoscale_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_autoscale_info instead.
- azure_rm_postgresqlconfiguration_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqlconfiguration_info instead.
- azure_rm_securitygroup_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_securitygroup_info instead.
- azure_rm_functionapp_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_functionapp_info instead.
- azure_rm_resourcegroup_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_resourcegroup_info instead.
- azure_rm_manageddisk_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_manageddisk_info instead.
- azure_rm_manageddisk:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_manageddisk instead.
- azure_rm_devtestlabschedule_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabschedule_info instead.
- azure_rm_containerinstance_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_containerinstance_info instead.
- azure_rm_networkinterface_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_networkinterface_info instead.
- azure_rm_devtestlabvirtualnetwork_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabvirtualnetwork_info instead.
- azure_rm_devtestlabcustomimage_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabcustomimage_info instead.
- azure_rm_resource_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_resource_info instead.
- azure_rm_mariadbfirewallrule_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbfirewallrule_info instead.
- azure_rm_roleassignment_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_roleassignment_info instead.
- azure_rm_trafficmanagerendpoint_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_trafficmanagerendpoint_info instead.
- azure_rm_mysqlconfiguration_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqlconfiguration_info instead.
- azure_rm_mysqlserver_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqlserver_info instead.
- azure_rm_postgresqldatabase_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqldatabase_info instead.
- azure_rm_subnet_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_subnet_info instead.
- azure_rm_virtualnetworkpeering_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualnetworkpeering_info instead.
- azure_rm_containerregistry_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_containerregistry_info instead.
- azure_rm_routetable_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_routetable_info instead.
- azure_rm_devtestlabvirtualmachine_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabvirtualmachine_info instead.
- azure_rm_virtualmachineimage_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachineimage_info instead.
- azure_rm_aksversion_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_aksversion_info instead.
- azure_rm_mysqldatabase_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqldatabase_info instead.
- azure_rm_availabilityset_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_availabilityset_info instead.
- azure_rm_automationaccount_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_automationaccount_info instead.
- azure_rm_virtualmachine_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachine_info instead.
- azure_rm_virtualnetwork_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualnetwork_info instead.
- azure_rm_virtualmachinescalesetinstance_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescalesetinstance_info instead.
- azure_rm_rediscache_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_rediscache_info instead.
- azure_rm_deployment_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_deployment_info instead.
- azure_rm_devtestlabenvironment_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabenvironment_info instead.
- azure_rm_dnszone_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_dnszone_info instead.
- azure_rm_applicationsecuritygroup_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_applicationsecuritygroup_info instead.
- azure_rm_postgresqlfirewallrule_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqlfirewallrule_info instead.
- azure_rm_webapp_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_webapp_info instead.
- azure_rm_devtestlabartifact_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabartifact_info instead.
- azure_rm_cdnprofile_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_cdnprofile_info instead.
- azure_rm_lock_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_lock_info instead.
- azure_rm_cdnendpoint_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_cdnendpoint_info instead.
- azure_rm_loadbalancer_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_loadbalancer_info instead.
- azure_rm_publicipaddress_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_publicipaddress_info instead.
- azure_rm_image_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_image_info instead.
- azure_rm_postgresqlserver_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_postgresqlserver_info instead.
- azure_rm_appserviceplan_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_appserviceplan_info instead.
- azure_rm_devtestlab_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlab_info instead.
- azure_rm_devtestlabpolicy_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabpolicy_info instead.
- azure_rm_dnsrecordset_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_dnsrecordset_info instead.
- azure_rm_roledefinition_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_roledefinition_info instead.
- azure_rm_virtualmachinescaleset_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescaleset_info instead.
- azure_rm_mysqlfirewallrule_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mysqlfirewallrule_info instead.
- azure_rm_cosmosdbaccount_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_cosmosdbaccount_info instead.
- azure_rm_sqlfirewallrule_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_sqlfirewallrule_info instead.
- azure_rm_sqldatabase_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_sqldatabase_info instead.
- azure_rm_sqlserver_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_sqlserver_info instead.
- azure_rm_servicebus_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_servicebus_info instead.
- azure_rm_virtualmachineextension_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachineextension_info instead.
- azure_rm_trafficmanagerprofile_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_trafficmanagerprofile_info instead.
- azure_rm_virtualmachinescalesetextension_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_virtualmachinescalesetextension_info instead.
- azure_rm_mariadbconfiguration_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbconfiguration_info instead.
- azure_rm_storageaccount_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_storageaccount_info instead.
- azure_rm_mariadbdatabase_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_mariadbdatabase_info instead.
- azure_rm_aks_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_aks_info instead.
- azure_rm_loganalyticsworkspace_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_loganalyticsworkspace_info instead.
- azure_rm_devtestlabarmtemplate_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_devtestlabarmtemplate_info instead.
- azure_rm_hdinsightcluster_info:
- tombstone:
- removal_version: 2.0.0
- warning_text: Use azure.azcollection.azure_rm_hdinsightcluster_info instead.
diff --git a/ansible_collections/community/azure/shippable.yml b/ansible_collections/community/azure/shippable.yml
deleted file mode 100644
index 2f43c46a3..000000000
--- a/ansible_collections/community/azure/shippable.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-language: python
-
-env:
- matrix:
- - T=none
-
-matrix:
- exclude:
- - env: T=none
- include:
- - env: T=devel/sanity/1
- - env: T=devel/sanity/extra
-# - env: T=2.10/sanity
-
-# - env: T=devel/azure/2.7/1
-# - env: T=devel/azure/3.6/1
-# - env: T=2.10/azure/2.7/1
-# - env: T=2.10/azure/3.6/1
-
-
-branches:
- except:
- - "*-patch-*"
- - "revert-*-*"
-
-build:
- ci:
- - tests/utils/shippable/timing.sh tests/utils/shippable/shippable.sh $T
-
-integrations:
- notifications:
- - integrationName: email
- type: email
- on_success: never
- on_failure: never
- on_start: never
- on_pull_request: never
diff --git a/ansible_collections/community/azure/tests/.gitignore b/ansible_collections/community/azure/tests/.gitignore
deleted file mode 100644
index ea1472ec1..000000000
--- a/ansible_collections/community/azure/tests/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-output/
diff --git a/ansible_collections/community/azure/tests/sanity/ignore-2.10.txt b/ansible_collections/community/azure/tests/sanity/ignore-2.10.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/azure/tests/sanity/ignore-2.10.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/azure/tests/sanity/ignore-2.11.txt b/ansible_collections/community/azure/tests/sanity/ignore-2.11.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/azure/tests/sanity/ignore-2.11.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/azure/tests/sanity/ignore-2.12.txt b/ansible_collections/community/azure/tests/sanity/ignore-2.12.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/azure/tests/sanity/ignore-2.12.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/azure/tests/sanity/ignore-2.13.txt b/ansible_collections/community/azure/tests/sanity/ignore-2.13.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/azure/tests/sanity/ignore-2.13.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/azure/tests/sanity/ignore-2.14.txt b/ansible_collections/community/azure/tests/sanity/ignore-2.14.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/azure/tests/sanity/ignore-2.14.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/azure/tests/utils/ado/ado.sh b/ansible_collections/community/azure/tests/utils/ado/ado.sh
deleted file mode 100755
index 55d7f66da..000000000
--- a/ansible_collections/community/azure/tests/utils/ado/ado.sh
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env bash
-
-set -o pipefail -eux
-
-declare -a args
-IFS='/:' read -ra args <<< "$1"
-
-group="${args[0]}"
-
-command -v python
-python -V
-
-if [ "$2" = "2.7" ]
-then
- command -v pip
- pip --version
- pip list --disable-pip-version-check
-else
- command -v pip3
- pip3 --version
- pip3 list --disable-pip-version-check
-fi
-
-export PATH="${PWD}/bin:${PATH}"
-export PYTHONIOENCODING="UTF-8"
-export LC_ALL="en_US.utf-8"
-
-if [ "$2" = "2.7" ]
-then
- pip install virtualenv
- virtualenv --python /usr/bin/python2.7 ~/ansible-venv
-else
- pip3 install virtualenv
- virtualenv --python /usr/bin/python"$2" ~/ansible-venv
-fi
-
-set +ux
-. ~/ansible-venv/bin/activate
-set -ux
-
-if [ "$2" = "2.7" ]
-then
- if [ "$3" = "devel" ]
- then
- pip install git+https://github.com/ansible/ansible.git@devel --disable-pip-version-check
- else
- git clone https://github.com/ansible/ansible.git
- cd "ansible"
- git checkout "stable-$3"
- source hacking/env-setup
- pip install paramiko PyYAML Jinja2 httplib2 six
- fi
-else
- if [ "$3" = "devel" ]
- then
- pip3 install git+https://github.com/ansible/ansible.git@devel --disable-pip-version-check
- else
- git clone https://github.com/ansible/ansible.git
- cd "ansible"
- git checkout "stable-$3"
- source hacking/env-setup
- pip3 install paramiko PyYAML Jinja2 httplib2 six
- fi
-fi
-
-TEST_DIR="${HOME}/.ansible/ansible_collections/azure/azcollection"
-mkdir -p "${TEST_DIR}"
-cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}"
-cd "${TEST_DIR}"
-mkdir -p shippable/testresults
-
-if [ "$2" = "2.7" ]
-then
- pip install --upgrade pip
- pip install -I -r "${TEST_DIR}/requirements-azure.txt"
- pip3 install setuptools
- pip3 install -I -r "${TEST_DIR}/sanity-requirements-azure.txt"
- pip3 list
-else
- pip3 install -I -r "${TEST_DIR}/requirements-azure.txt"
- pip3 install -I -r "${TEST_DIR}/sanity-requirements-azure.txt"
- pip3 list
-fi
-
-timeout=60
-
-if [ "$4" = "all" ]
-then
- echo "All module need test"
-else
- path_dir="${TEST_DIR}/tests/integration/targets/"
- for item in "$path_dir"*
- do
- if [ "${item}" = "$path_dir""$4" ]
- then
- echo "PASS"
- else
- echo " " >> "${item}"/aliases
- echo "disabled" >> "${item}"/aliases
- fi
- done
-fi
-echo '--------------------------------------------'
-ansible --version
-echo '--------------------------------------------'
-
-ansible-test env --dump --show --timeout "${timeout}" --color -v
-
-cat <<EOF >> "${TEST_DIR}"/tests/integration/cloud-config-azure.ini
-[default]
-AZURE_CLIENT_ID:${AZURE_CLIENT_ID}
-AZURE_SECRET:${AZURE_SECRET}
-AZURE_SUBSCRIPTION_ID:${AZURE_SUBSCRIPTION_ID}
-AZURE_TENANT:${AZURE_TENANT}
-RESOURCE_GROUP:${RESOURCE_GROUP}
-RESOURCE_GROUP_SECONDARY:${RESOURCE_GROUP_SECONDARY}
-EOF
-
-if [ "sanity" = "${group}" ]
-then
- ansible-test sanity --color -v --junit
-else
- ansible-test integration --color -v --retry-on-error "shippable/azure/group${group}/" --allow-destructive
-fi
diff --git a/ansible_collections/community/azure/tests/utils/shippable/azure.sh b/ansible_collections/community/azure/tests/utils/shippable/azure.sh
deleted file mode 100755
index d76c32282..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/azure.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-
-set -o pipefail -eux
-
-declare -a args
-IFS='/:' read -ra args <<< "$1"
-
-cloud="${args[0]}"
-python="${args[1]}"
-group="${args[2]}"
-
-target="shippable/${cloud}/group${group}/"
-
-stage="${S:-prod}"
-
-# shellcheck disable=SC2086
-ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
- --remote-terminate always --remote-stage "${stage}" \
- --docker --python "${python}"
diff --git a/ansible_collections/community/azure/tests/utils/shippable/check_matrix.py b/ansible_collections/community/azure/tests/utils/shippable/check_matrix.py
deleted file mode 100755
index fb5594668..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/check_matrix.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python
-"""Verify the currently executing Shippable test matrix matches the one defined in the "shippable.yml" file."""
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import datetime
-import json
-import os
-import re
-import sys
-import time
-
-try:
- from typing import NoReturn
-except ImportError:
- NoReturn = None
-
-try:
- # noinspection PyCompatibility
- from urllib2 import urlopen # pylint: disable=ansible-bad-import-from
-except ImportError:
- # noinspection PyCompatibility
- from urllib.request import urlopen
-
-
-def main(): # type: () -> None
- """Main entry point."""
- repo_full_name = os.environ['REPO_FULL_NAME']
- required_repo_full_name = 'ansible-collections/community.azure'
-
- if repo_full_name != required_repo_full_name:
- sys.stderr.write('Skipping matrix check on repo "%s" which is not "%s".\n' % (repo_full_name, required_repo_full_name))
- return
-
- with open('shippable.yml', 'rb') as yaml_file:
- yaml = yaml_file.read().decode('utf-8').splitlines()
-
- defined_matrix = [match.group(1) for match in [re.search(r'^ *- env: T=(.*)$', line) for line in yaml] if match and match.group(1) != 'none']
-
- if not defined_matrix:
- fail('No matrix entries found in the "shippable.yml" file.',
- 'Did you modify the "shippable.yml" file?')
-
- run_id = os.environ['SHIPPABLE_BUILD_ID']
- sleep = 1
- jobs = []
-
- for attempts_remaining in range(4, -1, -1):
- try:
- jobs = json.loads(urlopen('https://api.shippable.com/jobs?runIds=%s' % run_id).read())
-
- if not isinstance(jobs, list):
- raise Exception('Shippable run %s data is not a list.' % run_id)
-
- break
- except Exception as ex:
- if not attempts_remaining:
- fail('Unable to retrieve Shippable run %s matrix.' % run_id,
- str(ex))
-
- sys.stderr.write('Unable to retrieve Shippable run %s matrix: %s\n' % (run_id, ex))
- sys.stderr.write('Trying again in %d seconds...\n' % sleep)
- time.sleep(sleep)
- sleep *= 2
-
- if len(jobs) != len(defined_matrix):
- if len(jobs) == 1:
- hint = '\n\nMake sure you do not use the "Rebuild with SSH" option.'
- else:
- hint = ''
-
- fail('Shippable run %s has %d jobs instead of the expected %d jobs.' % (run_id, len(jobs), len(defined_matrix)),
- 'Try re-running the entire matrix.%s' % hint)
-
- actual_matrix = dict((job.get('jobNumber'), dict(tuple(line.split('=', 1)) for line in job.get('env', [])).get('T', '')) for job in jobs)
- errors = [(job_number, test, actual_matrix.get(job_number)) for job_number, test in enumerate(defined_matrix, 1) if actual_matrix.get(job_number) != test]
-
- if len(errors):
- error_summary = '\n'.join('Job %s expected "%s" but found "%s" instead.' % (job_number, expected, actual) for job_number, expected, actual in errors)
-
- fail('Shippable run %s has a job matrix mismatch.' % run_id,
- 'Try re-running the entire matrix.\n\n%s' % error_summary)
-
-
-def fail(message, output): # type: (str, str) -> NoReturn
- # Include a leading newline to improve readability on Shippable "Tests" tab.
- # Without this, the first line becomes indented.
- output = '\n' + output.strip()
-
- timestamp = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
-
- # hack to avoid requiring junit-xml, which isn't pre-installed on Shippable outside our test containers
- xml = '''
-<?xml version="1.0" encoding="utf-8"?>
-<testsuites disabled="0" errors="1" failures="0" tests="1" time="0.0">
-\t<testsuite disabled="0" errors="1" failures="0" file="None" log="None" name="ansible-test" skipped="0" tests="1" time="0" timestamp="%s" url="None">
-\t\t<testcase classname="timeout" name="timeout">
-\t\t\t<error message="%s" type="error">%s</error>
-\t\t</testcase>
-\t</testsuite>
-</testsuites>
-''' % (timestamp, message, output)
-
- path = 'shippable/testresults/check-matrix.xml'
- dir_path = os.path.dirname(path)
-
- if not os.path.exists(dir_path):
- os.makedirs(dir_path)
-
- with open(path, 'w') as junit_fd:
- junit_fd.write(xml.lstrip())
-
- sys.stderr.write(message + '\n')
- sys.stderr.write(output + '\n')
-
- sys.exit(1)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/azure/tests/utils/shippable/cloud.sh b/ansible_collections/community/azure/tests/utils/shippable/cloud.sh
deleted file mode 100755
index d76c32282..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/cloud.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-
-set -o pipefail -eux
-
-declare -a args
-IFS='/:' read -ra args <<< "$1"
-
-cloud="${args[0]}"
-python="${args[1]}"
-group="${args[2]}"
-
-target="shippable/${cloud}/group${group}/"
-
-stage="${S:-prod}"
-
-# shellcheck disable=SC2086
-ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
- --remote-terminate always --remote-stage "${stage}" \
- --docker --python "${python}"
diff --git a/ansible_collections/community/azure/tests/utils/shippable/sanity.sh b/ansible_collections/community/azure/tests/utils/shippable/sanity.sh
deleted file mode 100755
index c216220e8..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/sanity.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-
-set -o pipefail -eux
-
-declare -a args
-IFS='/:' read -ra args <<< "$1"
-
-group="${args[1]}"
-
-if [ "${BASE_BRANCH:-}" ]; then
- base_branch="origin/${BASE_BRANCH}"
-else
- base_branch=""
-fi
-
-if [ "${group}" == "extra" ]; then
- # ansible-galaxy -vvv collection install community.internal_test_tools
- git clone --single-branch --depth 1 https://github.com/ansible-collections/community.internal_test_tools.git ../internal_test_tools
-
- ../internal_test_tools/tools/run.py --color
- exit
-fi
-
-# shellcheck disable=SC2086
-ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
- --docker --base-branch "${base_branch}" \
- --allow-disabled
diff --git a/ansible_collections/community/azure/tests/utils/shippable/shippable.sh b/ansible_collections/community/azure/tests/utils/shippable/shippable.sh
deleted file mode 100755
index 363f06bcd..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/shippable.sh
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env bash
-
-set -o pipefail -eux
-
-declare -a args
-IFS='/:' read -ra args <<< "$1"
-
-ansible_version="${args[0]}"
-script="${args[1]}"
-
-function join {
- local IFS="$1";
- shift;
- echo "$*";
-}
-
-test="$(join / "${args[@]:1}")"
-
-docker images ansible/ansible
-docker images quay.io/ansible/*
-docker ps
-
-for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v -e '^drydock/' -e '^quay.io/ansible/azure-pipelines-test-container:' | sed 's/^.* //'); do
- docker rm -f "${container}" || true # ignore errors
-done
-
-docker ps
-
-if [ -d /home/shippable/cache/ ]; then
- ls -la /home/shippable/cache/
-fi
-
-command -v python
-python -V
-
-function retry
-{
- # shellcheck disable=SC2034
- for repetition in 1 2 3; do
- set +e
- "$@"
- result=$?
- set -e
- if [ ${result} == 0 ]; then
- return ${result}
- fi
- echo "@* -> ${result}"
- done
- echo "Command '@*' failed 3 times!"
- exit 255
-}
-
-command -v pip
-pip --version
-pip list --disable-pip-version-check
-if [ "${ansible_version}" == "devel" ]; then
- retry pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
-else
- retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
-fi
-
-if [ "${SHIPPABLE_BUILD_ID:-}" ]; then
- export ANSIBLE_COLLECTIONS_PATHS="${HOME}/.ansible"
- SHIPPABLE_RESULT_DIR="$(pwd)/shippable"
- TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/azure"
- mkdir -p "${TEST_DIR}"
- cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}"
- cd "${TEST_DIR}"
-else
- export ANSIBLE_COLLECTIONS_PATHS="${PWD}/../../../"
-fi
-
-# START: HACK install dependencies
-# retry ansible-galaxy -vvv collection install azure.azcollection
-
-# END: HACK
-
-export PYTHONIOENCODING='utf-8'
-
-if [ "${JOB_TRIGGERED_BY_NAME:-}" == "nightly-trigger" ]; then
- COVERAGE=yes
- COMPLETE=yes
-fi
-
-if [ -n "${COVERAGE:-}" ]; then
- # on-demand coverage reporting triggered by setting the COVERAGE environment variable to a non-empty value
- export COVERAGE="--coverage"
-elif [[ "${COMMIT_MESSAGE}" =~ ci_coverage ]]; then
- # on-demand coverage reporting triggered by having 'ci_coverage' in the latest commit message
- export COVERAGE="--coverage"
-else
- # on-demand coverage reporting disabled (default behavior, always-on coverage reporting remains enabled)
- export COVERAGE="--coverage-check"
-fi
-
-if [ -n "${COMPLETE:-}" ]; then
- # disable change detection triggered by setting the COMPLETE environment variable to a non-empty value
- export CHANGED=""
-elif [[ "${COMMIT_MESSAGE}" =~ ci_complete ]]; then
- # disable change detection triggered by having 'ci_complete' in the latest commit message
- export CHANGED=""
-else
- # enable change detection (default behavior)
- export CHANGED="--changed"
-fi
-
-if [ "${IS_PULL_REQUEST:-}" == "true" ]; then
- # run unstable tests which are targeted by focused changes on PRs
- export UNSTABLE="--allow-unstable-changed"
-else
- # do not run unstable tests outside PRs
- export UNSTABLE=""
-fi
-
-function cleanup
-{
- # for complete on-demand coverage generate a report for all files with no coverage on the "sanity/5" job so we only have one copy
- if [ "${COVERAGE}" == "--coverage" ] && [ "${CHANGED}" == "" ] && [ "${test}" == "sanity/5" ]; then
- stub="--stub"
- # trigger coverage reporting for stubs even if no other coverage data exists
- mkdir -p tests/output/coverage/
- else
- stub=""
- fi
-
- if [ -d tests/output/coverage/ ]; then
- if find tests/output/coverage/ -mindepth 1 -name '.*' -prune -o -print -quit | grep -q .; then
- process_coverage='yes' # process existing coverage files
- elif [ "${stub}" ]; then
- process_coverage='yes' # process coverage when stubs are enabled
- else
- process_coverage=''
- fi
-
- if [ "${process_coverage}" ]; then
- # use python 3.7 for coverage to avoid running out of memory during coverage xml processing
- # only use it for coverage to avoid the additional overhead of setting up a virtual environment for a potential no-op job
- virtualenv --python /usr/bin/python3.7 ~/ansible-venv
- set +ux
- . ~/ansible-venv/bin/activate
- set -ux
-
- # shellcheck disable=SC2086
- ansible-test coverage xml --color -v --requirements --group-by command --group-by version ${stub:+"$stub"}
- cp -a tests/output/reports/coverage=*.xml "$SHIPPABLE_RESULT_DIR/codecoverage/"
-
- if [ "${ansible_version}" != "2.9" ]; then
- # analyze and capture code coverage aggregated by integration test target
- ansible-test coverage analyze targets generate -v "$SHIPPABLE_RESULT_DIR/testresults/coverage-analyze-targets.json"
- fi
-
- # upload coverage report to codecov.io only when using complete on-demand coverage
- if [ "${COVERAGE}" == "--coverage" ] && [ "${CHANGED}" == "" ]; then
- for file in tests/output/reports/coverage=*.xml; do
- flags="${file##*/coverage=}"
- flags="${flags%-powershell.xml}"
- flags="${flags%.xml}"
- # remove numbered component from stub files when converting to tags
- flags="${flags//stub-[0-9]*/stub}"
- flags="${flags//=/,}"
- flags="${flags//[^a-zA-Z0-9_,]/_}"
-
- bash <(curl -s https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh) \
- -f "${file}" \
- -F "${flags}" \
- -n "${test}" \
- -t 47041dbd-4bef-43b8-8873-4c6a1a8a3711 \
- -X coveragepy \
- -X gcov \
- -X fix \
- -X search \
- -X xcode \
- || echo "Failed to upload code coverage report to codecov.io: ${file}"
- done
- fi
- fi
- fi
-
- if [ -d tests/output/junit/ ]; then
- cp -aT tests/output/junit/ "$SHIPPABLE_RESULT_DIR/testresults/"
- fi
-
- if [ -d tests/output/data/ ]; then
- cp -a tests/output/data/ "$SHIPPABLE_RESULT_DIR/testresults/"
- fi
-
- if [ -d tests/output/bot/ ]; then
- cp -aT tests/output/bot/ "$SHIPPABLE_RESULT_DIR/testresults/"
- fi
-}
-
-if [ "${SHIPPABLE_BUILD_ID:-}" ]; then trap cleanup EXIT; fi
-
-if [[ "${COVERAGE:-}" == "--coverage" ]]; then
- timeout=60
-else
- timeout=50
-fi
-
-ansible-test env --dump --show --timeout "${timeout}" --color -v
-
-if [ "${SHIPPABLE_BUILD_ID:-}" ]; then "tests/utils/shippable/check_matrix.py"; fi
-"tests/utils/shippable/${script}.sh" "${test}"
diff --git a/ansible_collections/community/azure/tests/utils/shippable/timing.py b/ansible_collections/community/azure/tests/utils/shippable/timing.py
deleted file mode 100755
index fb538271b..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/timing.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python3.7
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-import time
-
-start = time.time()
-
-sys.stdin.reconfigure(errors='surrogateescape')
-sys.stdout.reconfigure(errors='surrogateescape')
-
-for line in sys.stdin:
- seconds = time.time() - start
- sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
- sys.stdout.flush()
diff --git a/ansible_collections/community/azure/tests/utils/shippable/timing.sh b/ansible_collections/community/azure/tests/utils/shippable/timing.sh
deleted file mode 100755
index 77e257830..000000000
--- a/ansible_collections/community/azure/tests/utils/shippable/timing.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-set -o pipefail -eu
-
-"$@" 2>&1 | "$(dirname "$0")/timing.py"
diff --git a/ansible_collections/community/ciscosmb/.github/workflows/CI.yml b/ansible_collections/community/ciscosmb/.github/workflows/CI.yml
index 6d07a3edc..73c71b48e 100644
--- a/ansible_collections/community/ciscosmb/.github/workflows/CI.yml
+++ b/ansible_collections/community/ciscosmb/.github/workflows/CI.yml
@@ -33,40 +33,31 @@ jobs:
# https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html
sanity:
- name: Sanity (Ansible ${{ matrix.ansible }})
+ name: Sanity tests
+ runs-on: ${{ matrix.os }}
strategy:
+ fail-fast: false
matrix:
+ # Ansible Support Matrix
+ # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix
ansible:
- # It's important that Sanity is tested against all stable-X.Y branches
- # Testing against `devel` may fail as new tests are added.
- # An alternative to `devel` is the `milestone` branch with
- # gets synchronized with `devel` every few weeks and therefore
- # tends to be a more stable target. Be aware that it is not updated
- # around creation of a new stable branch, this might cause a problem
- # that two different versions of ansible-test use the same sanity test
- # ignore.txt file.
- # - stable-2.9 # Only if your collection supports Ansible 2.9
- - stable-2.10 # Only if your collection supports ansible-base 2.10
- - stable-2.11
- - stable-2.12
- - stable-2.13
- stable-2.14
+ - stable-2.15
+ - stable-2.16
- devel
- # - milestone
- runs-on: ubuntu-latest
+ python:
+ - 3.11
+ os:
+ - ubuntu-22.04
steps:
- # Run sanity tests inside a Docker container.
- # The docker container has all the pinned dependencies that are
- # required and all Python versions Ansible supports.
- - name: Perform sanity testing
+ - name: Sanity testing
uses: ansible-community/ansible-test-gh-action@release/v1
with:
ansible-core-version: ${{ matrix.ansible }}
+ target-python-version: ${{ matrix.python }}
testing-type: sanity
- # OPTIONAL If your sanity tests require code
- # from other collections, install them like this
test-deps: >-
- git+https://github.com/ansible-collections/ansible.netcommon.git
+ ansible.netcommon
###
# Unit tests (OPTIONAL)
@@ -74,44 +65,52 @@ jobs:
# https://docs.ansible.com/ansible/latest/dev_guide/testing_units.html
units:
- runs-on: ubuntu-latest
- name: Units (Ansible ${{ matrix.ansible }}+py${{ matrix.python }})
+ name: Unit tests (${{ matrix.ansible }}+py${{ matrix.python }})
+ runs-on: ${{ matrix.os }}
strategy:
- # As soon as the first unit test fails, cancel the others to free up the CI queue
fail-fast: false
matrix:
+ # Ansible Support matrix
+ # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix
ansible:
- # - stable-2.9 # Only if your collection supports Ansible 2.9
- - stable-2.10 # Only if your collection supports ansible-base 2.10
- - stable-2.11
- - stable-2.12
- - stable-2.13
- stable-2.14
+ - stable-2.15
+ - stable-2.16
- devel
- # - milestone
python:
+ # - "2.7" no support for old Python
+ - "3.5"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
+ - "3.11"
+ - "3.12"
+ os:
+ - ubuntu-22.04
exclude:
# no support
- - ansible: stable-2.10
- python: "3.10"
- - ansible: stable-2.11
- python: "3.10"
+ - ansible: stable-2.14
+ python: "3.12"
+ - ansible: stable-2.15
+ python: "3.12"
+ - ansible: stable-2.16
+ python: "3.5"
+ - ansible: devel
+ python: "3.5"
+ - ansible: devel
+ python: "3.6"
+ - ansible: devel
+ python: "3.7"
+
steps:
- - name: >-
- Perform unit testing against
- Ansible version ${{ matrix.ansible }}
+ - name: Unit testing
uses: ansible-community/ansible-test-gh-action@release/v1
with:
ansible-core-version: ${{ matrix.ansible }}
target-python-version: ${{ matrix.python }}
testing-type: units
- # OPTIONAL If your unit tests require code
- # from other collections, install them like this
test-deps: >-
ansible.netcommon
ansible.utils
diff --git a/ansible_collections/community/ciscosmb/.github/workflows/FastCI.yml b/ansible_collections/community/ciscosmb/.github/workflows/FastCI.yml
index ab8b17874..867757d51 100644
--- a/ansible_collections/community/ciscosmb/.github/workflows/FastCI.yml
+++ b/ansible_collections/community/ciscosmb/.github/workflows/FastCI.yml
@@ -28,72 +28,52 @@ jobs:
# https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html
sanity:
- name: Fast Sanity (Ansible ${{ matrix.ansible }})
+ name: Sanity tests
+ runs-on: ${{ matrix.os }}
strategy:
+ fail-fast: false
matrix:
+ # Ansible Support matrix
+ # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix
ansible:
- # It's important that Sanity is tested against all stable-X.Y branches
- # Testing against `devel` may fail as new tests are added.
- # An alternative to `devel` is the `milestone` branch with
- # gets synchronized with `devel` every few weeks and therefore
- # tends to be a more stable target. Be aware that it is not updated
- # around creation of a new stable branch, this might cause a problem
- # that two different versions of ansible-test use the same sanity test
- # ignore.txt file.
- # - stable-2.9 # Only if your collection supports Ansible 2.9
- # - stable-2.10 # Only if your collection supports ansible-base 2.10
- # - stable-2.11
- # - stable-2.12
- - stable-2.13
- # - stable-2.14
- # - devel
- # - milestone
- runs-on: ubuntu-latest
+ - stable-2.14
+ python:
+ - 3.11
+ os:
+ - ubuntu-22.04
+
steps:
- # Run sanity tests inside a Docker container.
- # The docker container has all the pinned dependencies that are
- # required and all Python versions Ansible supports.
- - name: Perform sanity testing
+ - name: Sanity testing
uses: ansible-community/ansible-test-gh-action@release/v1
with:
ansible-core-version: ${{ matrix.ansible }}
+ target-python-version: ${{ matrix.python }}
testing-type: sanity
- # OPTIONAL If your sanity tests require code
- # from other collections, install them like this
test-deps: >-
- git+https://github.com/ansible-collections/ansible.netcommon.git
-
-###
-# Unit tests (OPTIONAL)
-#
-# https://docs.ansible.com/ansible/latest/dev_guide/testing_units.html
+ ansible.netcommon
- units:
- runs-on: ubuntu-latest
- name: Fast Units (Ansible ${{ matrix.ansible }}+py${{ matrix.python }})
+ unit:
+ name: Unit tests
+ runs-on: ${{ matrix.os }}
strategy:
- # As soon as the first unit test fails, cancel the others to free up the CI queue
fail-fast: false
matrix:
+ # Ansible Support matrix
+ # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix
ansible:
- # - stable-2.9 # Only if your collection supports Ansible 2.9
- # - stable-2.10 # Only if your collection supports ansible-base 2.10
- # - stable-2.11
- # - stable-2.12
- - stable-2.13
- # - stable-2.14
- # - devel
- # - milestone
+ - stable-2.14
+ python:
+ - 3.11
+ os:
+ - ubuntu-22.04
+
steps:
- - name: >-
- Perform unit testing against
- Ansible version ${{ matrix.ansible }}
+ - name: Unit testing
uses: ansible-community/ansible-test-gh-action@release/v1
with:
ansible-core-version: ${{ matrix.ansible }}
+ target-python-version: ${{ matrix.python }}
testing-type: units
- # OPTIONAL If your unit tests require code
- # from other collections, install them like this
test-deps: >-
ansible.netcommon
ansible.utils
diff --git a/ansible_collections/community/ciscosmb/CHANGELOG.rst b/ansible_collections/community/ciscosmb/CHANGELOG.rst
index fb3bc6cc0..1f16349ea 100644
--- a/ansible_collections/community/ciscosmb/CHANGELOG.rst
+++ b/ansible_collections/community/ciscosmb/CHANGELOG.rst
@@ -4,6 +4,54 @@ CiscoSMB Ansible module Release Notes
.. contents:: Topics
+v1.0.9
+======
+
+Release Summary
+---------------
+
+Primarily revert release. Previous release (1.0.8) fixed typo in attribute name, but it was breaking change.
+This release brought the typo back (bandwith) and just added the new attribute with correct name "bandwidth" as a copy of the mistypped attribute.
+
+Attribude "bandwith" will be removed in next minor release.
+
+Minor Changes
+-------------
+
+- added additional attribute - add interface 'bandwidth' attribute
+- reverted attribute change - keep interface 'bandwith' attribute
+
+Bugfixes
+--------
+
+- typo in changelog fragment template
+- typo in test script
+
+v1.0.8
+======
+
+Release Summary
+---------------
+
+Release Date: 2024-04-09
+
+ Minor bugfixes, updated CI
+
+Minor Changes
+-------------
+
+- docs - addeed info about SG-250 support and testing
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- in facts of interface 'bandwith' changed to 'bandwidth'
+
+Bugfixes
+--------
+
+- issue
+- solved issue
v1.0.7
======
@@ -15,7 +63,6 @@ Release Date: 2023-10-30
Fix issue on CSB-350 #69
Clarify configuration doc #66 #64
-
Bugfixes
--------
@@ -30,7 +77,6 @@ Release Summary
Code cleaning, better documentation
-
Minor Changes
-------------
@@ -68,7 +114,6 @@ Release Summary
Release Date: 2021-09-13
-
Bugfixes
--------
@@ -83,7 +128,6 @@ Release Summary
Release Date: 2019-10-31
Minor changes in documentation, adding Python 3.6 as a supported version
-
Minor Changes
-------------
diff --git a/ansible_collections/community/ciscosmb/FILES.json b/ansible_collections/community/ciscosmb/FILES.json
index cc62fa878..6c096d426 100644
--- a/ansible_collections/community/ciscosmb/FILES.json
+++ b/ansible_collections/community/ciscosmb/FILES.json
@@ -25,14 +25,14 @@
"name": ".github/workflows/CI.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c9a8a6506530fe75912e7c5a4f088ea5faf7ffa2f423425b2805f4b0961a5f37",
+ "chksum_sha256": "123b77a907e54d2342804810653b910173ff576f19f27d113822aab39c53667f",
"format": 1
},
{
"name": ".github/workflows/FastCI.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "94a5e1a4be780b591cee49ad059ce07e8e89de89453daf0d3fd6bc3d9e5fd5d5",
+ "chksum_sha256": "3f8607ef0946ef96025c3f7cd6977db800e150594b77340617247defcdeb7bfb",
"format": 1
},
{
@@ -53,14 +53,14 @@
"name": "changelogs/fragments/.keep",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4a458bd648a360c285839f2e2ad6994993c035eb278b64bde2c08a3665a84e4c",
+ "chksum_sha256": "a02e74b2342d643d4eb450f87cc2f2c7f608be6061321555b1d71ecdf90e3938",
"format": 1
},
{
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a3610efbe7df3df55e25d674d38c6f9681680cc6807e3af36cac886440c6346c",
+ "chksum_sha256": "caa1a1be21ebfefcf82b3bb041e7b0489c684dfb189c6023c55ed69096e03803",
"format": 1
},
{
@@ -158,7 +158,7 @@
"name": "plugins/modules/facts.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "06cbfc8b6ee23c25089ac592d9d21ce0a086dd9c080852cf50f14833e90ce210",
+ "chksum_sha256": "710465293235ea44b25f55d81f083086549adabb87cc83b3e535f2275222d5bd",
"format": 1
},
{
@@ -172,7 +172,7 @@
"name": "plugins/terminal/ciscosmb.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "58fdbc076d66763501c686e9f2394f8c9db2b104469d50feae65bee55634eb68",
+ "chksum_sha256": "1f92f1abb0c83531a3de62936d337a401b8adac1c8356879f7a2c55de19d4fff",
"format": 1
},
{
@@ -214,7 +214,7 @@
"name": "tests/unit/compat/mock.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0af958450cf6de3fbafe94b1111eae8ba5a8dbe1d785ffbb9df81f26e4946d99",
+ "chksum_sha256": "7ebc6613b5c5f9e6d3726bec3406a5d670ca04ef69f7eb21c5ee83ef94ef5445",
"format": 1
},
{
@@ -627,7 +627,7 @@
"name": "tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b9ff43b3f0e29480f539528c72abfe7a2d2fa80e4affa834245e78d73a04947a",
+ "chksum_sha256": "de8e5dc48a066d75be282819a947f132edaf27462f5572ff1fceede749346be4",
"format": 1
},
{
@@ -704,7 +704,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "482e1b4cebbd09bb0d8f7b0876ddffd6477af428618f284e1180a583401a8cbb",
+ "chksum_sha256": "64accbe17f9d81d7bcb88b4c90f58d2536e9fc8defa7bd19d878b71bc865c4d2",
"format": 1
},
{
@@ -732,7 +732,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "40d7260f4d76c77e48a364647b75e113ce91d0e18ad67b13207e14cec08718e1",
+ "chksum_sha256": "8b7d0c6c412dd63b33cb45e4fe981241150fa1a6d48516e75f91783831022b19",
"format": 1
},
{
diff --git a/ansible_collections/community/ciscosmb/MANIFEST.json b/ansible_collections/community/ciscosmb/MANIFEST.json
index 2a98111d7..220aa5caf 100644
--- a/ansible_collections/community/ciscosmb/MANIFEST.json
+++ b/ansible_collections/community/ciscosmb/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "ciscosmb",
- "version": "1.0.7",
+ "version": "1.0.9",
"authors": [
"Petr Kl\u00edma <qaxi@seznam.cz>"
],
@@ -35,7 +35,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "922f00a582a76f8d668444f41338cfc356b64945bfe4149e7a12ac1e838c03b4",
+ "chksum_sha256": "0184b4a8b12bb7fd53db5eba127a744f66f90bdf37070164de7b6825a4b0f3d6",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/ciscosmb/README.md b/ansible_collections/community/ciscosmb/README.md
index 0ddae236a..4382b1d65 100644
--- a/ansible_collections/community/ciscosmb/README.md
+++ b/ansible_collections/community/ciscosmb/README.md
@@ -1,6 +1,8 @@
# Ansible Cisco Small Bussiness Switches (SMB) module
-Ansible Galaxy module for Cisco SMB switches - SG300, SG500, SG350, SG550, CBS350
+Thorough project check - [![CI](https://github.com/ansible-collections/community.ciscosmb/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ansible-collections/community.ciscosmb/actions/workflows/CI.yml)
+
+Ansible Galaxy module for Cisco SMB switches - SG250, SG300, SG500, SG350, SG550, CBS350
## Install
@@ -11,6 +13,7 @@ ansible-galaxy collection install community.ciscosmb
## Usage examples
Tested on devices:
+* SG250-10P
* SG350-10-K9
* SG350-28-K9
* SG500-52-K9
@@ -58,6 +61,8 @@ Tested on Python versions:
* 3.8
* 3.9
* 3.10
+* 3.11
+* 3.12
### Running examples
@@ -140,7 +145,7 @@ vim galaxy.yml
# edit changelog fragments (template in changelogs/fragments/.keep)
cp changelogs/fragments/.keep changelogs/fragments/release-x.y.z.yml
-vim changelogs/fragments/fragment.yml
+vim changelogs/fragments/release-x.y.z.yml
# change and generate CHANGELOG.rst
antsibull-changelog lint -v
diff --git a/ansible_collections/community/ciscosmb/changelogs/changelog.yaml b/ansible_collections/community/ciscosmb/changelogs/changelog.yaml
index 41e81a1b7..490b8c7e6 100644
--- a/ansible_collections/community/ciscosmb/changelogs/changelog.yaml
+++ b/ansible_collections/community/ciscosmb/changelogs/changelog.yaml
@@ -191,3 +191,41 @@ releases:
- issue69.yml
- release-1.0.7.yml
release_date: '2023-10-30'
+ 1.0.8:
+ changes:
+ breaking_changes:
+ - in facts of interface 'bandwith' changed to 'bandwidth'
+ bugfixes:
+ - issue
+ - solved issue
+ minor_changes:
+ - docs - addeed info about SG-250 support and testing
+ release_summary: "Release Date: 2024-04-09\n\n Minor bugfixes, updated CI\n"
+ fragments:
+ - CI.yml
+ - add-SG250.yml
+ - bandwidth.yml
+ - on_become.yml
+ - release-1.0.8.yml
+ release_date: '2024-04-09'
+ 1.0.9:
+ changes:
+ bugfixes:
+ - typo in changelog fragment template
+ - typo in test script
+ minor_changes:
+ - added additional attribute - add interface 'bandwidth' attribute
+ - reverted attribute change - keep interface 'bandwith' attribute
+ release_summary: 'Primarily revert release. Previous release (1.0.8) fixed typo
+ in attribute name, but it was breaking change.
+
+ This release brought the typo back (bandwith) and just added the new attribute
+ with correct name "bandwidth" as a copy of the mistypped attribute.
+
+
+ Attribude "bandwith" will be removed in next minor release.
+
+ '
+ fragments:
+ - 75-versioning_violation.yml
+ release_date: '2024-05-03'
diff --git a/ansible_collections/community/ciscosmb/changelogs/fragments/.keep b/ansible_collections/community/ciscosmb/changelogs/fragments/.keep
index 7b3ecc4f0..c61804f01 100644
--- a/ansible_collections/community/ciscosmb/changelogs/fragments/.keep
+++ b/ansible_collections/community/ciscosmb/changelogs/fragments/.keep
@@ -1,4 +1,4 @@
-# fragment.xml
+# fragment.yml
release_summary: |
Release Date: 2019-10-31
`Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`
diff --git a/ansible_collections/community/ciscosmb/plugins/modules/facts.py b/ansible_collections/community/ciscosmb/plugins/modules/facts.py
index 23cd9820a..a8744ef3c 100644
--- a/ansible_collections/community/ciscosmb/plugins/modules/facts.py
+++ b/ansible_collections/community/ciscosmb/plugins/modules/facts.py
@@ -423,9 +423,11 @@ class Interfaces(FactsBase):
interface["mode"] = i[8].lower()
if i[6] == "Up":
- interface["bandwith"] = int(i[3]) * 1000 # to get speed in kb
+ interface["bandwidth"] = int(i[3]) * 1000 # to get speed in kb
+ interface["bandwith"] = interface["bandwidth"]
else:
- interface["bandwith"] = None
+ interface["bandwidth"] = None
+ interface["bandwith"] = interface["bandwidth"]
for key in interface:
if interface[key] == "--":
@@ -449,9 +451,11 @@ class Interfaces(FactsBase):
interface["control"] = i[5].lower()
if i[6] == "Up":
- interface["bandwith"] = int(i[3]) * 1000 # to get speed in kb
+ interface["bandwidth"] = int(i[3]) * 1000 # to get speed in kb
+ interface["bandwith"] = interface["bandwidth"]
else:
- interface["bandwith"] = None
+ interface["bandwidth"] = None
+ interface["bandwith"] = interface["bandwidth"]
for key in interface:
if interface[key] == "--":
@@ -624,6 +628,7 @@ class Interfaces(FactsBase):
self.facts["interfaces"][interface]["admin_state"] = "up"
self.facts["interfaces"][interface]["description"] = None
self.facts["interfaces"][interface]["state"] = "up"
+ self.facts["interfaces"][interface]["bandwidth"] = None
self.facts["interfaces"][interface]["bandwith"] = None
self.facts["interfaces"][interface]["duplex"] = None
self.facts["interfaces"][interface]["negotiation"] = None
diff --git a/ansible_collections/community/ciscosmb/plugins/terminal/ciscosmb.py b/ansible_collections/community/ciscosmb/plugins/terminal/ciscosmb.py
index e8aa46d9b..6bb4d8a89 100644
--- a/ansible_collections/community/ciscosmb/plugins/terminal/ciscosmb.py
+++ b/ansible_collections/community/ciscosmb/plugins/terminal/ciscosmb.py
@@ -80,9 +80,6 @@ class TerminalModule(TerminalBase):
)
def on_become(self, passwd=None):
- if self._get_prompt().endswith(b"#"):
- return
-
cmd = {u"command": u"enable"}
if passwd:
# Note: python-3.5 cannot combine u"" and r"" together. Thus make
diff --git a/ansible_collections/community/ciscosmb/tests/unit/compat/mock.py b/ansible_collections/community/ciscosmb/tests/unit/compat/mock.py
index 0972cd2e8..5d25fbe16 100644
--- a/ansible_collections/community/ciscosmb/tests/unit/compat/mock.py
+++ b/ansible_collections/community/ciscosmb/tests/unit/compat/mock.py
@@ -64,8 +64,7 @@ if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
# newline that our naive format() added
data_as_list[-1] = data_as_list[-1][:-1]
- for line in data_as_list:
- yield line
+ yield data_as_list
def mock_open(mock=None, read_data=''):
"""
@@ -93,8 +92,7 @@ if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
if handle.readline.return_value is not None:
while True:
yield handle.readline.return_value
- for line in _data:
- yield line
+ yield _data
global file_spec
if file_spec is None:
diff --git a/ansible_collections/community/ciscosmb/tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py b/ansible_collections/community/ciscosmb/tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py
index 98a185dd7..107c365ca 100644
--- a/ansible_collections/community/ciscosmb/tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py
+++ b/ansible_collections/community/ciscosmb/tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py
@@ -116,6 +116,13 @@ class TestCiscoSMBFactsModule(TestCiscoSMBModule):
len(result['ansible_facts']['ansible_net_neighbors']), 9
)
+ interfaces = result['ansible_facts']['ansible_net_interfaces']
+ ge42 = interfaces['GigabitEthernet1/42']
+
+ self.assertEqual(ge42['bandwidth'], 1000000)
+
+ self.assertEqual(ge42['bandwidth'], ge42['bandwith'])
+
# def test_ciscosmb_facts_routing(self):
# set_module_args(dict(gather_subset='routing'))
# result = self.execute_module()
diff --git a/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml
index 19a36fb46..3505f5d99 100644
--- a/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml
+++ b/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml
@@ -176,7 +176,7 @@ stages:
- name: Debian Bookworm
test: debian-bookworm/3.11
- name: ArchLinux
- test: archlinux/3.11
+ test: archlinux/3.12
groups:
- 1
- 2
diff --git a/ansible_collections/community/crypto/.github/workflows/ansible-test.yml b/ansible_collections/community/crypto/.github/workflows/ansible-test.yml
index d31e861c4..dac31b04c 100644
--- a/ansible_collections/community/crypto/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/crypto/.github/workflows/ansible-test.yml
@@ -50,6 +50,7 @@ jobs:
with:
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pull-request-change-detection: 'true'
testing-type: sanity
@@ -85,6 +86,7 @@ jobs:
with:
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pull-request-change-detection: 'true'
testing-type: units
@@ -282,6 +284,7 @@ jobs:
with:
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
docker-image: ${{ matrix.docker }}
integration-continue-on-error: 'false'
diff --git a/ansible_collections/community/crypto/CHANGELOG.md b/ansible_collections/community/crypto/CHANGELOG.md
index 1652a3ad2..abb97442d 100644
--- a/ansible_collections/community/crypto/CHANGELOG.md
+++ b/ansible_collections/community/crypto/CHANGELOG.md
@@ -2,269 +2,328 @@
**Topics**
-- <a href="#v2-19-0">v2\.19\.0</a>
+- <a href="#v2-20-0">v2\.20\.0</a>
- <a href="#release-summary">Release Summary</a>
- <a href="#minor-changes">Minor Changes</a>
- <a href="#deprecated-features">Deprecated Features</a>
- <a href="#bugfixes">Bugfixes</a>
- <a href="#new-modules">New Modules</a>
-- <a href="#v2-18-0">v2\.18\.0</a>
+- <a href="#v2-19-1">v2\.19\.1</a>
- <a href="#release-summary-1">Release Summary</a>
- - <a href="#minor-changes-1">Minor Changes</a>
- - <a href="#deprecated-features-1">Deprecated Features</a>
- <a href="#bugfixes-1">Bugfixes</a>
- - <a href="#new-plugins">New Plugins</a>
- - <a href="#filter">Filter</a>
-- <a href="#v2-17-1">v2\.17\.1</a>
+- <a href="#v2-19-0">v2\.19\.0</a>
- <a href="#release-summary-2">Release Summary</a>
+ - <a href="#minor-changes-1">Minor Changes</a>
+ - <a href="#deprecated-features-1">Deprecated Features</a>
- <a href="#bugfixes-2">Bugfixes</a>
-- <a href="#v2-17-0">v2\.17\.0</a>
+ - <a href="#new-modules-1">New Modules</a>
+- <a href="#v2-18-0">v2\.18\.0</a>
- <a href="#release-summary-3">Release Summary</a>
- <a href="#minor-changes-2">Minor Changes</a>
-- <a href="#v2-16-2">v2\.16\.2</a>
- - <a href="#release-summary-4">Release Summary</a>
+ - <a href="#deprecated-features-2">Deprecated Features</a>
- <a href="#bugfixes-3">Bugfixes</a>
-- <a href="#v2-16-1">v2\.16\.1</a>
- - <a href="#release-summary-5">Release Summary</a>
+ - <a href="#new-plugins">New Plugins</a>
+ - <a href="#filter">Filter</a>
+- <a href="#v2-17-1">v2\.17\.1</a>
+ - <a href="#release-summary-4">Release Summary</a>
- <a href="#bugfixes-4">Bugfixes</a>
-- <a href="#v2-16-0">v2\.16\.0</a>
- - <a href="#release-summary-6">Release Summary</a>
+- <a href="#v2-17-0">v2\.17\.0</a>
+ - <a href="#release-summary-5">Release Summary</a>
- <a href="#minor-changes-3">Minor Changes</a>
+- <a href="#v2-16-2">v2\.16\.2</a>
+ - <a href="#release-summary-6">Release Summary</a>
- <a href="#bugfixes-5">Bugfixes</a>
-- <a href="#v2-15-1">v2\.15\.1</a>
+- <a href="#v2-16-1">v2\.16\.1</a>
- <a href="#release-summary-7">Release Summary</a>
- <a href="#bugfixes-6">Bugfixes</a>
-- <a href="#v2-15-0">v2\.15\.0</a>
+- <a href="#v2-16-0">v2\.16\.0</a>
- <a href="#release-summary-8">Release Summary</a>
- <a href="#minor-changes-4">Minor Changes</a>
- - <a href="#deprecated-features-2">Deprecated Features</a>
- <a href="#bugfixes-7">Bugfixes</a>
+- <a href="#v2-15-1">v2\.15\.1</a>
+ - <a href="#release-summary-9">Release Summary</a>
+ - <a href="#bugfixes-8">Bugfixes</a>
+- <a href="#v2-15-0">v2\.15\.0</a>
+ - <a href="#release-summary-10">Release Summary</a>
+ - <a href="#minor-changes-5">Minor Changes</a>
+ - <a href="#deprecated-features-3">Deprecated Features</a>
+ - <a href="#bugfixes-9">Bugfixes</a>
- <a href="#new-plugins-1">New Plugins</a>
- <a href="#filter-1">Filter</a>
- <a href="#lookup">Lookup</a>
- <a href="#v2-14-1">v2\.14\.1</a>
- - <a href="#release-summary-9">Release Summary</a>
- - <a href="#bugfixes-8">Bugfixes</a>
+ - <a href="#release-summary-11">Release Summary</a>
+ - <a href="#bugfixes-10">Bugfixes</a>
- <a href="#known-issues">Known Issues</a>
- <a href="#v2-14-0">v2\.14\.0</a>
- - <a href="#release-summary-10">Release Summary</a>
- - <a href="#minor-changes-5">Minor Changes</a>
-- <a href="#v2-13-1">v2\.13\.1</a>
- - <a href="#release-summary-11">Release Summary</a>
- - <a href="#bugfixes-9">Bugfixes</a>
-- <a href="#v2-13-0">v2\.13\.0</a>
- <a href="#release-summary-12">Release Summary</a>
- <a href="#minor-changes-6">Minor Changes</a>
- - <a href="#deprecated-features-3">Deprecated Features</a>
- - <a href="#bugfixes-10">Bugfixes</a>
-- <a href="#v2-12-0">v2\.12\.0</a>
+- <a href="#v2-13-1">v2\.13\.1</a>
- <a href="#release-summary-13">Release Summary</a>
- - <a href="#minor-changes-7">Minor Changes</a>
-- <a href="#v2-11-1">v2\.11\.1</a>
+ - <a href="#bugfixes-11">Bugfixes</a>
+- <a href="#v2-13-0">v2\.13\.0</a>
- <a href="#release-summary-14">Release Summary</a>
-- <a href="#v2-11-0">v2\.11\.0</a>
+ - <a href="#minor-changes-7">Minor Changes</a>
+ - <a href="#deprecated-features-4">Deprecated Features</a>
+ - <a href="#bugfixes-12">Bugfixes</a>
+- <a href="#v2-12-0">v2\.12\.0</a>
- <a href="#release-summary-15">Release Summary</a>
- <a href="#minor-changes-8">Minor Changes</a>
- - <a href="#bugfixes-11">Bugfixes</a>
-- <a href="#v2-10-0">v2\.10\.0</a>
+- <a href="#v2-11-1">v2\.11\.1</a>
- <a href="#release-summary-16">Release Summary</a>
- - <a href="#bugfixes-12">Bugfixes</a>
- - <a href="#new-plugins-2">New Plugins</a>
- - <a href="#filter-2">Filter</a>
-- <a href="#v2-9-0">v2\.9\.0</a>
+- <a href="#v2-11-0">v2\.11\.0</a>
- <a href="#release-summary-17">Release Summary</a>
- <a href="#minor-changes-9">Minor Changes</a>
-- <a href="#v2-8-1">v2\.8\.1</a>
+ - <a href="#bugfixes-13">Bugfixes</a>
+- <a href="#v2-10-0">v2\.10\.0</a>
- <a href="#release-summary-18">Release Summary</a>
-- <a href="#v2-8-0">v2\.8\.0</a>
+ - <a href="#bugfixes-14">Bugfixes</a>
+ - <a href="#new-plugins-2">New Plugins</a>
+ - <a href="#filter-2">Filter</a>
+- <a href="#v2-9-0">v2\.9\.0</a>
- <a href="#release-summary-19">Release Summary</a>
- <a href="#minor-changes-10">Minor Changes</a>
-- <a href="#v2-7-1">v2\.7\.1</a>
+- <a href="#v2-8-1">v2\.8\.1</a>
- <a href="#release-summary-20">Release Summary</a>
- - <a href="#bugfixes-13">Bugfixes</a>
-- <a href="#v2-7-0">v2\.7\.0</a>
+- <a href="#v2-8-0">v2\.8\.0</a>
- <a href="#release-summary-21">Release Summary</a>
- <a href="#minor-changes-11">Minor Changes</a>
- - <a href="#bugfixes-14">Bugfixes</a>
-- <a href="#v2-6-0">v2\.6\.0</a>
+- <a href="#v2-7-1">v2\.7\.1</a>
- <a href="#release-summary-22">Release Summary</a>
- - <a href="#minor-changes-12">Minor Changes</a>
-- <a href="#v2-5-0">v2\.5\.0</a>
+ - <a href="#bugfixes-15">Bugfixes</a>
+- <a href="#v2-7-0">v2\.7\.0</a>
- <a href="#release-summary-23">Release Summary</a>
- - <a href="#minor-changes-13">Minor Changes</a>
-- <a href="#v2-4-0">v2\.4\.0</a>
+ - <a href="#minor-changes-12">Minor Changes</a>
+ - <a href="#bugfixes-16">Bugfixes</a>
+- <a href="#v2-6-0">v2\.6\.0</a>
- <a href="#release-summary-24">Release Summary</a>
- - <a href="#deprecated-features-4">Deprecated Features</a>
- - <a href="#bugfixes-15">Bugfixes</a>
-- <a href="#v2-3-4">v2\.3\.4</a>
+ - <a href="#minor-changes-13">Minor Changes</a>
+- <a href="#v2-5-0">v2\.5\.0</a>
- <a href="#release-summary-25">Release Summary</a>
-- <a href="#v2-3-3">v2\.3\.3</a>
+ - <a href="#minor-changes-14">Minor Changes</a>
+- <a href="#v2-4-0">v2\.4\.0</a>
- <a href="#release-summary-26">Release Summary</a>
- - <a href="#bugfixes-16">Bugfixes</a>
-- <a href="#v2-3-2">v2\.3\.2</a>
- - <a href="#release-summary-27">Release Summary</a>
+ - <a href="#deprecated-features-5">Deprecated Features</a>
- <a href="#bugfixes-17">Bugfixes</a>
-- <a href="#v2-3-1">v2\.3\.1</a>
+- <a href="#v2-3-4">v2\.3\.4</a>
+ - <a href="#release-summary-27">Release Summary</a>
+- <a href="#v2-3-3">v2\.3\.3</a>
- <a href="#release-summary-28">Release Summary</a>
- <a href="#bugfixes-18">Bugfixes</a>
-- <a href="#v2-3-0">v2\.3\.0</a>
+- <a href="#v2-3-2">v2\.3\.2</a>
- <a href="#release-summary-29">Release Summary</a>
- - <a href="#minor-changes-14">Minor Changes</a>
- <a href="#bugfixes-19">Bugfixes</a>
-- <a href="#v2-2-4">v2\.2\.4</a>
+- <a href="#v2-3-1">v2\.3\.1</a>
- <a href="#release-summary-30">Release Summary</a>
- <a href="#bugfixes-20">Bugfixes</a>
-- <a href="#v2-2-3">v2\.2\.3</a>
+- <a href="#v2-3-0">v2\.3\.0</a>
- <a href="#release-summary-31">Release Summary</a>
+ - <a href="#minor-changes-15">Minor Changes</a>
- <a href="#bugfixes-21">Bugfixes</a>
-- <a href="#v2-2-2">v2\.2\.2</a>
+- <a href="#v2-2-4">v2\.2\.4</a>
- <a href="#release-summary-32">Release Summary</a>
- <a href="#bugfixes-22">Bugfixes</a>
-- <a href="#v2-2-1">v2\.2\.1</a>
+- <a href="#v2-2-3">v2\.2\.3</a>
- <a href="#release-summary-33">Release Summary</a>
- <a href="#bugfixes-23">Bugfixes</a>
-- <a href="#v2-2-0">v2\.2\.0</a>
+- <a href="#v2-2-2">v2\.2\.2</a>
- <a href="#release-summary-34">Release Summary</a>
- - <a href="#minor-changes-15">Minor Changes</a>
- <a href="#bugfixes-24">Bugfixes</a>
-- <a href="#v2-1-0">v2\.1\.0</a>
+- <a href="#v2-2-1">v2\.2\.1</a>
- <a href="#release-summary-35">Release Summary</a>
- - <a href="#minor-changes-16">Minor Changes</a>
- <a href="#bugfixes-25">Bugfixes</a>
- - <a href="#new-modules-1">New Modules</a>
-- <a href="#v2-0-2">v2\.0\.2</a>
+- <a href="#v2-2-0">v2\.2\.0</a>
- <a href="#release-summary-36">Release Summary</a>
-- <a href="#v2-0-1">v2\.0\.1</a>
+ - <a href="#minor-changes-16">Minor Changes</a>
+ - <a href="#bugfixes-26">Bugfixes</a>
+- <a href="#v2-1-0">v2\.1\.0</a>
- <a href="#release-summary-37">Release Summary</a>
- <a href="#minor-changes-17">Minor Changes</a>
- - <a href="#bugfixes-26">Bugfixes</a>
-- <a href="#v2-0-0">v2\.0\.0</a>
- - <a href="#release-summary-38">Release Summary</a>
- - <a href="#minor-changes-18">Minor Changes</a>
- - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
- - <a href="#deprecated-features-5">Deprecated Features</a>
- - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- <a href="#bugfixes-27">Bugfixes</a>
-- <a href="#v1-9-4">v1\.9\.4</a>
+ - <a href="#new-modules-2">New Modules</a>
+- <a href="#v2-0-2">v2\.0\.2</a>
+ - <a href="#release-summary-38">Release Summary</a>
+- <a href="#v2-0-1">v2\.0\.1</a>
- <a href="#release-summary-39">Release Summary</a>
+ - <a href="#minor-changes-18">Minor Changes</a>
- <a href="#bugfixes-28">Bugfixes</a>
-- <a href="#v1-9-3">v1\.9\.3</a>
+- <a href="#v2-0-0">v2\.0\.0</a>
- <a href="#release-summary-40">Release Summary</a>
+ - <a href="#minor-changes-19">Minor Changes</a>
+ - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
+ - <a href="#deprecated-features-6">Deprecated Features</a>
+ - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- <a href="#bugfixes-29">Bugfixes</a>
-- <a href="#v1-9-2">v1\.9\.2</a>
+- <a href="#v1-9-4">v1\.9\.4</a>
- <a href="#release-summary-41">Release Summary</a>
-- <a href="#v1-9-1">v1\.9\.1</a>
+ - <a href="#bugfixes-30">Bugfixes</a>
+- <a href="#v1-9-3">v1\.9\.3</a>
- <a href="#release-summary-42">Release Summary</a>
-- <a href="#v1-9-0">v1\.9\.0</a>
+ - <a href="#bugfixes-31">Bugfixes</a>
+- <a href="#v1-9-2">v1\.9\.2</a>
- <a href="#release-summary-43">Release Summary</a>
- - <a href="#minor-changes-19">Minor Changes</a>
- - <a href="#bugfixes-30">Bugfixes</a>
-- <a href="#v1-8-0">v1\.8\.0</a>
+- <a href="#v1-9-1">v1\.9\.1</a>
- <a href="#release-summary-44">Release Summary</a>
- - <a href="#minor-changes-20">Minor Changes</a>
- - <a href="#bugfixes-31">Bugfixes</a>
-- <a href="#v1-7-1">v1\.7\.1</a>
+- <a href="#v1-9-0">v1\.9\.0</a>
- <a href="#release-summary-45">Release Summary</a>
+ - <a href="#minor-changes-20">Minor Changes</a>
- <a href="#bugfixes-32">Bugfixes</a>
-- <a href="#v1-7-0">v1\.7\.0</a>
+- <a href="#v1-8-0">v1\.8\.0</a>
- <a href="#release-summary-46">Release Summary</a>
- <a href="#minor-changes-21">Minor Changes</a>
- <a href="#bugfixes-33">Bugfixes</a>
- - <a href="#new-modules-2">New Modules</a>
-- <a href="#v1-6-2">v1\.6\.2</a>
+- <a href="#v1-7-1">v1\.7\.1</a>
- <a href="#release-summary-47">Release Summary</a>
- <a href="#bugfixes-34">Bugfixes</a>
-- <a href="#v1-6-1">v1\.6\.1</a>
+- <a href="#v1-7-0">v1\.7\.0</a>
- <a href="#release-summary-48">Release Summary</a>
+ - <a href="#minor-changes-22">Minor Changes</a>
- <a href="#bugfixes-35">Bugfixes</a>
-- <a href="#v1-6-0">v1\.6\.0</a>
+ - <a href="#new-modules-3">New Modules</a>
+- <a href="#v1-6-2">v1\.6\.2</a>
- <a href="#release-summary-49">Release Summary</a>
- - <a href="#minor-changes-22">Minor Changes</a>
- - <a href="#deprecated-features-6">Deprecated Features</a>
- <a href="#bugfixes-36">Bugfixes</a>
-- <a href="#v1-5-0">v1\.5\.0</a>
+- <a href="#v1-6-1">v1\.6\.1</a>
- <a href="#release-summary-50">Release Summary</a>
- - <a href="#minor-changes-23">Minor Changes</a>
- - <a href="#deprecated-features-7">Deprecated Features</a>
- <a href="#bugfixes-37">Bugfixes</a>
-- <a href="#v1-4-0">v1\.4\.0</a>
+- <a href="#v1-6-0">v1\.6\.0</a>
- <a href="#release-summary-51">Release Summary</a>
- - <a href="#minor-changes-24">Minor Changes</a>
+ - <a href="#minor-changes-23">Minor Changes</a>
+ - <a href="#deprecated-features-7">Deprecated Features</a>
- <a href="#bugfixes-38">Bugfixes</a>
-- <a href="#v1-3-0">v1\.3\.0</a>
+- <a href="#v1-5-0">v1\.5\.0</a>
- <a href="#release-summary-52">Release Summary</a>
- - <a href="#minor-changes-25">Minor Changes</a>
+ - <a href="#minor-changes-24">Minor Changes</a>
+ - <a href="#deprecated-features-8">Deprecated Features</a>
- <a href="#bugfixes-39">Bugfixes</a>
- - <a href="#new-modules-3">New Modules</a>
-- <a href="#v1-2-0">v1\.2\.0</a>
+- <a href="#v1-4-0">v1\.4\.0</a>
- <a href="#release-summary-53">Release Summary</a>
- - <a href="#minor-changes-26">Minor Changes</a>
- - <a href="#security-fixes">Security Fixes</a>
+ - <a href="#minor-changes-25">Minor Changes</a>
- <a href="#bugfixes-40">Bugfixes</a>
-- <a href="#v1-1-1">v1\.1\.1</a>
+- <a href="#v1-3-0">v1\.3\.0</a>
- <a href="#release-summary-54">Release Summary</a>
+ - <a href="#minor-changes-26">Minor Changes</a>
- <a href="#bugfixes-41">Bugfixes</a>
-- <a href="#v1-1-0">v1\.1\.0</a>
+ - <a href="#new-modules-4">New Modules</a>
+- <a href="#v1-2-0">v1\.2\.0</a>
- <a href="#release-summary-55">Release Summary</a>
- <a href="#minor-changes-27">Minor Changes</a>
+ - <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-42">Bugfixes</a>
- - <a href="#new-modules-4">New Modules</a>
-- <a href="#v1-0-0">v1\.0\.0</a>
+- <a href="#v1-1-1">v1\.1\.1</a>
- <a href="#release-summary-56">Release Summary</a>
- - <a href="#minor-changes-28">Minor Changes</a>
- - <a href="#deprecated-features-8">Deprecated Features</a>
- - <a href="#removed-features-previously-deprecated-1">Removed Features \(previously deprecated\)</a>
- <a href="#bugfixes-43">Bugfixes</a>
+- <a href="#v1-1-0">v1\.1\.0</a>
+ - <a href="#release-summary-57">Release Summary</a>
+ - <a href="#minor-changes-28">Minor Changes</a>
+ - <a href="#bugfixes-44">Bugfixes</a>
- <a href="#new-modules-5">New Modules</a>
+- <a href="#v1-0-0">v1\.0\.0</a>
+ - <a href="#release-summary-58">Release Summary</a>
+ - <a href="#minor-changes-29">Minor Changes</a>
+ - <a href="#deprecated-features-9">Deprecated Features</a>
+ - <a href="#removed-features-previously-deprecated-1">Removed Features \(previously deprecated\)</a>
+ - <a href="#bugfixes-45">Bugfixes</a>
+ - <a href="#new-modules-6">New Modules</a>
+
+<a id="v2-20-0"></a>
+## v2\.20\.0
+
+<a id="release-summary"></a>
+### Release Summary
+
+Feature and bugfix release\.
+
+The deprecations in this release are only relevant for collections that use shared
+code or docs fragments from this collection\.
+
+<a id="minor-changes"></a>
+### Minor Changes
+
+* acme\_certificate \- add <code>include\_renewal\_cert\_id</code> option to allow requesting renewal of a specific certificate according to the current ACME Renewal Information specification draft \([https\://github\.com/ansible\-collections/community\.crypto/pull/739](https\://github\.com/ansible\-collections/community\.crypto/pull/739)\)\.
+
+<a id="deprecated-features"></a>
+### Deprecated Features
+
+* acme documentation fragment \- the default <code>community\.crypto\.acme\[\.documentation\]</code> docs fragment is deprecated and will be removed from community\.crypto 3\.0\.0\. Replace it with both the new <code>community\.crypto\.acme\.basic</code> and <code>community\.crypto\.acme\.account</code> fragments \([https\://github\.com/ansible\-collections/community\.crypto/pull/735](https\://github\.com/ansible\-collections/community\.crypto/pull/735)\)\.
+* acme\.backends module utils \- the <code>get\_cert\_information\(\)</code> method for a ACME crypto backend must be implemented from community\.crypto 3\.0\.0 on \([https\://github\.com/ansible\-collections/community\.crypto/pull/736](https\://github\.com/ansible\-collections/community\.crypto/pull/736)\)\.
+* crypto\.module\_backends\.common module utils \- the <code>crypto\.module\_backends\.common</code> module utils is deprecated and will be removed from community\.crypto 3\.0\.0\. Use the improved <code>argspec</code> module util instead \([https\://github\.com/ansible\-collections/community\.crypto/pull/749](https\://github\.com/ansible\-collections/community\.crypto/pull/749)\)\.
+
+<a id="bugfixes"></a>
+### Bugfixes
+
+* x509\_crl\, x509\_certificate\, x509\_certificate\_info \- when parsing absolute timestamps which omitted the second count\, the first digit of the minutes was used as a one\-digit minutes count\, and the second digit of the minutes as a one\-digit second count \([https\://github\.com/ansible\-collections/community\.crypto/pull/745](https\://github\.com/ansible\-collections/community\.crypto/pull/745)\)\.
+
+<a id="new-modules"></a>
+### New Modules
+
+* community\.crypto\.acme\_ari\_info \- Retrieves ACME Renewal Information \(ARI\) for a certificate\.
+* community\.crypto\.acme\_certificate\_deactivate\_authz \- Deactivate all authz for an ACME v2 order\.
+* community\.crypto\.acme\_certificate\_renewal\_info \- Determine whether a certificate should be renewed or not\.
+
+<a id="v2-19-1"></a>
+## v2\.19\.1
+
+<a id="release-summary-1"></a>
+### Release Summary
+
+Bugfix release\.
+
+<a id="bugfixes-1"></a>
+### Bugfixes
+
+* crypto\.math module utils \- change return values for <code>quick\_is\_not\_prime\(\)</code> and <code>convert\_int\_to\_bytes\(0\, 0\)</code> for special cases that do not appear when using the collection \([https\://github\.com/ansible\-collections/community\.crypto/pull/733](https\://github\.com/ansible\-collections/community\.crypto/pull/733)\)\.
+* ecs\_certificate \- fixed <code>csr</code> option to be empty and allow renewal of a specific certificate according to the Renewal Information specification \([https\://github\.com/ansible\-collections/community\.crypto/pull/740](https\://github\.com/ansible\-collections/community\.crypto/pull/740)\)\.
+* x509\_certificate \- since community\.crypto 2\.19\.0 the module was no longer idempotent with respect to <code>not\_before</code> and <code>not\_after</code> times\. This is now fixed \([https\://github\.com/ansible\-collections/community\.crypto/issues/753](https\://github\.com/ansible\-collections/community\.crypto/issues/753)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/754](https\://github\.com/ansible\-collections/community\.crypto/pull/754)\)\.
<a id="v2-19-0"></a>
## v2\.19\.0
-<a id="release-summary"></a>
+<a id="release-summary-2"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes"></a>
+<a id="minor-changes-1"></a>
### Minor Changes
* When using cryptography \>\= 42\.0\.0\, use offset\-aware <code>datetime\.datetime</code> objects \(with timezone UTC\) instead of offset\-naive UTC timestamps \([https\://github\.com/ansible\-collections/community\.crypto/issues/726](https\://github\.com/ansible\-collections/community\.crypto/issues/726)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/727](https\://github\.com/ansible\-collections/community\.crypto/pull/727)\)\.
* openssh\_cert \- avoid UTC functions deprecated in Python 3\.12 when using Python 3 \([https\://github\.com/ansible\-collections/community\.crypto/pull/727](https\://github\.com/ansible\-collections/community\.crypto/pull/727)\)\.
-<a id="deprecated-features"></a>
+<a id="deprecated-features-1"></a>
### Deprecated Features
* acme\.backends module utils \- from community\.crypto on\, all implementations of <code>CryptoBackend</code> must override <code>get\_ordered\_csr\_identifiers\(\)</code>\. The current default implementation\, which simply sorts the result of <code>get\_csr\_identifiers\(\)</code>\, will then be removed \([https\://github\.com/ansible\-collections/community\.crypto/pull/725](https\://github\.com/ansible\-collections/community\.crypto/pull/725)\)\.
-<a id="bugfixes"></a>
+<a id="bugfixes-2"></a>
### Bugfixes
* acme\_certificate \- respect the order of the CNAME and SAN identifiers that are passed on when creating an ACME order \([https\://github\.com/ansible\-collections/community\.crypto/issues/723](https\://github\.com/ansible\-collections/community\.crypto/issues/723)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/725](https\://github\.com/ansible\-collections/community\.crypto/pull/725)\)\.
-<a id="new-modules"></a>
+<a id="new-modules-1"></a>
### New Modules
-* x509\_certificate\_convert \- Convert X\.509 certificates
+* community\.crypto\.x509\_certificate\_convert \- Convert X\.509 certificates
<a id="v2-18-0"></a>
## v2\.18\.0
-<a id="release-summary-1"></a>
+<a id="release-summary-3"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes-1"></a>
+<a id="minor-changes-2"></a>
### Minor Changes
* x509\_crl \- the new option <code>serial\_numbers</code> allow to configure in which format serial numbers can be provided to <code>revoked\_certificates\[\]\.serial\_number</code>\. The default is as integers \(<code>serial\_numbers\=integer</code>\) for backwards compatibility\; setting <code>serial\_numbers\=hex\-octets</code> allows to specify colon\-separated hex octet strings like <code>00\:11\:22\:FF</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/687](https\://github\.com/ansible\-collections/community\.crypto/issues/687)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/715](https\://github\.com/ansible\-collections/community\.crypto/pull/715)\)\.
-<a id="deprecated-features-1"></a>
+<a id="deprecated-features-2"></a>
### Deprecated Features
* openssl\_csr\_pipe\, openssl\_privatekey\_pipe\, x509\_certificate\_pipe \- the current behavior of check mode is deprecated and will change in community\.crypto 3\.0\.0\. The current behavior is similar to the modules without <code>\_pipe</code>\: if the object needs to be \(re\-\)generated\, only the <code>changed</code> status is set\, but the object is not updated\. From community\.crypto 3\.0\.0 on\, the modules will ignore check mode and always act as if check mode is not active\. This behavior can already achieved now by adding <code>check\_mode\: false</code> to the task\. If you think this breaks your use\-case of this module\, please [create an issue in the community\.crypto repository](https\://github\.com/ansible\-collections/community\.crypto/issues/new/choose) \([https\://github\.com/ansible\-collections/community\.crypto/issues/712](https\://github\.com/ansible\-collections/community\.crypto/issues/712)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/714](https\://github\.com/ansible\-collections/community\.crypto/pull/714)\)\.
-<a id="bugfixes-1"></a>
+<a id="bugfixes-3"></a>
### Bugfixes
* luks\_device \- fixed module a bug that prevented using <code>remove\_keyslot</code> with the value <code>0</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/710](https\://github\.com/ansible\-collections/community\.crypto/pull/710)\)\.
@@ -277,18 +336,18 @@ Bugfix and feature release\.
<a id="filter"></a>
#### Filter
-* parse\_serial \- Convert a serial number as a colon\-separated list of hex numbers to an integer
-* to\_serial \- Convert an integer to a colon\-separated list of hex numbers
+* community\.crypto\.parse\_serial \- Convert a serial number as a colon\-separated list of hex numbers to an integer
+* community\.crypto\.to\_serial \- Convert an integer to a colon\-separated list of hex numbers
<a id="v2-17-1"></a>
## v2\.17\.1
-<a id="release-summary-2"></a>
+<a id="release-summary-4"></a>
### Release Summary
Bugfix release for compatibility with cryptography 42\.0\.0\.
-<a id="bugfixes-2"></a>
+<a id="bugfixes-4"></a>
### Bugfixes
* openssl\_dhparam \- was using an internal function instead of the public API to load DH param files when using the <code>cryptography</code> backend\. The internal function was removed in cryptography 42\.0\.0\. The module now uses the public API\, which has been available since support for DH params was added to cryptography \([https\://github\.com/ansible\-collections/community\.crypto/pull/698](https\://github\.com/ansible\-collections/community\.crypto/pull/698)\)\.
@@ -298,12 +357,12 @@ Bugfix release for compatibility with cryptography 42\.0\.0\.
<a id="v2-17-0"></a>
## v2\.17\.0
-<a id="release-summary-3"></a>
+<a id="release-summary-5"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-2"></a>
+<a id="minor-changes-3"></a>
### Minor Changes
* luks\_device \- add allow discards option \([https\://github\.com/ansible\-collections/community\.crypto/pull/693](https\://github\.com/ansible\-collections/community\.crypto/pull/693)\)\.
@@ -311,12 +370,12 @@ Feature release\.
<a id="v2-16-2"></a>
## v2\.16\.2
-<a id="release-summary-4"></a>
+<a id="release-summary-6"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-3"></a>
+<a id="bugfixes-5"></a>
### Bugfixes
* acme\_\* modules \- directly react on bad return data for account creation/retrieval/updating requests \([https\://github\.com/ansible\-collections/community\.crypto/pull/682](https\://github\.com/ansible\-collections/community\.crypto/pull/682)\)\.
@@ -327,12 +386,12 @@ Bugfix release\.
<a id="v2-16-1"></a>
## v2\.16\.1
-<a id="release-summary-5"></a>
+<a id="release-summary-7"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-4"></a>
+<a id="bugfixes-6"></a>
### Bugfixes
* acme\_\* modules \- also retry requests in case of socket errors\, bad status lines\, and unknown connection errors\; improve error messages in these cases \([https\://github\.com/ansible\-collections/community\.crypto/issues/680](https\://github\.com/ansible\-collections/community\.crypto/issues/680)\)\.
@@ -340,17 +399,17 @@ Bugfix release\.
<a id="v2-16-0"></a>
## v2\.16\.0
-<a id="release-summary-6"></a>
+<a id="release-summary-8"></a>
### Release Summary
Bugfix release\.
-<a id="minor-changes-3"></a>
+<a id="minor-changes-4"></a>
### Minor Changes
* luks\_devices \- add new options <code>keyslot</code>\, <code>new\_keyslot</code>\, and <code>remove\_keyslot</code> to allow adding/removing keys to/from specific keyslots \([https\://github\.com/ansible\-collections/community\.crypto/pull/664](https\://github\.com/ansible\-collections/community\.crypto/pull/664)\)\.
-<a id="bugfixes-5"></a>
+<a id="bugfixes-7"></a>
### Bugfixes
* openssl\_pkcs12 \- modify autodetect to not detect pyOpenSSL \>\= 23\.3\.0\, which removed PKCS\#12 support \([https\://github\.com/ansible\-collections/community\.crypto/pull/666](https\://github\.com/ansible\-collections/community\.crypto/pull/666)\)\.
@@ -358,12 +417,12 @@ Bugfix release\.
<a id="v2-15-1"></a>
## v2\.15\.1
-<a id="release-summary-7"></a>
+<a id="release-summary-9"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-6"></a>
+<a id="bugfixes-8"></a>
### Bugfixes
* acme\_\* modules \- correctly handle error documents without <code>type</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/651](https\://github\.com/ansible\-collections/community\.crypto/issues/651)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/652](https\://github\.com/ansible\-collections/community\.crypto/pull/652)\)\.
@@ -371,22 +430,22 @@ Bugfix release\.
<a id="v2-15-0"></a>
## v2\.15\.0
-<a id="release-summary-8"></a>
+<a id="release-summary-10"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes-4"></a>
+<a id="minor-changes-5"></a>
### Minor Changes
* openssh\_keypair \- fail when comment cannot be updated \([https\://github\.com/ansible\-collections/community\.crypto/pull/646](https\://github\.com/ansible\-collections/community\.crypto/pull/646)\)\.
-<a id="deprecated-features-2"></a>
+<a id="deprecated-features-3"></a>
### Deprecated Features
* get\_certificate \- the default <code>false</code> of the <code>asn1\_base64</code> option is deprecated and will change to <code>true</code> in community\.crypto 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.crypto/pull/600](https\://github\.com/ansible\-collections/community\.crypto/pull/600)\)\.
-<a id="bugfixes-7"></a>
+<a id="bugfixes-9"></a>
### Bugfixes
* openssh\_cert\, openssh\_keypair \- the modules ignored return codes of <code>ssh</code> and <code>ssh\-keygen</code> in some cases \([https\://github\.com/ansible\-collections/community\.crypto/issues/645](https\://github\.com/ansible\-collections/community\.crypto/issues/645)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/646](https\://github\.com/ansible\-collections/community\.crypto/pull/646)\)\.
@@ -398,17 +457,17 @@ Bugfix and feature release\.
<a id="filter-1"></a>
#### Filter
-* gpg\_fingerprint \- Retrieve a GPG fingerprint from a GPG public or private key
+* community\.crypto\.gpg\_fingerprint \- Retrieve a GPG fingerprint from a GPG public or private key
<a id="lookup"></a>
#### Lookup
-* gpg\_fingerprint \- Retrieve a GPG fingerprint from a GPG public or private key file
+* community\.crypto\.gpg\_fingerprint \- Retrieve a GPG fingerprint from a GPG public or private key file
<a id="v2-14-1"></a>
## v2\.14\.1
-<a id="release-summary-9"></a>
+<a id="release-summary-11"></a>
### Release Summary
Bugfix and maintenance release with updated documentation\.
@@ -421,7 +480,7 @@ ansible\-core 2\.15 or later to see it as it is intended\. Alternatively you can
look at [the devel docsite](https\://docs\.ansible\.com/ansible/devel/collections/community/crypto/)
for the rendered HTML version of the documentation of the latest release\.
-<a id="bugfixes-8"></a>
+<a id="bugfixes-10"></a>
### Bugfixes
* Fix PEM detection/identification to also accept random other lines before the line starting with <code>\-\-\-\-\-BEGIN</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/627](https\://github\.com/ansible\-collections/community\.crypto/issues/627)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/628](https\://github\.com/ansible\-collections/community\.crypto/pull/628)\)\.
@@ -434,12 +493,12 @@ for the rendered HTML version of the documentation of the latest release\.
<a id="v2-14-0"></a>
## v2\.14\.0
-<a id="release-summary-10"></a>
+<a id="release-summary-12"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-5"></a>
+<a id="minor-changes-6"></a>
### Minor Changes
* acme\_certificate \- allow to use no challenge by providing <code>no challenge</code> for the <code>challenge</code> option\. This is needed for ACME servers where validation is done without challenges \([https\://github\.com/ansible\-collections/community\.crypto/issues/613](https\://github\.com/ansible\-collections/community\.crypto/issues/613)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/615](https\://github\.com/ansible\-collections/community\.crypto/pull/615)\)\.
@@ -449,12 +508,12 @@ Feature release\.
<a id="v2-13-1"></a>
## v2\.13\.1
-<a id="release-summary-11"></a>
+<a id="release-summary-13"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-9"></a>
+<a id="bugfixes-11"></a>
### Bugfixes
* execution environment definition \- fix installation of <code>python3\-pyOpenSSL</code> package on CentOS and RHEL \([https\://github\.com/ansible\-collections/community\.crypto/pull/606](https\://github\.com/ansible\-collections/community\.crypto/pull/606)\)\.
@@ -463,22 +522,22 @@ Bugfix release\.
<a id="v2-13-0"></a>
## v2\.13\.0
-<a id="release-summary-12"></a>
+<a id="release-summary-14"></a>
### Release Summary
Bugfix and maintenance release\.
-<a id="minor-changes-6"></a>
+<a id="minor-changes-7"></a>
### Minor Changes
* x509\_crl \- the <code>crl\_mode</code> option has been added to replace the existing <code>mode</code> option \([https\://github\.com/ansible\-collections/community\.crypto/issues/596](https\://github\.com/ansible\-collections/community\.crypto/issues/596)\)\.
-<a id="deprecated-features-3"></a>
+<a id="deprecated-features-4"></a>
### Deprecated Features
* x509\_crl \- the <code>mode</code> option is deprecated\; use <code>crl\_mode</code> instead\. The <code>mode</code> option will change its meaning in community\.crypto 3\.0\.0\, and will refer to the CRL file\'s mode instead \([https\://github\.com/ansible\-collections/community\.crypto/issues/596](https\://github\.com/ansible\-collections/community\.crypto/issues/596)\)\.
-<a id="bugfixes-10"></a>
+<a id="bugfixes-12"></a>
### Bugfixes
* openssh\_keypair \- always generate a new key pair if the private key does not exist\. Previously\, the module would fail when <code>regenerate\=fail</code> without an existing key\, contradicting the documentation \([https\://github\.com/ansible\-collections/community\.crypto/pull/598](https\://github\.com/ansible\-collections/community\.crypto/pull/598)\)\.
@@ -487,12 +546,12 @@ Bugfix and maintenance release\.
<a id="v2-12-0"></a>
## v2\.12\.0
-<a id="release-summary-13"></a>
+<a id="release-summary-15"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-7"></a>
+<a id="minor-changes-8"></a>
### Minor Changes
* get\_certificate \- add <code>asn1\_base64</code> option to control whether the ASN\.1 included in the <code>extensions</code> return value is binary data or Base64 encoded \([https\://github\.com/ansible\-collections/community\.crypto/pull/592](https\://github\.com/ansible\-collections/community\.crypto/pull/592)\)\.
@@ -500,7 +559,7 @@ Feature release\.
<a id="v2-11-1"></a>
## v2\.11\.1
-<a id="release-summary-14"></a>
+<a id="release-summary-16"></a>
### Release Summary
Maintenance release with improved documentation\.
@@ -508,17 +567,17 @@ Maintenance release with improved documentation\.
<a id="v2-11-0"></a>
## v2\.11\.0
-<a id="release-summary-15"></a>
+<a id="release-summary-17"></a>
### Release Summary
Feature and bugfix release\.
-<a id="minor-changes-8"></a>
+<a id="minor-changes-9"></a>
### Minor Changes
* get\_certificate \- adds <code>ciphers</code> option for custom cipher selection \([https\://github\.com/ansible\-collections/community\.crypto/pull/571](https\://github\.com/ansible\-collections/community\.crypto/pull/571)\)\.
-<a id="bugfixes-11"></a>
+<a id="bugfixes-13"></a>
### Bugfixes
* action plugin helper \- fix handling of deprecations for ansible\-core 2\.14\.2 \([https\://github\.com/ansible\-collections/community\.crypto/pull/572](https\://github\.com/ansible\-collections/community\.crypto/pull/572)\)\.
@@ -528,12 +587,12 @@ Feature and bugfix release\.
<a id="v2-10-0"></a>
## v2\.10\.0
-<a id="release-summary-16"></a>
+<a id="release-summary-18"></a>
### Release Summary
Bugfix and feature release\.
-<a id="bugfixes-12"></a>
+<a id="bugfixes-14"></a>
### Bugfixes
* openssl\_csr\, openssl\_csr\_pipe \- prevent invalid values for <code>crl\_distribution\_points</code> that do not have one of <code>full\_name</code>\, <code>relative\_name</code>\, and <code>crl\_issuer</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/560](https\://github\.com/ansible\-collections/community\.crypto/pull/560)\)\.
@@ -545,22 +604,22 @@ Bugfix and feature release\.
<a id="filter-2"></a>
#### Filter
-* openssl\_csr\_info \- Retrieve information from OpenSSL Certificate Signing Requests \(CSR\)
-* openssl\_privatekey\_info \- Retrieve information from OpenSSL private keys
-* openssl\_publickey\_info \- Retrieve information from OpenSSL public keys in PEM format
-* split\_pem \- Split PEM file contents into multiple objects
-* x509\_certificate\_info \- Retrieve information from X\.509 certificates in PEM format
-* x509\_crl\_info \- Retrieve information from X\.509 CRLs in PEM format
+* community\.crypto\.openssl\_csr\_info \- Retrieve information from OpenSSL Certificate Signing Requests \(CSR\)
+* community\.crypto\.openssl\_privatekey\_info \- Retrieve information from OpenSSL private keys
+* community\.crypto\.openssl\_publickey\_info \- Retrieve information from OpenSSL public keys in PEM format
+* community\.crypto\.split\_pem \- Split PEM file contents into multiple objects
+* community\.crypto\.x509\_certificate\_info \- Retrieve information from X\.509 certificates in PEM format
+* community\.crypto\.x509\_crl\_info \- Retrieve information from X\.509 CRLs in PEM format
<a id="v2-9-0"></a>
## v2\.9\.0
-<a id="release-summary-17"></a>
+<a id="release-summary-19"></a>
### Release Summary
Regular feature release\.
-<a id="minor-changes-9"></a>
+<a id="minor-changes-10"></a>
### Minor Changes
* x509\_certificate\_info \- adds <code>issuer\_uri</code> field in return value based on Authority Information Access data \([https\://github\.com/ansible\-collections/community\.crypto/pull/530](https\://github\.com/ansible\-collections/community\.crypto/pull/530)\)\.
@@ -568,7 +627,7 @@ Regular feature release\.
<a id="v2-8-1"></a>
## v2\.8\.1
-<a id="release-summary-18"></a>
+<a id="release-summary-20"></a>
### Release Summary
Maintenance release with improved documentation\.
@@ -576,12 +635,12 @@ Maintenance release with improved documentation\.
<a id="v2-8-0"></a>
## v2\.8\.0
-<a id="release-summary-19"></a>
+<a id="release-summary-21"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-10"></a>
+<a id="minor-changes-11"></a>
### Minor Changes
* acme\_\* modules \- handle more gracefully if CA\'s new nonce call does not return a nonce \([https\://github\.com/ansible\-collections/community\.crypto/pull/525](https\://github\.com/ansible\-collections/community\.crypto/pull/525)\)\.
@@ -591,12 +650,12 @@ Feature release\.
<a id="v2-7-1"></a>
## v2\.7\.1
-<a id="release-summary-20"></a>
+<a id="release-summary-22"></a>
### Release Summary
Maintenance release\.
-<a id="bugfixes-13"></a>
+<a id="bugfixes-15"></a>
### Bugfixes
* acme\_\* modules \- improve feedback when importing <code>cryptography</code> does not work \([https\://github\.com/ansible\-collections/community\.crypto/issues/518](https\://github\.com/ansible\-collections/community\.crypto/issues/518)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/519](https\://github\.com/ansible\-collections/community\.crypto/pull/519)\)\.
@@ -604,17 +663,17 @@ Maintenance release\.
<a id="v2-7-0"></a>
## v2\.7\.0
-<a id="release-summary-21"></a>
+<a id="release-summary-23"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-11"></a>
+<a id="minor-changes-12"></a>
### Minor Changes
* acme\* modules \- also support the HTTP 503 Service Unavailable and 408 Request Timeout response status for automatic retries \([https\://github\.com/ansible\-collections/community\.crypto/pull/513](https\://github\.com/ansible\-collections/community\.crypto/pull/513)\)\.
-<a id="bugfixes-14"></a>
+<a id="bugfixes-16"></a>
### Bugfixes
* openssl\_privatekey\_pipe \- ensure compatibility with newer versions of ansible\-core \([https\://github\.com/ansible\-collections/community\.crypto/pull/515](https\://github\.com/ansible\-collections/community\.crypto/pull/515)\)\.
@@ -622,12 +681,12 @@ Feature release\.
<a id="v2-6-0"></a>
## v2\.6\.0
-<a id="release-summary-22"></a>
+<a id="release-summary-24"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-12"></a>
+<a id="minor-changes-13"></a>
### Minor Changes
* acme\* modules \- support the HTTP 429 Too Many Requests response status \([https\://github\.com/ansible\-collections/community\.crypto/pull/508](https\://github\.com/ansible\-collections/community\.crypto/pull/508)\)\.
@@ -636,12 +695,12 @@ Feature release\.
<a id="v2-5-0"></a>
## v2\.5\.0
-<a id="release-summary-23"></a>
+<a id="release-summary-25"></a>
### Release Summary
Maintenance release with improved licensing declaration and documentation fixes\.
-<a id="minor-changes-13"></a>
+<a id="minor-changes-14"></a>
### Minor Changes
* All software licenses are now in the <code>LICENSES/</code> directory of the collection root\. Moreover\, <code>SPDX\-License\-Identifier\:</code> is used to declare the applicable license for every file that is not automatically generated \([https\://github\.com/ansible\-collections/community\.crypto/pull/491](https\://github\.com/ansible\-collections/community\.crypto/pull/491)\)\.
@@ -649,17 +708,17 @@ Maintenance release with improved licensing declaration and documentation fixes\
<a id="v2-4-0"></a>
## v2\.4\.0
-<a id="release-summary-24"></a>
+<a id="release-summary-26"></a>
### Release Summary
Deprecation and bugfix release\. No new features this time\.
-<a id="deprecated-features-4"></a>
+<a id="deprecated-features-5"></a>
### Deprecated Features
* Support for Ansible 2\.9 and ansible\-base 2\.10 is deprecated\, and will be removed in the next major release \(community\.crypto 3\.0\.0\)\. Some modules might still work with these versions afterwards\, but we will no longer keep compatibility code that was needed to support them \([https\://github\.com/ansible\-collections/community\.crypto/pull/460](https\://github\.com/ansible\-collections/community\.crypto/pull/460)\)\.
-<a id="bugfixes-15"></a>
+<a id="bugfixes-17"></a>
### Bugfixes
* openssl\_pkcs12 \- when using the pyOpenSSL backend\, do not crash when trying to read non\-existing other certificates \([https\://github\.com/ansible\-collections/community\.crypto/issues/486](https\://github\.com/ansible\-collections/community\.crypto/issues/486)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/487](https\://github\.com/ansible\-collections/community\.crypto/pull/487)\)\.
@@ -667,7 +726,7 @@ Deprecation and bugfix release\. No new features this time\.
<a id="v2-3-4"></a>
## v2\.3\.4
-<a id="release-summary-25"></a>
+<a id="release-summary-27"></a>
### Release Summary
Re\-release of what was intended to be 2\.3\.3\.
@@ -683,12 +742,12 @@ has been added\.
<a id="v2-3-3"></a>
## v2\.3\.3
-<a id="release-summary-26"></a>
+<a id="release-summary-28"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-16"></a>
+<a id="bugfixes-18"></a>
### Bugfixes
* Include <code>Apache\-2\.0\.txt</code> file for <code>plugins/module\_utils/crypto/\_obj2txt\.py</code> and <code>plugins/module\_utils/crypto/\_objects\_data\.py</code>\.
@@ -698,12 +757,12 @@ Bugfix release\.
<a id="v2-3-2"></a>
## v2\.3\.2
-<a id="release-summary-27"></a>
+<a id="release-summary-29"></a>
### Release Summary
Maintenance and bugfix release\.
-<a id="bugfixes-17"></a>
+<a id="bugfixes-19"></a>
### Bugfixes
* Include <code>simplified\_bsd\.txt</code> license file for the ECS module utils\.
@@ -712,12 +771,12 @@ Maintenance and bugfix release\.
<a id="v2-3-1"></a>
## v2\.3\.1
-<a id="release-summary-28"></a>
+<a id="release-summary-30"></a>
### Release Summary
Maintenance release\.
-<a id="bugfixes-18"></a>
+<a id="bugfixes-20"></a>
### Bugfixes
* Include <code>PSF\-license\.txt</code> file for <code>plugins/module\_utils/\_version\.py</code>\.
@@ -725,12 +784,12 @@ Maintenance release\.
<a id="v2-3-0"></a>
## v2\.3\.0
-<a id="release-summary-29"></a>
+<a id="release-summary-31"></a>
### Release Summary
Feature and bugfix release\.
-<a id="minor-changes-14"></a>
+<a id="minor-changes-15"></a>
### Minor Changes
* Prepare collection for inclusion in an Execution Environment by declaring its dependencies\. Please note that system packages are used for cryptography and PyOpenSSL\, which can be rather limited\. If you need features from newer cryptography versions\, you will have to manually force a newer version to be installed by pip by specifying something like <code>cryptography \>\= 37\.0\.0</code> in your Execution Environment\'s Python dependencies file \([https\://github\.com/ansible\-collections/community\.crypto/pull/440](https\://github\.com/ansible\-collections/community\.crypto/pull/440)\)\.
@@ -744,7 +803,7 @@ Feature and bugfix release\.
* x509\_crl \- add <code>name\_encoding</code> option to control the encoding \(IDNA\, Unicode\) used to return domain names in general names \([https\://github\.com/ansible\-collections/community\.crypto/pull/436](https\://github\.com/ansible\-collections/community\.crypto/pull/436)\)\.
* x509\_crl\_info \- add <code>name\_encoding</code> option to control the encoding \(IDNA\, Unicode\) used to return domain names in general names \([https\://github\.com/ansible\-collections/community\.crypto/pull/436](https\://github\.com/ansible\-collections/community\.crypto/pull/436)\)\.
-<a id="bugfixes-19"></a>
+<a id="bugfixes-21"></a>
### Bugfixes
* Make collection more robust when PyOpenSSL is used with an incompatible cryptography version \([https\://github\.com/ansible\-collections/community\.crypto/pull/445](https\://github\.com/ansible\-collections/community\.crypto/pull/445)\)\.
@@ -753,12 +812,12 @@ Feature and bugfix release\.
<a id="v2-2-4"></a>
## v2\.2\.4
-<a id="release-summary-30"></a>
+<a id="release-summary-32"></a>
### Release Summary
Regular maintenance release\.
-<a id="bugfixes-20"></a>
+<a id="bugfixes-22"></a>
### Bugfixes
* openssh\_\* modules \- fix exception handling to report traceback to users for enhanced traceability \([https\://github\.com/ansible\-collections/community\.crypto/pull/417](https\://github\.com/ansible\-collections/community\.crypto/pull/417)\)\.
@@ -766,12 +825,12 @@ Regular maintenance release\.
<a id="v2-2-3"></a>
## v2\.2\.3
-<a id="release-summary-31"></a>
+<a id="release-summary-33"></a>
### Release Summary
Regular bugfix release\.
-<a id="bugfixes-21"></a>
+<a id="bugfixes-23"></a>
### Bugfixes
* luks\_device \- fix parsing of <code>lsblk</code> output when device name ends with <code>crypt</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/409](https\://github\.com/ansible\-collections/community\.crypto/issues/409)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/410](https\://github\.com/ansible\-collections/community\.crypto/pull/410)\)\.
@@ -779,14 +838,14 @@ Regular bugfix release\.
<a id="v2-2-2"></a>
## v2\.2\.2
-<a id="release-summary-32"></a>
+<a id="release-summary-34"></a>
### Release Summary
Regular bugfix release\.
In this release\, we extended the test matrix to include Alpine 3\, ArchLinux\, Debian Bullseye\, and CentOS Stream 8\. CentOS 8 was removed from the test matrix\.
-<a id="bugfixes-22"></a>
+<a id="bugfixes-24"></a>
### Bugfixes
* certificate\_complete\_chain \- allow multiple potential intermediate certificates to have the same subject \([https\://github\.com/ansible\-collections/community\.crypto/issues/399](https\://github\.com/ansible\-collections/community\.crypto/issues/399)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/403](https\://github\.com/ansible\-collections/community\.crypto/pull/403)\)\.
@@ -798,12 +857,12 @@ In this release\, we extended the test matrix to include Alpine 3\, ArchLinux\,
<a id="v2-2-1"></a>
## v2\.2\.1
-<a id="release-summary-33"></a>
+<a id="release-summary-35"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-23"></a>
+<a id="bugfixes-25"></a>
### Bugfixes
* openssh\_cert \- fixed false <code>changed</code> status for <code>host</code> certificates when using <code>full\_idempotence</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/395](https\://github\.com/ansible\-collections/community\.crypto/issues/395)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/396](https\://github\.com/ansible\-collections/community\.crypto/pull/396)\)\.
@@ -811,17 +870,17 @@ Bugfix release\.
<a id="v2-2-0"></a>
## v2\.2\.0
-<a id="release-summary-34"></a>
+<a id="release-summary-36"></a>
### Release Summary
Regular bugfix and feature release\.
-<a id="minor-changes-15"></a>
+<a id="minor-changes-16"></a>
### Minor Changes
* openssh\_cert \- added <code>ignore\_timestamps</code> parameter so it can be used semi\-idempotent with relative timestamps in <code>valid\_to</code>/<code>valid\_from</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/379](https\://github\.com/ansible\-collections/community\.crypto/issues/379)\)\.
-<a id="bugfixes-24"></a>
+<a id="bugfixes-26"></a>
### Bugfixes
* luks\_devices \- set <code>LANG</code> and similar environment variables to avoid translated output\, which can break some of the module\'s functionality like key management \([https\://github\.com/ansible\-collections/community\.crypto/pull/388](https\://github\.com/ansible\-collections/community\.crypto/pull/388)\, [https\://github\.com/ansible\-collections/community\.crypto/issues/385](https\://github\.com/ansible\-collections/community\.crypto/issues/385)\)\.
@@ -829,33 +888,33 @@ Regular bugfix and feature release\.
<a id="v2-1-0"></a>
## v2\.1\.0
-<a id="release-summary-35"></a>
+<a id="release-summary-37"></a>
### Release Summary
Feature and bugfix release\.
-<a id="minor-changes-16"></a>
+<a id="minor-changes-17"></a>
### Minor Changes
* Adjust error messages that indicate <code>cryptography</code> is not installed from <code>Can\'t</code> to <code>Cannot</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/374](https\://github\.com/ansible\-collections/community\.crypto/pull/374)\)\.
-<a id="bugfixes-25"></a>
+<a id="bugfixes-27"></a>
### Bugfixes
* Various modules and plugins \- use vendored version of <code>distutils\.version</code> instead of the deprecated Python standard library <code>distutils</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/353](https\://github\.com/ansible\-collections/community\.crypto/pull/353)\)\.
* certificate\_complete\_chain \- do not append root twice if the chain already ends with a root certificate \([https\://github\.com/ansible\-collections/community\.crypto/pull/360](https\://github\.com/ansible\-collections/community\.crypto/pull/360)\)\.
* certificate\_complete\_chain \- do not hang when infinite loop is found \([https\://github\.com/ansible\-collections/community\.crypto/issues/355](https\://github\.com/ansible\-collections/community\.crypto/issues/355)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/360](https\://github\.com/ansible\-collections/community\.crypto/pull/360)\)\.
-<a id="new-modules-1"></a>
+<a id="new-modules-2"></a>
### New Modules
-* crypto\_info \- Retrieve cryptographic capabilities
-* openssl\_privatekey\_convert \- Convert OpenSSL private keys
+* community\.crypto\.crypto\_info \- Retrieve cryptographic capabilities
+* community\.crypto\.openssl\_privatekey\_convert \- Convert OpenSSL private keys
<a id="v2-0-2"></a>
## v2\.0\.2
-<a id="release-summary-36"></a>
+<a id="release-summary-38"></a>
### Release Summary
Documentation fix release\. No actual code changes\.
@@ -863,17 +922,17 @@ Documentation fix release\. No actual code changes\.
<a id="v2-0-1"></a>
## v2\.0\.1
-<a id="release-summary-37"></a>
+<a id="release-summary-39"></a>
### Release Summary
Bugfix release with extra forward compatibility for newer versions of cryptography\.
-<a id="minor-changes-17"></a>
+<a id="minor-changes-18"></a>
### Minor Changes
* acme\_\* modules \- fix usage of <code>fetch\_url</code> with changes in latest ansible\-core <code>devel</code> branch \([https\://github\.com/ansible\-collections/community\.crypto/pull/339](https\://github\.com/ansible\-collections/community\.crypto/pull/339)\)\.
-<a id="bugfixes-26"></a>
+<a id="bugfixes-28"></a>
### Bugfixes
* acme\_certificate \- avoid passing multiple certificates to <code>cryptography</code>\'s X\.509 certificate loader when <code>fullchain\_dest</code> is used \([https\://github\.com/ansible\-collections/community\.crypto/pull/324](https\://github\.com/ansible\-collections/community\.crypto/pull/324)\)\.
@@ -884,12 +943,12 @@ Bugfix release with extra forward compatibility for newer versions of cryptograp
<a id="v2-0-0"></a>
## v2\.0\.0
-<a id="release-summary-38"></a>
+<a id="release-summary-40"></a>
### Release Summary
A new major release of the <code>community\.crypto</code> collection\. The main changes are removal of the PyOpenSSL backends for almost all modules \(<code>openssl\_pkcs12</code> being the only exception\)\, and removal of the <code>assertonly</code> provider in the <code>x509\_certificate</code> provider\. There are also some other breaking changes which should improve the user interface/experience of this collection long\-term\.
-<a id="minor-changes-18"></a>
+<a id="minor-changes-19"></a>
### Minor Changes
* acme\_certificate \- the <code>subject</code> and <code>issuer</code> fields in in the <code>select\_chain</code> entries are now more strictly validated \([https\://github\.com/ansible\-collections/community\.crypto/pull/316](https\://github\.com/ansible\-collections/community\.crypto/pull/316)\)\.
@@ -914,7 +973,7 @@ A new major release of the <code>community\.crypto</code> collection\. The main
* openssl\_privatekey\_info \- by default consistency checks are not run\; they need to be explicitly requested by passing <code>check\_consistency\=true</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/309](https\://github\.com/ansible\-collections/community\.crypto/pull/309)\)\.
* x509\_crl \- for idempotency checks\, the <code>issuer</code> order is ignored\. If order is important\, use the new <code>issuer\_ordered</code> option \([https\://github\.com/ansible\-collections/community\.crypto/pull/316](https\://github\.com/ansible\-collections/community\.crypto/pull/316)\)\.
-<a id="deprecated-features-5"></a>
+<a id="deprecated-features-6"></a>
### Deprecated Features
* acme\_\* modules \- ACME version 1 is now deprecated and support for it will be removed in community\.crypto 2\.0\.0 \([https\://github\.com/ansible\-collections/community\.crypto/pull/288](https\://github\.com/ansible\-collections/community\.crypto/pull/288)\)\.
@@ -946,7 +1005,7 @@ A new major release of the <code>community\.crypto</code> collection\. The main
* x509\_certificate\_info \- removed the <code>pyopenssl</code> backend \([https\://github\.com/ansible\-collections/community\.crypto/pull/273](https\://github\.com/ansible\-collections/community\.crypto/pull/273)\)\.
* x509\_certificate\_pipe \- removed the <code>pyopenssl</code> backend \([https\://github\.com/ansible\-collections/community\.crypto/pull/273](https\://github\.com/ansible\-collections/community\.crypto/pull/273)\)\.
-<a id="bugfixes-27"></a>
+<a id="bugfixes-29"></a>
### Bugfixes
* cryptography backend \- improve Unicode handling for Python 2 \([https\://github\.com/ansible\-collections/community\.crypto/pull/313](https\://github\.com/ansible\-collections/community\.crypto/pull/313)\)\.
@@ -958,12 +1017,12 @@ A new major release of the <code>community\.crypto</code> collection\. The main
<a id="v1-9-4"></a>
## v1\.9\.4
-<a id="release-summary-39"></a>
+<a id="release-summary-41"></a>
### Release Summary
Regular bugfix release\.
-<a id="bugfixes-28"></a>
+<a id="bugfixes-30"></a>
### Bugfixes
* acme\_\* modules \- fix commands composed for OpenSSL backend to retrieve information on CSRs and certificates from stdin to use <code>/dev/stdin</code> instead of <code>\-</code>\. This is needed for OpenSSL 1\.0\.1 and 1\.0\.2\, apparently \([https\://github\.com/ansible\-collections/community\.crypto/pull/279](https\://github\.com/ansible\-collections/community\.crypto/pull/279)\)\.
@@ -972,12 +1031,12 @@ Regular bugfix release\.
<a id="v1-9-3"></a>
## v1\.9\.3
-<a id="release-summary-40"></a>
+<a id="release-summary-42"></a>
### Release Summary
Regular bugfix release\.
-<a id="bugfixes-29"></a>
+<a id="bugfixes-31"></a>
### Bugfixes
* openssl\_csr and openssl\_csr\_pipe \- make sure that Unicode strings are used to compare strings with the cryptography backend\. This fixes idempotency problems with non\-ASCII letters on Python 2 \([https\://github\.com/ansible\-collections/community\.crypto/issues/270](https\://github\.com/ansible\-collections/community\.crypto/issues/270)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/271](https\://github\.com/ansible\-collections/community\.crypto/pull/271)\)\.
@@ -985,7 +1044,7 @@ Regular bugfix release\.
<a id="v1-9-2"></a>
## v1\.9\.2
-<a id="release-summary-41"></a>
+<a id="release-summary-43"></a>
### Release Summary
Bugfix release to fix the changelog\. No other change compared to 1\.9\.0\.
@@ -993,7 +1052,7 @@ Bugfix release to fix the changelog\. No other change compared to 1\.9\.0\.
<a id="v1-9-1"></a>
## v1\.9\.1
-<a id="release-summary-42"></a>
+<a id="release-summary-44"></a>
### Release Summary
Accidental 1\.9\.1 release\. Identical to 1\.9\.0\.
@@ -1001,18 +1060,18 @@ Accidental 1\.9\.1 release\. Identical to 1\.9\.0\.
<a id="v1-9-0"></a>
## v1\.9\.0
-<a id="release-summary-43"></a>
+<a id="release-summary-45"></a>
### Release Summary
Regular feature release\.
-<a id="minor-changes-19"></a>
+<a id="minor-changes-20"></a>
### Minor Changes
* get\_certificate \- added <code>starttls</code> option to retrieve certificates from servers which require clients to request an encrypted connection \([https\://github\.com/ansible\-collections/community\.crypto/pull/264](https\://github\.com/ansible\-collections/community\.crypto/pull/264)\)\.
* openssh\_keypair \- added <code>diff</code> support \([https\://github\.com/ansible\-collections/community\.crypto/pull/260](https\://github\.com/ansible\-collections/community\.crypto/pull/260)\)\.
-<a id="bugfixes-30"></a>
+<a id="bugfixes-32"></a>
### Bugfixes
* keypair\_backend module utils \- simplify code to pass sanity tests \([https\://github\.com/ansible\-collections/community\.crypto/pull/263](https\://github\.com/ansible\-collections/community\.crypto/pull/263)\)\.
@@ -1023,12 +1082,12 @@ Regular feature release\.
<a id="v1-8-0"></a>
## v1\.8\.0
-<a id="release-summary-44"></a>
+<a id="release-summary-46"></a>
### Release Summary
Regular bugfix and feature release\.
-<a id="minor-changes-20"></a>
+<a id="minor-changes-21"></a>
### Minor Changes
* Avoid internal ansible\-core module\_utils in favor of equivalent public API available since at least Ansible 2\.9 \([https\://github\.com/ansible\-collections/community\.crypto/pull/253](https\://github\.com/ansible\-collections/community\.crypto/pull/253)\)\.
@@ -1036,7 +1095,7 @@ Regular bugfix and feature release\.
* openssh\_cert \- added <code>regenerate</code> option to validate additional certificate parameters which trigger regeneration of an existing certificate \([https\://github\.com/ansible\-collections/community\.crypto/pull/256](https\://github\.com/ansible\-collections/community\.crypto/pull/256)\)\.
* openssh\_cert \- adding <code>diff</code> support \([https\://github\.com/ansible\-collections/community\.crypto/pull/255](https\://github\.com/ansible\-collections/community\.crypto/pull/255)\)\.
-<a id="bugfixes-31"></a>
+<a id="bugfixes-33"></a>
### Bugfixes
* openssh\_cert \- fixed certificate generation to restore original certificate if an error is encountered \([https\://github\.com/ansible\-collections/community\.crypto/pull/255](https\://github\.com/ansible\-collections/community\.crypto/pull/255)\)\.
@@ -1045,12 +1104,12 @@ Regular bugfix and feature release\.
<a id="v1-7-1"></a>
## v1\.7\.1
-<a id="release-summary-45"></a>
+<a id="release-summary-47"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-32"></a>
+<a id="bugfixes-34"></a>
### Bugfixes
* openssl\_pkcs12 \- fix crash when loading passphrase\-protected PKCS\#12 files with <code>cryptography</code> backend \([https\://github\.com/ansible\-collections/community\.crypto/issues/247](https\://github\.com/ansible\-collections/community\.crypto/issues/247)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/248](https\://github\.com/ansible\-collections/community\.crypto/pull/248)\)\.
@@ -1058,12 +1117,12 @@ Bugfix release\.
<a id="v1-7-0"></a>
## v1\.7\.0
-<a id="release-summary-46"></a>
+<a id="release-summary-48"></a>
### Release Summary
Regular feature and bugfix release\.
-<a id="minor-changes-21"></a>
+<a id="minor-changes-22"></a>
### Minor Changes
* cryptography\_openssh module utils \- new module\_utils for managing asymmetric keypairs and OpenSSH formatted/encoded asymmetric keypairs \([https\://github\.com/ansible\-collections/community\.crypto/pull/213](https\://github\.com/ansible\-collections/community\.crypto/pull/213)\)\.
@@ -1086,27 +1145,27 @@ Regular feature and bugfix release\.
* x509\_crl\_info \- add <code>list\_revoked\_certificates</code> option to avoid enumerating all revoked certificates \([https\://github\.com/ansible\-collections/community\.crypto/pull/232](https\://github\.com/ansible\-collections/community\.crypto/pull/232)\)\.
* x509\_crl\_info \- refactor module to allow code reuse for diff mode \([https\://github\.com/ansible\-collections/community\.crypto/pull/203](https\://github\.com/ansible\-collections/community\.crypto/pull/203)\)\.
-<a id="bugfixes-33"></a>
+<a id="bugfixes-35"></a>
### Bugfixes
* openssh\_keypair \- fix <code>check\_mode</code> to populate return values for existing keypairs \([https\://github\.com/ansible\-collections/community\.crypto/issues/113](https\://github\.com/ansible\-collections/community\.crypto/issues/113)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/230](https\://github\.com/ansible\-collections/community\.crypto/pull/230)\)\.
* various modules \- prevent crashes when modules try to set attributes on not yet existing files in check mode\. This will be fixed in ansible\-core 2\.12\, but it is not backported to every Ansible version we support \([https\://github\.com/ansible\-collections/community\.crypto/issue/242](https\://github\.com/ansible\-collections/community\.crypto/issue/242)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/243](https\://github\.com/ansible\-collections/community\.crypto/pull/243)\)\.
* x509\_certificate \- fix crash when <code>assertonly</code> provider is used and some error conditions should be reported \([https\://github\.com/ansible\-collections/community\.crypto/issues/240](https\://github\.com/ansible\-collections/community\.crypto/issues/240)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/241](https\://github\.com/ansible\-collections/community\.crypto/pull/241)\)\.
-<a id="new-modules-2"></a>
+<a id="new-modules-3"></a>
### New Modules
-* openssl\_publickey\_info \- Provide information for OpenSSL public keys
+* community\.crypto\.openssl\_publickey\_info \- Provide information for OpenSSL public keys
<a id="v1-6-2"></a>
## v1\.6\.2
-<a id="release-summary-47"></a>
+<a id="release-summary-49"></a>
### Release Summary
Bugfix release\. Fixes compatibility issue of ACME modules with step\-ca\.
-<a id="bugfixes-34"></a>
+<a id="bugfixes-36"></a>
### Bugfixes
* acme\_\* modules \- avoid crashing for ACME servers where the <code>meta</code> directory key is not present \([https\://github\.com/ansible\-collections/community\.crypto/issues/220](https\://github\.com/ansible\-collections/community\.crypto/issues/220)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/221](https\://github\.com/ansible\-collections/community\.crypto/pull/221)\)\.
@@ -1114,12 +1173,12 @@ Bugfix release\. Fixes compatibility issue of ACME modules with step\-ca\.
<a id="v1-6-1"></a>
## v1\.6\.1
-<a id="release-summary-48"></a>
+<a id="release-summary-50"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-35"></a>
+<a id="bugfixes-37"></a>
### Bugfixes
* acme\_\* modules \- fix wrong usages of <code>ACMEProtocolException</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/216](https\://github\.com/ansible\-collections/community\.crypto/pull/216)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/217](https\://github\.com/ansible\-collections/community\.crypto/pull/217)\)\.
@@ -1127,12 +1186,12 @@ Bugfix release\.
<a id="v1-6-0"></a>
## v1\.6\.0
-<a id="release-summary-49"></a>
+<a id="release-summary-51"></a>
### Release Summary
Fixes compatibility issues with the latest ansible\-core 2\.11 beta\, and contains a lot of internal refactoring for the ACME modules and support for private key passphrases for them\.
-<a id="minor-changes-22"></a>
+<a id="minor-changes-23"></a>
### Minor Changes
* acme module\_utils \- the <code>acme</code> module\_utils has been split up into several Python modules \([https\://github\.com/ansible\-collections/community\.crypto/pull/184](https\://github\.com/ansible\-collections/community\.crypto/pull/184)\)\.
@@ -1141,12 +1200,12 @@ Fixes compatibility issues with the latest ansible\-core 2\.11 beta\, and contai
* acme\_certificate\_revoke \- support revoking by private keys that are passphrase protected for <code>cryptography</code> backend \([https\://github\.com/ansible\-collections/community\.crypto/pull/207](https\://github\.com/ansible\-collections/community\.crypto/pull/207)\)\.
* acme\_challenge\_cert\_helper \- add <code>private\_key\_passphrase</code> parameter \([https\://github\.com/ansible\-collections/community\.crypto/pull/207](https\://github\.com/ansible\-collections/community\.crypto/pull/207)\)\.
-<a id="deprecated-features-6"></a>
+<a id="deprecated-features-7"></a>
### Deprecated Features
* acme module\_utils \- the <code>acme</code> module\_utils \(<code>ansible\_collections\.community\.crypto\.plugins\.module\_utils\.acme</code>\) is deprecated and will be removed in community\.crypto 2\.0\.0\. Use the new Python modules in the <code>acme</code> package instead \(<code>ansible\_collections\.community\.crypto\.plugins\.module\_utils\.acme\.xxx</code>\) \([https\://github\.com/ansible\-collections/community\.crypto/pull/184](https\://github\.com/ansible\-collections/community\.crypto/pull/184)\)\.
-<a id="bugfixes-36"></a>
+<a id="bugfixes-38"></a>
### Bugfixes
* action\_module plugin helper \- make compatible with latest changes in ansible\-core 2\.11\.0b3 \([https\://github\.com/ansible\-collections/community\.crypto/pull/202](https\://github\.com/ansible\-collections/community\.crypto/pull/202)\)\.
@@ -1155,23 +1214,23 @@ Fixes compatibility issues with the latest ansible\-core 2\.11 beta\, and contai
<a id="v1-5-0"></a>
## v1\.5\.0
-<a id="release-summary-50"></a>
+<a id="release-summary-52"></a>
### Release Summary
Regular feature and bugfix release\. Deprecates a return value\.
-<a id="minor-changes-23"></a>
+<a id="minor-changes-24"></a>
### Minor Changes
* acme\_account\_info \- when <code>retrieve\_orders</code> is not <code>ignore</code> and the ACME server allows to query orders\, the new return value <code>order\_uris</code> is always populated with a list of URIs \([https\://github\.com/ansible\-collections/community\.crypto/pull/178](https\://github\.com/ansible\-collections/community\.crypto/pull/178)\)\.
* luks\_device \- allow to specify sector size for LUKS2 containers with new <code>sector\_size</code> parameter \([https\://github\.com/ansible\-collections/community\.crypto/pull/193](https\://github\.com/ansible\-collections/community\.crypto/pull/193)\)\.
-<a id="deprecated-features-7"></a>
+<a id="deprecated-features-8"></a>
### Deprecated Features
* acme\_account\_info \- when <code>retrieve\_orders\=url\_list</code>\, <code>orders</code> will no longer be returned in community\.crypto 2\.0\.0\. Use <code>order\_uris</code> instead \([https\://github\.com/ansible\-collections/community\.crypto/pull/178](https\://github\.com/ansible\-collections/community\.crypto/pull/178)\)\.
-<a id="bugfixes-37"></a>
+<a id="bugfixes-39"></a>
### Bugfixes
* openssl\_csr \- no longer fails when comparing CSR without basic constraint when <code>basic\_constraints</code> is specified \([https\://github\.com/ansible\-collections/community\.crypto/issues/179](https\://github\.com/ansible\-collections/community\.crypto/issues/179)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/180](https\://github\.com/ansible\-collections/community\.crypto/pull/180)\)\.
@@ -1179,12 +1238,12 @@ Regular feature and bugfix release\. Deprecates a return value\.
<a id="v1-4-0"></a>
## v1\.4\.0
-<a id="release-summary-51"></a>
+<a id="release-summary-53"></a>
### Release Summary
Release with several new features and bugfixes\.
-<a id="minor-changes-24"></a>
+<a id="minor-changes-25"></a>
### Minor Changes
* The ACME module\_utils has been relicensed back from the Simplified BSD License \([https\://opensource\.org/licenses/BSD\-2\-Clause](https\://opensource\.org/licenses/BSD\-2\-Clause)\) to the GPLv3\+ \(same license used by most other code in this collection\)\. This undoes a licensing change when the original GPLv3\+ licensed code was moved to module\_utils in [https\://github\.com/ansible/ansible/pull/40697](https\://github\.com/ansible/ansible/pull/40697) \([https\://github\.com/ansible\-collections/community\.crypto/pull/165](https\://github\.com/ansible\-collections/community\.crypto/pull/165)\)\.
@@ -1194,7 +1253,7 @@ Release with several new features and bugfixes\.
* openssl\_csr\, openssl\_csr\_pipe \- allow to specify CRL distribution endpoints with <code>crl\_distribution\_points</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/147](https\://github\.com/ansible\-collections/community\.crypto/issues/147)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/167](https\://github\.com/ansible\-collections/community\.crypto/pull/167)\)\.
* openssl\_pkcs12 \- allow to specify certificate bundles in <code>other\_certificates</code> by using new option <code>other\_certificates\_parse\_all</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/149](https\://github\.com/ansible\-collections/community\.crypto/issues/149)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/166](https\://github\.com/ansible\-collections/community\.crypto/pull/166)\)\.
-<a id="bugfixes-38"></a>
+<a id="bugfixes-40"></a>
### Bugfixes
* acme\_certificate \- error when requested challenge type is not found for non\-valid challenges\, instead of hanging on step 2 \([https\://github\.com/ansible\-collections/community\.crypto/issues/171](https\://github\.com/ansible\-collections/community\.crypto/issues/171)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/173](https\://github\.com/ansible\-collections/community\.crypto/pull/173)\)\.
@@ -1202,12 +1261,12 @@ Release with several new features and bugfixes\.
<a id="v1-3-0"></a>
## v1\.3\.0
-<a id="release-summary-52"></a>
+<a id="release-summary-54"></a>
### Release Summary
Contains new modules <code>openssl\_privatekey\_pipe</code>\, <code>openssl\_csr\_pipe</code> and <code>x509\_certificate\_pipe</code> which allow to create or update private keys\, CSRs and X\.509 certificates without having to write them to disk\.
-<a id="minor-changes-25"></a>
+<a id="minor-changes-26"></a>
### Minor Changes
* openssh\_cert \- add module parameter <code>use\_agent</code> to enable using signing keys stored in ssh\-agent \([https\://github\.com/ansible\-collections/community\.crypto/issues/116](https\://github\.com/ansible\-collections/community\.crypto/issues/116)\)\.
@@ -1217,29 +1276,29 @@ Contains new modules <code>openssl\_privatekey\_pipe</code>\, <code>openssl\_csr
* x509\_certificate \- for the <code>selfsigned</code> provider\, a CSR is not required anymore\. If no CSR is provided\, the module behaves as if a minimal CSR which only contains the public key has been provided \([https\://github\.com/ansible\-collections/community\.crypto/issues/32](https\://github\.com/ansible\-collections/community\.crypto/issues/32)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/129](https\://github\.com/ansible\-collections/community\.crypto/pull/129)\)\.
* x509\_certificate \- refactor module to allow code reuse by x509\_certificate\_pipe \([https\://github\.com/ansible\-collections/community\.crypto/pull/135](https\://github\.com/ansible\-collections/community\.crypto/pull/135)\)\.
-<a id="bugfixes-39"></a>
+<a id="bugfixes-41"></a>
### Bugfixes
* openssl\_pkcs12 \- report the correct state when <code>action</code> is <code>parse</code> \([https\://github\.com/ansible\-collections/community\.crypto/issues/143](https\://github\.com/ansible\-collections/community\.crypto/issues/143)\)\.
* support code \- improve handling of certificate and certificate signing request \(CSR\) loading with the <code>cryptography</code> backend when errors occur \([https\://github\.com/ansible\-collections/community\.crypto/issues/138](https\://github\.com/ansible\-collections/community\.crypto/issues/138)\, [https\://github\.com/ansible\-collections/community\.crypto/pull/139](https\://github\.com/ansible\-collections/community\.crypto/pull/139)\)\.
* x509\_certificate \- fix <code>entrust</code> provider\, which was broken since community\.crypto 0\.1\.0 due to a feature added before the collection move \([https\://github\.com/ansible\-collections/community\.crypto/pull/135](https\://github\.com/ansible\-collections/community\.crypto/pull/135)\)\.
-<a id="new-modules-3"></a>
+<a id="new-modules-4"></a>
### New Modules
-* openssl\_csr\_pipe \- Generate OpenSSL Certificate Signing Request \(CSR\)
-* openssl\_privatekey\_pipe \- Generate OpenSSL private keys without disk access
-* x509\_certificate\_pipe \- Generate and/or check OpenSSL certificates
+* community\.crypto\.openssl\_csr\_pipe \- Generate OpenSSL Certificate Signing Request \(CSR\)
+* community\.crypto\.openssl\_privatekey\_pipe \- Generate OpenSSL private keys without disk access
+* community\.crypto\.x509\_certificate\_pipe \- Generate and/or check OpenSSL certificates
<a id="v1-2-0"></a>
## v1\.2\.0
-<a id="release-summary-53"></a>
+<a id="release-summary-55"></a>
### Release Summary
Please note that this release fixes a security issue \(CVE\-2020\-25646\)\.
-<a id="minor-changes-26"></a>
+<a id="minor-changes-27"></a>
### Minor Changes
* acme\_certificate \- allow to pass CSR file as content with new option <code>csr\_content</code> \([https\://github\.com/ansible\-collections/community\.crypto/pull/115](https\://github\.com/ansible\-collections/community\.crypto/pull/115)\)\.
@@ -1255,7 +1314,7 @@ Please note that this release fixes a security issue \(CVE\-2020\-25646\)\.
* x509\_certificate \- the options <code>privatekey\_content</code> and <code>ownca\_privatekey\_content</code> were not marked as <code>no\_log</code>\, resulting in it being dumped into the system log by default\, and returned in the registered results in the <code>invocation</code> field \(CVE\-2020\-25646\, [https\://github\.com/ansible\-collections/community\.crypto/pull/125](https\://github\.com/ansible\-collections/community\.crypto/pull/125)\)\.
* x509\_crl \- the option <code>privatekey\_content</code> was not marked as <code>no\_log</code>\, resulting in it being dumped into the system log by default\, and returned in the registered results in the <code>invocation</code> field \(CVE\-2020\-25646\, [https\://github\.com/ansible\-collections/community\.crypto/pull/125](https\://github\.com/ansible\-collections/community\.crypto/pull/125)\)\.
-<a id="bugfixes-40"></a>
+<a id="bugfixes-42"></a>
### Bugfixes
* openssl\_pkcs12 \- do not crash when reading PKCS\#12 file which has no private key and/or no main certificate \([https\://github\.com/ansible\-collections/community\.crypto/issues/103](https\://github\.com/ansible\-collections/community\.crypto/issues/103)\)\.
@@ -1263,12 +1322,12 @@ Please note that this release fixes a security issue \(CVE\-2020\-25646\)\.
<a id="v1-1-1"></a>
## v1\.1\.1
-<a id="release-summary-54"></a>
+<a id="release-summary-56"></a>
### Release Summary
Bugfixes for Ansible 2\.10\.0\.
-<a id="bugfixes-41"></a>
+<a id="bugfixes-43"></a>
### Bugfixes
* meta/runtime\.yml \- convert Ansible version numbers for old names of modules to collection version numbers \([https\://github\.com/ansible\-collections/community\.crypto/pull/108](https\://github\.com/ansible\-collections/community\.crypto/pull/108)\)\.
@@ -1277,12 +1336,12 @@ Bugfixes for Ansible 2\.10\.0\.
<a id="v1-1-0"></a>
## v1\.1\.0
-<a id="release-summary-55"></a>
+<a id="release-summary-57"></a>
### Release Summary
Release for Ansible 2\.10\.0\.
-<a id="minor-changes-27"></a>
+<a id="minor-changes-28"></a>
### Minor Changes
* acme\_account \- add <code>external\_account\_binding</code> option to allow creation of ACME accounts with External Account Binding \([https\://github\.com/ansible\-collections/community\.crypto/issues/89](https\://github\.com/ansible\-collections/community\.crypto/issues/89)\)\.
@@ -1295,28 +1354,28 @@ Release for Ansible 2\.10\.0\.
* openssl\_csr \- add support for name constraints extension \([https\://github\.com/ansible\-collections/community\.crypto/issues/46](https\://github\.com/ansible\-collections/community\.crypto/issues/46)\)\.
* openssl\_csr\_info \- add support for name constraints extension \([https\://github\.com/ansible\-collections/community\.crypto/issues/46](https\://github\.com/ansible\-collections/community\.crypto/issues/46)\)\.
-<a id="bugfixes-42"></a>
+<a id="bugfixes-44"></a>
### Bugfixes
* acme\_inspect \- fix problem with Python 3\.5 that JSON was not decoded \([https\://github\.com/ansible\-collections/community\.crypto/issues/86](https\://github\.com/ansible\-collections/community\.crypto/issues/86)\)\.
* get\_certificate \- fix <code>ca\_cert</code> option handling when <code>proxy\_host</code> is used \([https\://github\.com/ansible\-collections/community\.crypto/pull/84](https\://github\.com/ansible\-collections/community\.crypto/pull/84)\)\.
* openssl\_\*\, x509\_\* modules \- fix handling of general names which refer to IP networks and not IP addresses \([https\://github\.com/ansible\-collections/community\.crypto/pull/92](https\://github\.com/ansible\-collections/community\.crypto/pull/92)\)\.
-<a id="new-modules-4"></a>
+<a id="new-modules-5"></a>
### New Modules
-* openssl\_signature \- Sign data with openssl
-* openssl\_signature\_info \- Verify signatures with openssl
+* community\.crypto\.openssl\_signature \- Sign data with openssl
+* community\.crypto\.openssl\_signature\_info \- Verify signatures with openssl
<a id="v1-0-0"></a>
## v1\.0\.0
-<a id="release-summary-56"></a>
+<a id="release-summary-58"></a>
### Release Summary
This is the first proper release of the <code>community\.crypto</code> collection\. This changelog contains all changes to the modules in this collection that were added after the release of Ansible 2\.9\.0\.
-<a id="minor-changes-28"></a>
+<a id="minor-changes-29"></a>
### Minor Changes
* luks\_device \- accept <code>passphrase</code>\, <code>new\_passphrase</code> and <code>remove\_passphrase</code>\.
@@ -1345,7 +1404,7 @@ This is the first proper release of the <code>community\.crypto</code> collectio
* openssl\_publickey \- allow to provide private key content via <code>private\_key\_content</code> option\.
* openssl\_publickey \- allow to return the existing/generated public key directly as <code>publickey</code> by setting <code>return\_content</code> to <code>yes</code>\.
-<a id="deprecated-features-8"></a>
+<a id="deprecated-features-9"></a>
### Deprecated Features
* openssl\_csr \- all values for the <code>version</code> option except <code>1</code> are deprecated\. The value 1 denotes the current only standardized CSR version\.
@@ -1355,7 +1414,7 @@ This is the first proper release of the <code>community\.crypto</code> collectio
* The <code>letsencrypt</code> module has been removed\. Use <code>acme\_certificate</code> instead\.
-<a id="bugfixes-43"></a>
+<a id="bugfixes-45"></a>
### Bugfixes
* ACME modules\: fix bug in ACME v1 account update code
@@ -1378,9 +1437,9 @@ This is the first proper release of the <code>community\.crypto</code> collectio
* openssl\_csr \- the module will now enforce that <code>privatekey\_path</code> is specified when <code>state\=present</code>\.
* openssl\_publickey \- fix a module crash caused when pyOpenSSL is not installed \([https\://github\.com/ansible/ansible/issues/67035](https\://github\.com/ansible/ansible/issues/67035)\)\.
-<a id="new-modules-5"></a>
+<a id="new-modules-6"></a>
### New Modules
-* ecs\_domain \- Request validation of a domain with the Entrust Certificate Services \(ECS\) API
-* x509\_crl \- Generate Certificate Revocation Lists \(CRLs\)
-* x509\_crl\_info \- Retrieve information on Certificate Revocation Lists \(CRLs\)
+* community\.crypto\.ecs\_domain \- Request validation of a domain with the Entrust Certificate Services \(ECS\) API
+* community\.crypto\.x509\_crl \- Generate Certificate Revocation Lists \(CRLs\)
+* community\.crypto\.x509\_crl\_info \- Retrieve information on Certificate Revocation Lists \(CRLs\)
diff --git a/ansible_collections/community/crypto/CHANGELOG.rst b/ansible_collections/community/crypto/CHANGELOG.rst
index b2dca8e3f..2ba4c8704 100644
--- a/ansible_collections/community/crypto/CHANGELOG.rst
+++ b/ansible_collections/community/crypto/CHANGELOG.rst
@@ -4,6 +4,56 @@ Community Crypto Release Notes
.. contents:: Topics
+v2.20.0
+=======
+
+Release Summary
+---------------
+
+Feature and bugfix release.
+
+The deprecations in this release are only relevant for collections that use shared
+code or docs fragments from this collection.
+
+Minor Changes
+-------------
+
+- acme_certificate - add ``include_renewal_cert_id`` option to allow requesting renewal of a specific certificate according to the current ACME Renewal Information specification draft (https://github.com/ansible-collections/community.crypto/pull/739).
+
+Deprecated Features
+-------------------
+
+- acme documentation fragment - the default ``community.crypto.acme[.documentation]`` docs fragment is deprecated and will be removed from community.crypto 3.0.0. Replace it with both the new ``community.crypto.acme.basic`` and ``community.crypto.acme.account`` fragments (https://github.com/ansible-collections/community.crypto/pull/735).
+- acme.backends module utils - the ``get_cert_information()`` method for a ACME crypto backend must be implemented from community.crypto 3.0.0 on (https://github.com/ansible-collections/community.crypto/pull/736).
+- crypto.module_backends.common module utils - the ``crypto.module_backends.common`` module utils is deprecated and will be removed from community.crypto 3.0.0. Use the improved ``argspec`` module util instead (https://github.com/ansible-collections/community.crypto/pull/749).
+
+Bugfixes
+--------
+
+- x509_crl, x509_certificate, x509_certificate_info - when parsing absolute timestamps which omitted the second count, the first digit of the minutes was used as a one-digit minutes count, and the second digit of the minutes as a one-digit second count (https://github.com/ansible-collections/community.crypto/pull/745).
+
+New Modules
+-----------
+
+- community.crypto.acme_ari_info - Retrieves ACME Renewal Information (ARI) for a certificate.
+- community.crypto.acme_certificate_deactivate_authz - Deactivate all authz for an ACME v2 order.
+- community.crypto.acme_certificate_renewal_info - Determine whether a certificate should be renewed or not.
+
+v2.19.1
+=======
+
+Release Summary
+---------------
+
+Bugfix release.
+
+Bugfixes
+--------
+
+- crypto.math module utils - change return values for ``quick_is_not_prime()`` and ``convert_int_to_bytes(0, 0)`` for special cases that do not appear when using the collection (https://github.com/ansible-collections/community.crypto/pull/733).
+- ecs_certificate - fixed ``csr`` option to be empty and allow renewal of a specific certificate according to the Renewal Information specification (https://github.com/ansible-collections/community.crypto/pull/740).
+- x509_certificate - since community.crypto 2.19.0 the module was no longer idempotent with respect to ``not_before`` and ``not_after`` times. This is now fixed (https://github.com/ansible-collections/community.crypto/issues/753, https://github.com/ansible-collections/community.crypto/pull/754).
+
v2.19.0
=======
@@ -31,7 +81,7 @@ Bugfixes
New Modules
-----------
-- x509_certificate_convert - Convert X.509 certificates
+- community.crypto.x509_certificate_convert - Convert X.509 certificates
v2.18.0
=======
@@ -64,8 +114,8 @@ New Plugins
Filter
~~~~~~
-- parse_serial - Convert a serial number as a colon-separated list of hex numbers to an integer
-- to_serial - Convert an integer to a colon-separated list of hex numbers
+- community.crypto.parse_serial - Convert a serial number as a colon-separated list of hex numbers to an integer
+- community.crypto.to_serial - Convert an integer to a colon-separated list of hex numbers
v2.17.1
=======
@@ -185,12 +235,12 @@ New Plugins
Filter
~~~~~~
-- gpg_fingerprint - Retrieve a GPG fingerprint from a GPG public or private key
+- community.crypto.gpg_fingerprint - Retrieve a GPG fingerprint from a GPG public or private key
Lookup
~~~~~~
-- gpg_fingerprint - Retrieve a GPG fingerprint from a GPG public or private key file
+- community.crypto.gpg_fingerprint - Retrieve a GPG fingerprint from a GPG public or private key file
v2.14.1
=======
@@ -333,12 +383,12 @@ New Plugins
Filter
~~~~~~
-- openssl_csr_info - Retrieve information from OpenSSL Certificate Signing Requests (CSR)
-- openssl_privatekey_info - Retrieve information from OpenSSL private keys
-- openssl_publickey_info - Retrieve information from OpenSSL public keys in PEM format
-- split_pem - Split PEM file contents into multiple objects
-- x509_certificate_info - Retrieve information from X.509 certificates in PEM format
-- x509_crl_info - Retrieve information from X.509 CRLs in PEM format
+- community.crypto.openssl_csr_info - Retrieve information from OpenSSL Certificate Signing Requests (CSR)
+- community.crypto.openssl_privatekey_info - Retrieve information from OpenSSL private keys
+- community.crypto.openssl_publickey_info - Retrieve information from OpenSSL public keys in PEM format
+- community.crypto.split_pem - Split PEM file contents into multiple objects
+- community.crypto.x509_certificate_info - Retrieve information from X.509 certificates in PEM format
+- community.crypto.x509_crl_info - Retrieve information from X.509 CRLs in PEM format
v2.9.0
======
@@ -637,8 +687,8 @@ Bugfixes
New Modules
-----------
-- crypto_info - Retrieve cryptographic capabilities
-- openssl_privatekey_convert - Convert OpenSSL private keys
+- community.crypto.crypto_info - Retrieve cryptographic capabilities
+- community.crypto.openssl_privatekey_convert - Convert OpenSSL private keys
v2.0.2
======
@@ -884,7 +934,7 @@ Bugfixes
New Modules
-----------
-- openssl_publickey_info - Provide information for OpenSSL public keys
+- community.crypto.openssl_publickey_info - Provide information for OpenSSL public keys
v1.6.2
======
@@ -1015,9 +1065,9 @@ Bugfixes
New Modules
-----------
-- openssl_csr_pipe - Generate OpenSSL Certificate Signing Request (CSR)
-- openssl_privatekey_pipe - Generate OpenSSL private keys without disk access
-- x509_certificate_pipe - Generate and/or check OpenSSL certificates
+- community.crypto.openssl_csr_pipe - Generate OpenSSL Certificate Signing Request (CSR)
+- community.crypto.openssl_privatekey_pipe - Generate OpenSSL private keys without disk access
+- community.crypto.x509_certificate_pipe - Generate and/or check OpenSSL certificates
v1.2.0
======
@@ -1093,8 +1143,8 @@ Bugfixes
New Modules
-----------
-- openssl_signature - Sign data with openssl
-- openssl_signature_info - Verify signatures with openssl
+- community.crypto.openssl_signature - Sign data with openssl
+- community.crypto.openssl_signature_info - Verify signatures with openssl
v1.0.0
======
@@ -1169,6 +1219,6 @@ Bugfixes
New Modules
-----------
-- ecs_domain - Request validation of a domain with the Entrust Certificate Services (ECS) API
-- x509_crl - Generate Certificate Revocation Lists (CRLs)
-- x509_crl_info - Retrieve information on Certificate Revocation Lists (CRLs)
+- community.crypto.ecs_domain - Request validation of a domain with the Entrust Certificate Services (ECS) API
+- community.crypto.x509_crl - Generate Certificate Revocation Lists (CRLs)
+- community.crypto.x509_crl_info - Retrieve information on Certificate Revocation Lists (CRLs)
diff --git a/ansible_collections/community/crypto/FILES.json b/ansible_collections/community/crypto/FILES.json
index e98f9499c..866c6794f 100644
--- a/ansible_collections/community/crypto/FILES.json
+++ b/ansible_collections/community/crypto/FILES.json
@@ -109,7 +109,7 @@
"name": ".azure-pipelines/azure-pipelines.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6e277188c1cbc0030cb55f73f6ebde233c77c66e2aa0d19476f9b7bae729d345",
+ "chksum_sha256": "76c14d937f8357d3124b959de775de59a0f2b6488d17b209d40bfe62217f579d",
"format": 1
},
{
@@ -130,7 +130,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4250c0cd843d1a134c3d806ef9030b55f9a1b949902d1a746ccd19edb9f51a95",
+ "chksum_sha256": "5fefc24aaf86bfa9ba76bbde513f7919a48a049bb05ee7f07a054adbc21d8d1b",
"format": 1
},
{
@@ -263,7 +263,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7dcaea3df82e79d7b11bb628e95889ccfb31077902d6ddaee8655a83f577b418",
+ "chksum_sha256": "feb7cda6ba4ab1719a468f5a61415bcc67ba5342f67063a5687dd1d367947db9",
"format": 1
},
{
@@ -277,7 +277,7 @@
"name": "changelogs/config.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "57d7548204ea1fd0b699f4cca0181e85a556bff89d5a35e52073d6dd44010b99",
+ "chksum_sha256": "3b2469377b8c18712f2566949b703be5a3b35ba07c336f060447313b9c44c58d",
"format": 1
},
{
@@ -368,7 +368,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "78f0817cd6a1f61ef403cff6f944799c473b2fe01fc618f8e4b94a996af77d75",
+ "chksum_sha256": "1a42d6a02d5627cd6b698fca894d464254b3fb3c99df0bc4880d20eefcc510f8",
"format": 1
},
{
@@ -403,7 +403,7 @@
"name": "plugins/doc_fragments/acme.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "72d44b4b7dc88ed9cedd76eec52a796b60da62283a14e68ad41e6adce69665f4",
+ "chksum_sha256": "0c59e90ff8eb2e5af6400a81d1f787dde63ceb400a37149e2c5224d9246883ce",
"format": 1
},
{
@@ -564,28 +564,28 @@
"name": "plugins/module_utils/acme/acme.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5d7f05fdab25dcbef2a8ce8d1edcd4c27fcc53c13c735a5c74e46aabc0098724",
+ "chksum_sha256": "8bb87a9023f0d079de2c496225a2e475177a98344a551d4c7e386313c3887277",
"format": 1
},
{
"name": "plugins/module_utils/acme/backend_cryptography.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5bccf4747fa4ef5853858db1683bfa4d31951fc1da78341c36063617eb4b2719",
+ "chksum_sha256": "67d1744bad142efd42898be008e4f2a94adfcd365b0ffe6f9066ea864e432fd5",
"format": 1
},
{
"name": "plugins/module_utils/acme/backend_openssl_cli.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7a722bedddbc63e4d6e66b10659f63531c2675e19740ccc3381b70f6ed3fdba4",
+ "chksum_sha256": "c2b87c74fc95a7e58689c912e715b2444774782c0690def4ef07790ef1385f9a",
"format": 1
},
{
"name": "plugins/module_utils/acme/backends.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e2c50aaec5b7404e7a8437d34f8246adcb6a7390dff505ce772d04b9a9530177",
+ "chksum_sha256": "aae3ba1f3e918957864d5773519e96f218b2af395a81d58b7760a525b175bb6d",
"format": 1
},
{
@@ -599,7 +599,7 @@
"name": "plugins/module_utils/acme/challenges.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f425838b07c8ec95b9ea9afe07e58f724c7ef5cb1a876e1dcfa9e4997d7f31ab",
+ "chksum_sha256": "87536afccc41f2138a433bf3c1247ea29a60b09c77b81f3e38cf4d1387492e3d",
"format": 1
},
{
@@ -620,14 +620,14 @@
"name": "plugins/module_utils/acme/orders.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bc139936871d65b9f4c0b0e5b772114eac5103bc291c4db907b650d0da63ea0d",
+ "chksum_sha256": "47a9091426fb8e0a1ac164aab8e38575360a9b5c101c8fcdb629e41072cb5ed1",
"format": 1
},
{
"name": "plugins/module_utils/acme/utils.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e4856fa1ff751214f8fabdb30c4813191e891b18c778439913fef72e5c421267",
+ "chksum_sha256": "fd81b1f8eaa63794b95d8909d9497af50578ac49b9e13d9408c7bf76cb1b81b4",
"format": 1
},
{
@@ -648,7 +648,7 @@
"name": "plugins/module_utils/crypto/module_backends/certificate.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c8858dddd2447413319f622af45c004f3b64eb6038e3e288454b76418d28d0f2",
+ "chksum_sha256": "1ac6dc3d2ed16216e8d4cb3dfffbcd83f85a92a1c357369c8ccb77dd40f5395e",
"format": 1
},
{
@@ -662,35 +662,35 @@
"name": "plugins/module_utils/crypto/module_backends/certificate_entrust.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "79486afc80b485e4c4c930b59f44c8320e5ece7eb63408bf5f5ac2bc66c3eeed",
+ "chksum_sha256": "117f7999f887c02e9d7c19657be67d169e6d1b2399d6cb3778a0e00ed1976b4a",
"format": 1
},
{
"name": "plugins/module_utils/crypto/module_backends/certificate_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cd9c993f1c224036eba267820de7e21cec8a06a138d943b776541be214f1d14f",
+ "chksum_sha256": "95c2b6df3f6e777c30ab1f24be70a384a1d60df2b4d2e9f6d2e4bd287178cf53",
"format": 1
},
{
"name": "plugins/module_utils/crypto/module_backends/certificate_ownca.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6c58c55efbdec1869fc10fe63785242aee81f2dc8fff03397de5b75303ed724d",
+ "chksum_sha256": "10c22ee5cf387d5b09e6d07b1e12f6eff324e34b2fcacdd929c96b84cafb4ea3",
"format": 1
},
{
"name": "plugins/module_utils/crypto/module_backends/certificate_selfsigned.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d46e3f53d82fe161efdc94f337126f66fcfb8e49647367c08a68ee2232ca6e8c",
+ "chksum_sha256": "0b4ee017b21abf3a7c2d5b65f34a2db09defa6b5725e3c5b19977672f03ee470",
"format": 1
},
{
"name": "plugins/module_utils/crypto/module_backends/common.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7624320b1ddd2c5661df4ace026ed0b29282125755951e13356dab6f8efba374",
+ "chksum_sha256": "3dce4b1ee5f50da338fe62a245f61e4725c8702a645299d433cf082b64b18135",
"format": 1
},
{
@@ -704,7 +704,7 @@
"name": "plugins/module_utils/crypto/module_backends/csr.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b3a7c30f3f7aaedb29f3e493fc6020c135cb0827c8e7bd53c49c68b3e97277da",
+ "chksum_sha256": "91d5019af08c4dda7e5d21611b9578d6a7bf35615f9f02335d732d2824ab6877",
"format": 1
},
{
@@ -718,14 +718,14 @@
"name": "plugins/module_utils/crypto/module_backends/privatekey.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "40ee4181c816995341ea4bd07d3de0d4c19b3d2076f7d6903fa15fc803543aff",
+ "chksum_sha256": "86051e9a9993ed441bfe364531071a202f5c60b44c45ce85026782bfd93c79bd",
"format": 1
},
{
"name": "plugins/module_utils/crypto/module_backends/privatekey_convert.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "90d164b2b338e8e15533df91394b5c8b9a425ee8d13812dbf5050e7d9b2d0388",
+ "chksum_sha256": "4d60f08fe8ee0d08a06641aef00f2ae31af22de034f4c13f3914b9b47e8193f3",
"format": 1
},
{
@@ -795,7 +795,7 @@
"name": "plugins/module_utils/crypto/math.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d91f76043cd78a1c9dec5d22a7775be984e5796efb78b30792042ac5a4ebbee8",
+ "chksum_sha256": "abc08963caaa5bf31d68049074b9f7199d53f207cc72cf0e9359178ae34b7ea9",
"format": 1
},
{
@@ -816,7 +816,7 @@
"name": "plugins/module_utils/crypto/support.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7d27f0bf007ccdb80a8d144381545f6406abad02396dbd39def186147a6efa91",
+ "chksum_sha256": "17a65c2c15ad982fb9efbbda36f39ed1d31dcb800cbff5e15cdc25f7d8b90acb",
"format": 1
},
{
@@ -879,7 +879,7 @@
"name": "plugins/module_utils/openssh/certificate.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2febea40e9db5c2f560a0e399603812f520b575b00cec33bfae2e536962d24c7",
+ "chksum_sha256": "982bf6955620eeb74f586ec90e561f5ee4fc0ae94e728a3c5c3d56cd698e18bb",
"format": 1
},
{
@@ -904,6 +904,13 @@
"format": 1
},
{
+ "name": "plugins/module_utils/argspec.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2bcda588b1ee3c1972389dd575d84c4c4d9d58ec29a6056f6dc69c57baaaed21",
+ "format": 1
+ },
+ {
"name": "plugins/module_utils/io.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -918,6 +925,13 @@
"format": 1
},
{
+ "name": "plugins/module_utils/time.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7f673b24a2e5e79b35857131b416ec519b661c084397d36970963cc6f3c08aad",
+ "format": 1
+ },
+ {
"name": "plugins/module_utils/version.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -935,42 +949,63 @@
"name": "plugins/modules/acme_account.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a9c3a88169fd7a7a8bfeedad92cace558ad6ec9aed11c641bd1f84a2382c9013",
+ "chksum_sha256": "99a0e35216a5b948f2023ed4f07198af7c76f4c09dc700dfd36be80804b908e7",
"format": 1
},
{
"name": "plugins/modules/acme_account_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7c83dcc40c140a22ec7131f77524aef58b07556c9268f2625741fc6a2c338b6c",
+ "chksum_sha256": "636a47fe3fe6bdf98fc464e72d95aff8d18fe5a37d95e4b733e820165ffae925",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/acme_ari_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "32425edb18282abb4161a369ec62d237ff1be803440f288e289fe36eb6041398",
"format": 1
},
{
"name": "plugins/modules/acme_certificate.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5f0f0039f146654c43e4a2a44e7be9becfc9a1d0566e11bef39ad591b472725d",
+ "chksum_sha256": "6d7f9006b87ab1c8b220668a7206cc223a72bfb992162b1d90c238dc8b148761",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/acme_certificate_deactivate_authz.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "09cf6f4fdd51244aade38600f6ed59c55640ee6652fe42705d19f4a29511328c",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/acme_certificate_renewal_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ec814b1f26e26701691f709f3abfc578f953e5200f554ce920d8673148cbedb6",
"format": 1
},
{
"name": "plugins/modules/acme_certificate_revoke.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "04f1b9f3dba82c5351a0ae1eae0c8360a6af3aad6e8df118d320271e3efb04c9",
+ "chksum_sha256": "a2d515f9a05cc38adb5e7817c991a7443582210c7843e9e7e2738864d16a18c2",
"format": 1
},
{
"name": "plugins/modules/acme_challenge_cert_helper.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8484e4dc9508cffab80145f63ebabf0e88e6d203a3e466f2c000ca3e465596cb",
+ "chksum_sha256": "b10d22bb7a15d7f70f8bfd82991a273d6fdcd08f02e9dd61cc84051d099468ba",
"format": 1
},
{
"name": "plugins/modules/acme_inspect.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "490494d06240823440e81a5539c91c52f7359fade12e9e19aa28f8dfc5f725da",
+ "chksum_sha256": "45be39256ee327763add7f5978cc9aeae485a4e23abcfbd86052b09b2e7eb179",
"format": 1
},
{
@@ -991,7 +1026,7 @@
"name": "plugins/modules/ecs_certificate.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0a5264350a46f4a5e7bf97a2b4bdf4d35391c4032dc8e3011ea6cdfe1a17e292",
+ "chksum_sha256": "3a81d2db16e086212b8ae6beee2300c3410649797fce664fe18174f6789bccee",
"format": 1
},
{
@@ -1005,7 +1040,7 @@
"name": "plugins/modules/get_certificate.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3ea3b665adf3bbc3c2dc8e92cf9efd6c7b273aec0c8f1ef29e6414b0a9c50dd9",
+ "chksum_sha256": "18a87dc709c74ab15fabf4ef66e1c7db408a997b7d3154373f2066064e9c72a2",
"format": 1
},
{
@@ -1138,7 +1173,7 @@
"name": "plugins/modules/x509_certificate_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e39c0d16a89cc7cac74d2c81e0406c9e5c1ebe8da0dd9c9c5ef9c26a78d5eae0",
+ "chksum_sha256": "806ee56458a3e0a54b2c8fdb0cb9ebe182f886dd9f8d93e55ae4af6e15f41cd0",
"format": 1
},
{
@@ -1152,7 +1187,7 @@
"name": "plugins/modules/x509_crl.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "eb2dfed3b7ec2739444923eb22812533901e9f6e7b6f19e127db7d34b3f6c6aa",
+ "chksum_sha256": "c19c2ab9d506103cb57b6b3f5473713b032e82074e2ff3f24cd7d562b61470b6",
"format": 1
},
{
@@ -1597,6 +1632,139 @@
"format": 1
},
{
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6f5821968427f3784e3f2ed2bf186dd0b0c198dabb3129c58aa1a5b5d487065d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/tasks/impl.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a3be6b0b0acfc57621d7fa623a290e0edcbf4671f3116b5c859b362e26d9df21",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c3f80b8fa9ebbd81fa9674493ba9bc538f90f23d0e44a0262e772804714e29ba",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/tests",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1b4b04590787e09f7621322d34e8dd36e2d2a7e7ec541ed89979fb8687e6ef2c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_deactivate_authz/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1846e9b081766a9ad0f4c13f42d014e82cd235f0cf8b1fd8d7eb41287c6a165f",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6f5821968427f3784e3f2ed2bf186dd0b0c198dabb3129c58aa1a5b5d487065d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/tasks/obtain-cert.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4ad45f93e26e6683cee0b57a66ddabe0147dd5d3af96fadc2209ab4d501b407a",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/tasks/impl.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "28f228dbb86eb0077126a9c05fa98f95e961698eba37efda6ba251ed8dac88b1",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c3f80b8fa9ebbd81fa9674493ba9bc538f90f23d0e44a0262e772804714e29ba",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/tests",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/tests/validate.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2a55b59480a69b659a2d208fdff116f6dbc09e9b7075e1dd11eee88eeeff476b",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/acme_certificate_renewal_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1846e9b081766a9ad0f4c13f42d014e82cd235f0cf8b1fd8d7eb41287c6a165f",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/acme_certificate_revoke",
"ftype": "dir",
"chksum_type": null,
@@ -1747,7 +1915,7 @@
"name": "tests/integration/targets/acme_inspect/tasks/impl.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d8366b412ff8b4002d339b97fb4b7b7ee9475120e0e6890a464c3701aeef45ac",
+ "chksum_sha256": "2caf144a1cce04ab28b5e5568c79ab571d362992eecb7f3cf629d81dc8ec234c",
"format": 1
},
{
@@ -4547,7 +4715,7 @@
"name": "tests/integration/targets/x509_certificate/tasks/ownca.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "318ebf03e19480212efdeb7a1643858fc5d7eb761c414c9de4d234f5fdc24232",
+ "chksum_sha256": "fb30c2c92d5264236bc6c0f41288487347c56d7cbc174e0f75e73ae5cc8013de",
"format": 1
},
{
@@ -4561,7 +4729,7 @@
"name": "tests/integration/targets/x509_certificate/tasks/selfsigned.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6b085441e03a22f8d7a87b902b0f17d17239982fe53d7522ef8b6ef2e68b8f41",
+ "chksum_sha256": "a9cf4be468603320f28ec7107cb54bd582ba4419b689941b6ec58d474d9995ae",
"format": 1
},
{
@@ -4575,14 +4743,14 @@
"name": "tests/integration/targets/x509_certificate/tests/validate_ownca.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "af825159e41199c2d1f1db026d1440dd6b84b14e6b684de12b76971812d10ec5",
+ "chksum_sha256": "cb548f9b1aadc89104d2b4c31b9151213b56006f0a43f1f63dab2c86a302f97e",
"format": 1
},
{
"name": "tests/integration/targets/x509_certificate/tests/validate_selfsigned.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fea7c0daa838f7449053a70b563857991d919c281980ca1d4323123b4ae39862",
+ "chksum_sha256": "f0dfd5f5011f3416fababc4c4685c4950d4c7567effd7769bd25d70692e601ad",
"format": 1
},
{
@@ -5132,6 +5300,62 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a14802e2b54e6c33073b0fcc8a208b1e4b0c9e0da26c39e3771430327e1c32b7",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt.license",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "aa565ba566a86a6c4fdfe3c12d2e816a5e7dd929d03e43025e02cd79c11fd373",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt.license",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eced04a43a5c76e168a808dd0739d36ff38973b7d94c210df622302efc5d003e",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem.license",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "15452d352f015272474d30ba1e1f2c3043d658cfc2628873833a1abe940153dc",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt.license",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/module_utils/acme/fixtures/csr_1.pem",
"ftype": "file",
"chksum_type": "sha256",
@@ -5233,21 +5457,21 @@
"name": "tests/unit/plugins/module_utils/acme/backend_data.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9b69baa0e28c3a4dc12e281c326a7f2280e2666fbbd3f51d8b34262b65640c52",
+ "chksum_sha256": "4b360ecd947ec58934ef86809c36a606ea84571a9f3cdc8924ab536d9b811925",
"format": 1
},
{
"name": "tests/unit/plugins/module_utils/acme/test_backend_cryptography.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fccabe7cb7879c3189d18a3057cd9768544c6c8f5d9416aac48687b59ee20de5",
+ "chksum_sha256": "d2c5a8487bb2ef25d9f735df6e37d0bb51afecf2bfe5e845f8e37b0a1b5db487",
"format": 1
},
{
"name": "tests/unit/plugins/module_utils/acme/test_backend_openssl_cli.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "810e5201c70b6e3bc1466d468c5fa822b7e8f5ed381f95de33b386b3a504cab4",
+ "chksum_sha256": "956ddae25c410ef809ace952a5d2457a68914a82065650d8f94d9abe5ce0b910",
"format": 1
},
{
@@ -5282,7 +5506,7 @@
"name": "tests/unit/plugins/module_utils/acme/test_utils.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3658a226ba4a966807e1b4b07b1afb25b38663e95fe2053909fb93eb3339d72e",
+ "chksum_sha256": "98a935f74f8d0f3a597b0a63de78854795ef22c340700c3c74f121a7d6a8edda",
"format": 1
},
{
@@ -5307,6 +5531,13 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/module_utils/crypto/test_math.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "451713c4ad9f0efc68073978274740e8abdcab922861ae69d8a55e034cbb4c46",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/module_utils/crypto/test_pem.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -5342,6 +5573,13 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/module_utils/test_time.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1546079502474355c20c41a193a338aa34512af2ba192067dbd303ed50b5d57a",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/modules",
"ftype": "dir",
"chksum_type": null,
@@ -5506,7 +5744,7 @@
"name": "CHANGELOG.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ca2c6e6efdcfdb7ee6ee1b3bbb095989678081d32fa9aca67b65f57e96a37026",
+ "chksum_sha256": "4aa8a179caafc747a16ed4a1e21627199d7d97fdce382e169af3b497872c74a9",
"format": 1
},
{
@@ -5520,7 +5758,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6ba9093a33e39e50b4a9436cbfdb36c2591a15c0aeadc8e7072b980df760ee6d",
+ "chksum_sha256": "d5b9954b1c1f6a83c292ced179112425246c2570642961d0056cc1fd3bb614c4",
"format": 1
},
{
@@ -5541,7 +5779,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "704b9171377cd1c819ac83f7603438188432dfc6296bb7c6bfa7291c85d3b8b6",
+ "chksum_sha256": "10d998a15b33191f0fbc4a3c8ef7eebc95ee59d5144025142834e50b608f6e73",
"format": 1
}
],
diff --git a/ansible_collections/community/crypto/MANIFEST.json b/ansible_collections/community/crypto/MANIFEST.json
index 40dbbd275..7ceac0b47 100644
--- a/ansible_collections/community/crypto/MANIFEST.json
+++ b/ansible_collections/community/crypto/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "crypto",
- "version": "2.19.0",
+ "version": "2.20.0",
"authors": [
"Ansible (github.com/ansible)"
],
@@ -41,7 +41,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b8a70c677576d6f7bda75b45d97af355a4f371b9269a791bdef8976361b39f75",
+ "chksum_sha256": "18d1adbc1789a8e0f32412b5f07fbecb376933288258b709f7a91ff4c951d56f",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/crypto/README.md b/ansible_collections/community/crypto/README.md
index 99c6a4f62..7e8136227 100644
--- a/ansible_collections/community/crypto/README.md
+++ b/ansible_collections/community/crypto/README.md
@@ -66,7 +66,9 @@ If you use the Ansible package and do not update collections independently, use
- ACME modules and plugins:
- acme_account_info module
- acme_account module
+ - acme_ari_info module
- acme_certificate module
+ - acme_certificate_deactivate_authz module
- acme_certificate_revoke module
- acme_challenge_cert_helper module
- acme_inspect module
diff --git a/ansible_collections/community/crypto/changelogs/changelog.yaml b/ansible_collections/community/crypto/changelogs/changelog.yaml
index 856a965ec..13eba21e1 100644
--- a/ansible_collections/community/crypto/changelogs/changelog.yaml
+++ b/ansible_collections/community/crypto/changelogs/changelog.yaml
@@ -1079,6 +1079,25 @@ releases:
name: x509_certificate_convert
namespace: ''
release_date: '2024-04-20'
+ 2.19.1:
+ changes:
+ bugfixes:
+ - crypto.math module utils - change return values for ``quick_is_not_prime()``
+ and ``convert_int_to_bytes(0, 0)`` for special cases that do not appear when
+ using the collection (https://github.com/ansible-collections/community.crypto/pull/733).
+ - ecs_certificate - fixed ``csr`` option to be empty and allow renewal of a
+ specific certificate according to the Renewal Information specification (https://github.com/ansible-collections/community.crypto/pull/740).
+ - x509_certificate - since community.crypto 2.19.0 the module was no longer
+ idempotent with respect to ``not_before`` and ``not_after`` times. This is
+ now fixed (https://github.com/ansible-collections/community.crypto/issues/753,
+ https://github.com/ansible-collections/community.crypto/pull/754).
+ release_summary: Bugfix release.
+ fragments:
+ - 2.19.1.yml
+ - 733-math-prime.yml
+ - 740-ecs_certificate-renewal-without-csr.yml
+ - 754-x509_certificate-time.yml
+ release_date: '2024-05-11'
2.2.0:
changes:
bugfixes:
@@ -1153,6 +1172,54 @@ releases:
- 2.2.4.yml
- 417-openssh_modules-fix-exception-reporting.yml
release_date: '2022-03-22'
+ 2.20.0:
+ changes:
+ bugfixes:
+ - x509_crl, x509_certificate, x509_certificate_info - when parsing absolute
+ timestamps which omitted the second count, the first digit of the minutes
+ was used as a one-digit minutes count, and the second digit of the minutes
+ as a one-digit second count (https://github.com/ansible-collections/community.crypto/pull/745).
+ deprecated_features:
+ - acme documentation fragment - the default ``community.crypto.acme[.documentation]``
+ docs fragment is deprecated and will be removed from community.crypto 3.0.0.
+ Replace it with both the new ``community.crypto.acme.basic`` and ``community.crypto.acme.account``
+ fragments (https://github.com/ansible-collections/community.crypto/pull/735).
+ - acme.backends module utils - the ``get_cert_information()`` method for a ACME
+ crypto backend must be implemented from community.crypto 3.0.0 on (https://github.com/ansible-collections/community.crypto/pull/736).
+ - crypto.module_backends.common module utils - the ``crypto.module_backends.common``
+ module utils is deprecated and will be removed from community.crypto 3.0.0.
+ Use the improved ``argspec`` module util instead (https://github.com/ansible-collections/community.crypto/pull/749).
+ minor_changes:
+ - acme_certificate - add ``include_renewal_cert_id`` option to allow requesting
+ renewal of a specific certificate according to the current ACME Renewal Information
+ specification draft (https://github.com/ansible-collections/community.crypto/pull/739).
+ release_summary: 'Feature and bugfix release.
+
+
+ The deprecations in this release are only relevant for collections that use
+ shared
+
+ code or docs fragments from this collection.
+
+ '
+ fragments:
+ - 2.20.0.yml
+ - 735-acme-docs-fragment.yml
+ - 736-cert-info.yml
+ - 739-acme_certificate-include_renewal_cert_id.yml
+ - 745-absolute-time.yml
+ - 749-argspec.yml
+ modules:
+ - description: Retrieves ACME Renewal Information (ARI) for a certificate.
+ name: acme_ari_info
+ namespace: ''
+ - description: Deactivate all authz for an ACME v2 order.
+ name: acme_certificate_deactivate_authz
+ namespace: ''
+ - description: Determine whether a certificate should be renewed or not.
+ name: acme_certificate_renewal_info
+ namespace: ''
+ release_date: '2024-05-20'
2.3.0:
changes:
bugfixes:
diff --git a/ansible_collections/community/crypto/changelogs/config.yaml b/ansible_collections/community/crypto/changelogs/config.yaml
index 93ceb6472..c4cf310cf 100644
--- a/ansible_collections/community/crypto/changelogs/config.yaml
+++ b/ansible_collections/community/crypto/changelogs/config.yaml
@@ -34,3 +34,6 @@ sections:
- - known_issues
- Known Issues
title: Community Crypto
+trivial_section_name: trivial
+use_fqcn: true
+add_plugin_period: true
diff --git a/ansible_collections/community/crypto/meta/runtime.yml b/ansible_collections/community/crypto/meta/runtime.yml
index 76500748c..9c7592dc7 100644
--- a/ansible_collections/community/crypto/meta/runtime.yml
+++ b/ansible_collections/community/crypto/meta/runtime.yml
@@ -8,6 +8,7 @@ requires_ansible: '>=2.9.10'
action_groups:
acme:
- acme_inspect
+ - acme_certificate_deactivate_authz
- acme_certificate_revoke
- acme_certificate
- acme_account
diff --git a/ansible_collections/community/crypto/plugins/doc_fragments/acme.py b/ansible_collections/community/crypto/plugins/doc_fragments/acme.py
index 2b5bfc231..e5ee3ec4e 100644
--- a/ansible_collections/community/crypto/plugins/doc_fragments/acme.py
+++ b/ansible_collections/community/crypto/plugins/doc_fragments/acme.py
@@ -11,6 +11,9 @@ __metaclass__ = type
class ModuleDocFragment(object):
# Standard files documentation fragment
+ #
+ # NOTE: This document fragment is DEPRECATED and will be removed from community.crypto 3.0.0.
+ # Use both the BASIC and ACCOUNT fragments as a replacement.
DOCUMENTATION = r'''
notes:
- "If a new enough version of the C(cryptography) library
@@ -137,3 +140,178 @@ options:
default: 10
version_added: 2.3.0
'''
+
+ # Basic documentation fragment without account data
+ BASIC = r'''
+notes:
+ - "Although the defaults are chosen so that the module can be used with
+ the L(Let's Encrypt,https://letsencrypt.org/) CA, the module can in
+ principle be used with any CA providing an ACME endpoint, such as
+ L(Buypass Go SSL,https://www.buypass.com/ssl/products/acme)."
+ - "So far, the ACME modules have only been tested by the developers against
+ Let's Encrypt (staging and production), Buypass (staging and production), ZeroSSL (production),
+ and L(Pebble testing server,https://github.com/letsencrypt/Pebble). We have got
+ community feedback that they also work with Sectigo ACME Service for InCommon.
+ If you experience problems with another ACME server, please
+ L(create an issue,https://github.com/ansible-collections/community.crypto/issues/new/choose)
+ to help us supporting it. Feedback that an ACME server not mentioned does work
+ is also appreciated."
+requirements:
+ - either openssl or L(cryptography,https://cryptography.io/) >= 1.5
+ - ipaddress
+options:
+ acme_version:
+ description:
+ - "The ACME version of the endpoint."
+ - "Must be V(1) for the classic Let's Encrypt and Buypass ACME endpoints,
+ or V(2) for standardized ACME v2 endpoints."
+ - "The value V(1) is deprecated since community.crypto 2.0.0 and will be
+ removed from community.crypto 3.0.0."
+ required: true
+ type: int
+ choices: [ 1, 2 ]
+ acme_directory:
+ description:
+ - "The ACME directory to use. This is the entry point URL to access
+ the ACME CA server API."
+ - "For safety reasons the default is set to the Let's Encrypt staging
+ server (for the ACME v1 protocol). This will create technically correct,
+ but untrusted certificates."
+ - "For Let's Encrypt, all staging endpoints can be found here:
+ U(https://letsencrypt.org/docs/staging-environment/). For Buypass, all
+ endpoints can be found here:
+ U(https://community.buypass.com/t/63d4ay/buypass-go-ssl-endpoints)"
+ - "For B(Let's Encrypt), the production directory URL for ACME v2 is
+ U(https://acme-v02.api.letsencrypt.org/directory)."
+ - "For B(Buypass), the production directory URL for ACME v2 and v1 is
+ U(https://api.buypass.com/acme/directory)."
+ - "For B(ZeroSSL), the production directory URL for ACME v2 is
+ U(https://acme.zerossl.com/v2/DV90)."
+ - "For B(Sectigo), the production directory URL for ACME v2 is
+ U(https://acme-qa.secure.trust-provider.com/v2/DV)."
+ - The notes for this module contain a list of ACME services this module has
+ been tested against.
+ required: true
+ type: str
+ validate_certs:
+ description:
+ - Whether calls to the ACME directory will validate TLS certificates.
+ - "B(Warning:) Should B(only ever) be set to V(false) for testing purposes,
+ for example when testing against a local Pebble server."
+ type: bool
+ default: true
+ select_crypto_backend:
+ description:
+ - Determines which crypto backend to use.
+ - The default choice is V(auto), which tries to use C(cryptography) if available, and falls back to
+ C(openssl).
+ - If set to V(openssl), will try to use the C(openssl) binary.
+ - If set to V(cryptography), will try to use the
+ L(cryptography,https://cryptography.io/) library.
+ type: str
+ default: auto
+ choices: [ auto, cryptography, openssl ]
+ request_timeout:
+ description:
+ - The time Ansible should wait for a response from the ACME API.
+ - This timeout is applied to all HTTP(S) requests (HEAD, GET, POST).
+ type: int
+ default: 10
+ version_added: 2.3.0
+'''
+
+ # Account data documentation fragment
+ ACCOUNT = r'''
+notes:
+ - "If a new enough version of the C(cryptography) library
+ is available (see Requirements for details), it will be used
+ instead of the C(openssl) binary. This can be explicitly disabled
+ or enabled with the O(select_crypto_backend) option. Note that using
+ the C(openssl) binary will be slower and less secure, as private key
+ contents always have to be stored on disk (see
+ O(account_key_content))."
+options:
+ account_key_src:
+ description:
+ - "Path to a file containing the ACME account RSA or Elliptic Curve
+ key."
+ - "Private keys can be created with the
+ M(community.crypto.openssl_privatekey) or M(community.crypto.openssl_privatekey_pipe)
+ modules. If the requisite (cryptography) is not available,
+ keys can also be created directly with the C(openssl) command line tool:
+ RSA keys can be created with C(openssl genrsa ...). Elliptic curve keys
+ can be created with C(openssl ecparam -genkey ...). Any other tool creating
+ private keys in PEM format can be used as well."
+ - "Mutually exclusive with O(account_key_content)."
+ - "Required if O(account_key_content) is not used."
+ type: path
+ aliases: [ account_key ]
+ account_key_content:
+ description:
+ - "Content of the ACME account RSA or Elliptic Curve key."
+ - "Mutually exclusive with O(account_key_src)."
+ - "Required if O(account_key_src) is not used."
+ - "B(Warning:) the content will be written into a temporary file, which will
+ be deleted by Ansible when the module completes. Since this is an
+ important private key — it can be used to change the account key,
+ or to revoke your certificates without knowing their private keys
+ —, this might not be acceptable."
+ - "In case C(cryptography) is used, the content is not written into a
+ temporary file. It can still happen that it is written to disk by
+ Ansible in the process of moving the module with its argument to
+ the node where it is executed."
+ type: str
+ account_key_passphrase:
+ description:
+ - Phassphrase to use to decode the account key.
+ - "B(Note:) this is not supported by the C(openssl) backend, only by the C(cryptography) backend."
+ type: str
+ version_added: 1.6.0
+ account_uri:
+ description:
+ - "If specified, assumes that the account URI is as given. If the
+ account key does not match this account, or an account with this
+ URI does not exist, the module fails."
+ type: str
+'''
+
+ # No account data documentation fragment
+ NO_ACCOUNT = r'''
+notes:
+ - "If a new enough version of the C(cryptography) library
+ is available (see Requirements for details), it will be used
+ instead of the C(openssl) binary. This can be explicitly disabled
+ or enabled with the O(select_crypto_backend) option. Note that using
+ the C(openssl) binary will be slower."
+options: {}
+'''
+
+ CERTIFICATE = r'''
+options:
+ csr:
+ description:
+ - "File containing the CSR for the new certificate."
+ - "Can be created with M(community.crypto.openssl_csr)."
+ - "The CSR may contain multiple Subject Alternate Names, but each one
+ will lead to an individual challenge that must be fulfilled for the
+ CSR to be signed."
+ - "B(Note): the private key used to create the CSR B(must not) be the
+ account key. This is a bad idea from a security point of view, and
+ the CA should not accept the CSR. The ACME server should return an
+ error in this case."
+ - Precisely one of O(csr) or O(csr_content) must be specified.
+ type: path
+ csr_content:
+ description:
+ - "Content of the CSR for the new certificate."
+ - "Can be created with M(community.crypto.openssl_csr_pipe)."
+ - "The CSR may contain multiple Subject Alternate Names, but each one
+ will lead to an individual challenge that must be fulfilled for the
+ CSR to be signed."
+ - "B(Note): the private key used to create the CSR B(must not) be the
+ account key. This is a bad idea from a security point of view, and
+ the CA should not accept the CSR. The ACME server should return an
+ error in this case."
+ - Precisely one of O(csr) or O(csr_content) must be specified.
+ type: str
+'''
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/acme.py b/ansible_collections/community/crypto/plugins/module_utils/acme/acme.py
index 74d0bc1ea..7f9b954c0 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/acme.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/acme.py
@@ -21,6 +21,8 @@ from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six import PY3
+from ansible_collections.community.crypto.plugins.module_utils.argspec import ArgumentSpec
+
from ansible_collections.community.crypto.plugins.module_utils.acme.backend_openssl_cli import (
OpenSSLCLIBackend,
)
@@ -42,7 +44,9 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.errors impor
)
from ansible_collections.community.crypto.plugins.module_utils.acme.utils import (
+ compute_cert_id,
nopad_b64,
+ parse_retry_after,
)
try:
@@ -153,6 +157,9 @@ class ACMEDirectory(object):
self.module, msg='Was not able to obtain nonce, giving up after 5 retries', info=info, response=response)
retry_count += 1
+ def has_renewal_info_endpoint(self):
+ return 'renewalInfo' in self.directory
+
class ACMEClient(object):
'''
@@ -168,9 +175,9 @@ class ACMEClient(object):
self.backend = backend
self.version = module.params['acme_version']
# account_key path and content are mutually exclusive
- self.account_key_file = module.params['account_key_src']
- self.account_key_content = module.params['account_key_content']
- self.account_key_passphrase = module.params['account_key_passphrase']
+ self.account_key_file = module.params.get('account_key_src')
+ self.account_key_content = module.params.get('account_key_content')
+ self.account_key_passphrase = module.params.get('account_key_passphrase')
# Grab account URI from module parameters.
# Make sure empty string is treated as None.
@@ -383,24 +390,94 @@ class ACMEClient(object):
self.module, msg=error_msg, info=info, content=content, content_json=result if parsed_json_result else None)
return result, info
+ def get_renewal_info(
+ self,
+ cert_id=None,
+ cert_info=None,
+ cert_filename=None,
+ cert_content=None,
+ include_retry_after=False,
+ retry_after_relative_with_timezone=True,
+ ):
+ if not self.directory.has_renewal_info_endpoint():
+ raise ModuleFailException('The ACME endpoint does not support ACME Renewal Information retrieval')
+
+ if cert_id is None:
+ cert_id = compute_cert_id(self.backend, cert_info=cert_info, cert_filename=cert_filename, cert_content=cert_content)
+ url = '{base}{cert_id}'.format(base=self.directory.directory['renewalInfo'], cert_id=cert_id)
+
+ data, info = self.get_request(url, parse_json_result=True, fail_on_error=True, get_only=True)
+
+ # Include Retry-After header if asked for
+ if include_retry_after and 'retry-after' in info:
+ try:
+ data['retryAfter'] = parse_retry_after(
+ info['retry-after'],
+ relative_with_timezone=retry_after_relative_with_timezone,
+ )
+ except ValueError:
+ pass
+ return data
+
def get_default_argspec():
'''
Provides default argument spec for the options documented in the acme doc fragment.
+
+ DEPRECATED: will be removed in community.crypto 3.0.0
'''
return dict(
- account_key_src=dict(type='path', aliases=['account_key']),
- account_key_content=dict(type='str', no_log=True),
- account_key_passphrase=dict(type='str', no_log=True),
- account_uri=dict(type='str'),
acme_directory=dict(type='str', required=True),
acme_version=dict(type='int', required=True, choices=[1, 2]),
validate_certs=dict(type='bool', default=True),
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']),
request_timeout=dict(type='int', default=10),
+ account_key_src=dict(type='path', aliases=['account_key']),
+ account_key_content=dict(type='str', no_log=True),
+ account_key_passphrase=dict(type='str', no_log=True),
+ account_uri=dict(type='str'),
)
+def create_default_argspec(
+ with_account=True,
+ require_account_key=True,
+ with_certificate=False,
+):
+ '''
+ Provides default argument spec for the options documented in the acme doc fragment.
+ '''
+ result = ArgumentSpec(
+ argument_spec=dict(
+ acme_directory=dict(type='str', required=True),
+ acme_version=dict(type='int', required=True, choices=[1, 2]),
+ validate_certs=dict(type='bool', default=True),
+ select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'openssl', 'cryptography']),
+ request_timeout=dict(type='int', default=10),
+ ),
+ )
+ if with_account:
+ result.update_argspec(
+ account_key_src=dict(type='path', aliases=['account_key']),
+ account_key_content=dict(type='str', no_log=True),
+ account_key_passphrase=dict(type='str', no_log=True),
+ account_uri=dict(type='str'),
+ )
+ if require_account_key:
+ result.update(required_one_of=[['account_key_src', 'account_key_content']])
+ result.update(mutually_exclusive=[['account_key_src', 'account_key_content']])
+ if with_certificate:
+ result.update_argspec(
+ csr=dict(type='path'),
+ csr_content=dict(type='str'),
+ )
+ result.update(
+ required_one_of=[['csr', 'csr_content']],
+ mutually_exclusive=[['csr', 'csr_content']],
+ )
+ return result
+
+
def create_backend(module, needs_acme_v2):
if not HAS_IPADDRESS:
module.fail_json(msg=missing_required_lib('ipaddress'), exception=IPADDRESS_IMPORT_ERROR)
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/backend_cryptography.py b/ansible_collections/community/crypto/plugins/module_utils/acme/backend_cryptography.py
index 0722c1f99..b652240dc 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/backend_cryptography.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/backend_cryptography.py
@@ -11,6 +11,7 @@ __metaclass__ = type
import base64
import binascii
+import datetime
import os
import traceback
@@ -19,7 +20,9 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
from ansible_collections.community.crypto.plugins.module_utils.acme.backends import (
+ CertificateInformation,
CryptoBackend,
+ _parse_acme_timestamp,
)
from ansible_collections.community.crypto.plugins.module_utils.acme.certificates import (
@@ -35,27 +38,40 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.io import re
from ansible_collections.community.crypto.plugins.module_utils.acme.utils import nopad_b64
+from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
+ OpenSSLObjectError,
+)
+
from ansible_collections.community.crypto.plugins.module_utils.crypto.math import (
convert_int_to_bytes,
convert_int_to_hex,
)
-from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
- get_now_datetime,
- ensure_utc_timezone,
- parse_name_field,
-)
-
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
cryptography_name_to_oid,
+ cryptography_serial_number_of_cert,
get_not_valid_after,
+ get_not_valid_before,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
extract_first_pem,
)
+from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
+ parse_name_field,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ ensure_utc_timezone,
+ from_epoch_seconds,
+ get_epoch_seconds,
+ get_now_datetime,
+ get_relative_time_option,
+ UTC,
+)
+
CRYPTOGRAPHY_MINIMAL_VERSION = '1.5'
CRYPTOGRAPHY_ERROR = None
@@ -170,6 +186,32 @@ class CryptographyBackend(CryptoBackend):
def __init__(self, module):
super(CryptographyBackend, self).__init__(module)
+ def get_now(self):
+ return get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE)
+
+ def parse_acme_timestamp(self, timestamp_str):
+ return _parse_acme_timestamp(timestamp_str, with_timezone=CRYPTOGRAPHY_TIMEZONE)
+
+ def parse_module_parameter(self, value, name):
+ try:
+ return get_relative_time_option(value, name, backend='cryptography', with_timezone=CRYPTOGRAPHY_TIMEZONE)
+ except OpenSSLObjectError as exc:
+ raise BackendException(to_native(exc))
+
+ def interpolate_timestamp(self, timestamp_start, timestamp_end, percentage):
+ start = get_epoch_seconds(timestamp_start)
+ end = get_epoch_seconds(timestamp_end)
+ return from_epoch_seconds(start + percentage * (end - start), with_timezone=CRYPTOGRAPHY_TIMEZONE)
+
+ def get_utc_datetime(self, *args, **kwargs):
+ kwargs_ext = dict(kwargs)
+ if CRYPTOGRAPHY_TIMEZONE and ('tzinfo' not in kwargs_ext and len(args) < 8):
+ kwargs_ext['tzinfo'] = UTC
+ result = datetime.datetime(*args, **kwargs_ext)
+ if CRYPTOGRAPHY_TIMEZONE and ('tzinfo' in kwargs or len(args) >= 8):
+ result = ensure_utc_timezone(result)
+ return result
+
def parse_key(self, key_file=None, key_content=None, passphrase=None):
'''
Parses an RSA or Elliptic Curve key file in PEM format and returns key_data.
@@ -376,7 +418,7 @@ class CryptographyBackend(CryptoBackend):
raise BackendException('Cannot parse certificate {0}: {1}'.format(cert_filename, e))
if now is None:
- now = get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE)
+ now = self.get_now()
elif CRYPTOGRAPHY_TIMEZONE:
now = ensure_utc_timezone(now)
return (get_not_valid_after(cert) - now).days
@@ -386,3 +428,44 @@ class CryptographyBackend(CryptoBackend):
Given a Criterium object, creates a ChainMatcher object.
'''
return CryptographyChainMatcher(criterium, self.module)
+
+ def get_cert_information(self, cert_filename=None, cert_content=None):
+ '''
+ Return some information on a X.509 certificate as a CertificateInformation object.
+ '''
+ if cert_filename is not None:
+ cert_content = read_file(cert_filename)
+ else:
+ cert_content = to_bytes(cert_content)
+
+ # Make sure we have at most one PEM. Otherwise cryptography 36.0.0 will barf.
+ cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or '')
+
+ try:
+ cert = cryptography.x509.load_pem_x509_certificate(cert_content, _cryptography_backend)
+ except Exception as e:
+ if cert_filename is None:
+ raise BackendException('Cannot parse certificate: {0}'.format(e))
+ raise BackendException('Cannot parse certificate {0}: {1}'.format(cert_filename, e))
+
+ ski = None
+ try:
+ ext = cert.extensions.get_extension_for_class(cryptography.x509.SubjectKeyIdentifier)
+ ski = ext.value.digest
+ except cryptography.x509.ExtensionNotFound:
+ pass
+
+ aki = None
+ try:
+ ext = cert.extensions.get_extension_for_class(cryptography.x509.AuthorityKeyIdentifier)
+ aki = ext.value.key_identifier
+ except cryptography.x509.ExtensionNotFound:
+ pass
+
+ return CertificateInformation(
+ not_valid_after=get_not_valid_after(cert),
+ not_valid_before=get_not_valid_before(cert),
+ serial_number=cryptography_serial_number_of_cert(cert),
+ subject_key_identifier=ski,
+ authority_key_identifier=aki,
+ )
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/backend_openssl_cli.py b/ansible_collections/community/crypto/plugins/module_utils/acme/backend_openssl_cli.py
index 9a1ed1f5a..9aab187ac 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/backend_openssl_cli.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/backend_openssl_cli.py
@@ -20,6 +20,7 @@ import traceback
from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
from ansible_collections.community.crypto.plugins.module_utils.acme.backends import (
+ CertificateInformation,
CryptoBackend,
)
@@ -30,6 +31,8 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.errors impor
from ansible_collections.community.crypto.plugins.module_utils.acme.utils import nopad_b64
+from ansible_collections.community.crypto.plugins.module_utils.crypto.math import convert_bytes_to_int
+
try:
import ipaddress
except ImportError:
@@ -39,6 +42,33 @@ except ImportError:
_OPENSSL_ENVIRONMENT_UPDATE = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C', LC_CTYPE='C')
+def _extract_date(out_text, name, cert_filename_suffix=""):
+ try:
+ date_str = re.search(r"\s+%s\s*:\s+(.*)" % name, out_text).group(1)
+ return datetime.datetime.strptime(date_str, '%b %d %H:%M:%S %Y %Z')
+ except AttributeError:
+ raise BackendException("No '{0}' date found{1}".format(name, cert_filename_suffix))
+ except ValueError as exc:
+ raise BackendException("Failed to parse '{0}' date{1}: {2}".format(name, cert_filename_suffix, exc))
+
+
+def _decode_octets(octets_text):
+ return binascii.unhexlify(re.sub(r"(\s|:)", "", octets_text).encode("utf-8"))
+
+
+def _extract_octets(out_text, name, required=True, potential_prefixes=None):
+ regexp = r"\s+%s:\s*\n\s+%s([A-Fa-f0-9]{2}(?::[A-Fa-f0-9]{2})*)\s*\n" % (
+ name,
+ ('(?:%s)' % '|'.join(re.escape(pp) for pp in potential_prefixes)) if potential_prefixes else '',
+ )
+ match = re.search(regexp, out_text, re.MULTILINE | re.DOTALL)
+ if match is not None:
+ return _decode_octets(match.group(1))
+ if not required:
+ return None
+ raise BackendException("No '{0}' octet string found".format(name))
+
+
class OpenSSLCLIBackend(CryptoBackend):
def __init__(self, module, openssl_binary=None):
super(OpenSSLCLIBackend, self).__init__(module)
@@ -89,10 +119,12 @@ class OpenSSLCLIBackend(CryptoBackend):
dummy, out, dummy = self.module.run_command(
openssl_keydump_cmd, check_rc=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
+ out_text = to_text(out, errors='surrogate_or_strict')
+
if account_key_type == 'rsa':
- pub_hex, pub_exp = re.search(
- r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)",
- to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL).groups()
+ pub_hex = re.search(r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent", out_text, re.MULTILINE | re.DOTALL).group(1)
+
+ pub_exp = re.search(r"\npublicExponent: ([0-9]+)", out_text, re.MULTILINE | re.DOTALL).group(1)
pub_exp = "{0:x}".format(int(pub_exp))
if len(pub_exp) % 2:
pub_exp = "0{0}".format(pub_exp)
@@ -104,17 +136,19 @@ class OpenSSLCLIBackend(CryptoBackend):
'jwk': {
"kty": "RSA",
"e": nopad_b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
- "n": nopad_b64(binascii.unhexlify(re.sub(r"(\s|:)", "", pub_hex).encode("utf-8"))),
+ "n": nopad_b64(_decode_octets(pub_hex)),
},
'hash': 'sha256',
}
elif account_key_type == 'ec':
pub_data = re.search(
r"pub:\s*\n\s+04:([a-f0-9\:\s]+?)\nASN1 OID: (\S+)(?:\nNIST CURVE: (\S+))?",
- to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL)
+ out_text,
+ re.MULTILINE | re.DOTALL,
+ )
if pub_data is None:
raise KeyParsingError('cannot parse elliptic curve key')
- pub_hex = binascii.unhexlify(re.sub(r"(\s|:)", "", pub_data.group(1)).encode("utf-8"))
+ pub_hex = _decode_octets(pub_data.group(1))
asn1_oid_curve = pub_data.group(2).lower()
nist_curve = pub_data.group(3).lower() if pub_data.group(3) else None
if asn1_oid_curve == 'prime256v1' or nist_curve == 'p-256':
@@ -303,13 +337,8 @@ class OpenSSLCLIBackend(CryptoBackend):
openssl_cert_cmd = [self.openssl_binary, "x509", "-in", filename, "-noout", "-text"]
dummy, out, dummy = self.module.run_command(
openssl_cert_cmd, data=data, check_rc=True, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
- try:
- not_after_str = re.search(r"\s+Not After\s*:\s+(.*)", to_text(out, errors='surrogate_or_strict')).group(1)
- not_after = datetime.datetime.strptime(not_after_str, '%b %d %H:%M:%S %Y %Z')
- except AttributeError:
- raise BackendException("No 'Not after' date found{0}".format(cert_filename_suffix))
- except ValueError:
- raise BackendException("Failed to parse 'Not after' date{0}".format(cert_filename_suffix))
+ out_text = to_text(out, errors='surrogate_or_strict')
+ not_after = _extract_date(out_text, 'Not After', cert_filename_suffix=cert_filename_suffix)
if now is None:
now = datetime.datetime.now()
return (not_after - now).days
@@ -319,3 +348,43 @@ class OpenSSLCLIBackend(CryptoBackend):
Given a Criterium object, creates a ChainMatcher object.
'''
raise BackendException('Alternate chain matching can only be used with the "cryptography" backend.')
+
+ def get_cert_information(self, cert_filename=None, cert_content=None):
+ '''
+ Return some information on a X.509 certificate as a CertificateInformation object.
+ '''
+ filename = cert_filename
+ data = None
+ if cert_filename is not None:
+ cert_filename_suffix = ' in {0}'.format(cert_filename)
+ else:
+ filename = '/dev/stdin'
+ data = to_bytes(cert_content)
+ cert_filename_suffix = ''
+
+ openssl_cert_cmd = [self.openssl_binary, "x509", "-in", filename, "-noout", "-text"]
+ dummy, out, dummy = self.module.run_command(
+ openssl_cert_cmd, data=data, check_rc=True, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
+ out_text = to_text(out, errors='surrogate_or_strict')
+
+ not_after = _extract_date(out_text, 'Not After', cert_filename_suffix=cert_filename_suffix)
+ not_before = _extract_date(out_text, 'Not Before', cert_filename_suffix=cert_filename_suffix)
+
+ sn = re.search(
+ r" Serial Number: ([0-9]+)",
+ to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL)
+ if sn:
+ serial = int(sn.group(1))
+ else:
+ serial = convert_bytes_to_int(_extract_octets(out_text, 'Serial Number', required=True))
+
+ ski = _extract_octets(out_text, 'X509v3 Subject Key Identifier', required=False)
+ aki = _extract_octets(out_text, 'X509v3 Authority Key Identifier', required=False, potential_prefixes=['keyid:', ''])
+
+ return CertificateInformation(
+ not_valid_after=not_after,
+ not_valid_before=not_before,
+ serial_number=serial,
+ subject_key_identifier=ski,
+ authority_key_identifier=aki,
+ )
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/backends.py b/ansible_collections/community/crypto/plugins/module_utils/acme/backends.py
index 2d95a3ee3..7c08fae95 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/backends.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/backends.py
@@ -9,9 +9,78 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
+from collections import namedtuple
import abc
+import datetime
+import re
from ansible.module_utils import six
+from ansible.module_utils.common.text.converters import to_native
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.errors import (
+ BackendException,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
+ OpenSSLObjectError,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ ensure_utc_timezone,
+ from_epoch_seconds,
+ get_epoch_seconds,
+ get_now_datetime,
+ get_relative_time_option,
+ remove_timezone,
+)
+
+
+CertificateInformation = namedtuple(
+ 'CertificateInformation',
+ (
+ 'not_valid_after',
+ 'not_valid_before',
+ 'serial_number',
+ 'subject_key_identifier',
+ 'authority_key_identifier',
+ ),
+)
+
+
+_FRACTIONAL_MATCHER = re.compile(r'^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(|\.\d+)(Z|[+-]\d{2}:?\d{2}.*)$')
+
+
+def _reduce_fractional_digits(timestamp_str):
+ """
+ Given a RFC 3339 timestamp that includes too many digits for the fractional seconds part, reduces these to at most 6.
+ """
+ # RFC 3339 (https://www.rfc-editor.org/info/rfc3339)
+ m = _FRACTIONAL_MATCHER.match(timestamp_str)
+ if not m:
+ raise BackendException('Cannot parse ISO 8601 timestamp {0!r}'.format(timestamp_str))
+ timestamp, fractional, timezone = m.groups()
+ if len(fractional) > 7:
+ # Python does not support anything smaller than microseconds
+ # (Golang supports nanoseconds, Boulder often emits more fractional digits, which Python chokes on)
+ fractional = fractional[:7]
+ return '%s%s%s' % (timestamp, fractional, timezone)
+
+
+def _parse_acme_timestamp(timestamp_str, with_timezone):
+ """
+ Parses a RFC 3339 timestamp.
+ """
+ # RFC 3339 (https://www.rfc-editor.org/info/rfc3339)
+ timestamp_str = _reduce_fractional_digits(timestamp_str)
+ for format in ('%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%M:%S.%fZ', '%Y-%m-%dT%H:%M:%S%z', '%Y-%m-%dT%H:%M:%S.%f%z'):
+ # Note that %z won't work with Python 2... https://stackoverflow.com/a/27829491
+ try:
+ result = datetime.datetime.strptime(timestamp_str, format)
+ except ValueError:
+ pass
+ else:
+ return ensure_utc_timezone(result) if with_timezone else remove_timezone(result)
+ raise BackendException('Cannot parse ISO 8601 timestamp {0!r}'.format(timestamp_str))
@six.add_metaclass(abc.ABCMeta)
@@ -19,6 +88,30 @@ class CryptoBackend(object):
def __init__(self, module):
self.module = module
+ def get_now(self):
+ return get_now_datetime(with_timezone=False)
+
+ def parse_acme_timestamp(self, timestamp_str):
+ # RFC 3339 (https://www.rfc-editor.org/info/rfc3339)
+ return _parse_acme_timestamp(timestamp_str, with_timezone=False)
+
+ def parse_module_parameter(self, value, name):
+ try:
+ return get_relative_time_option(value, name, backend='cryptography', with_timezone=False)
+ except OpenSSLObjectError as exc:
+ raise BackendException(to_native(exc))
+
+ def interpolate_timestamp(self, timestamp_start, timestamp_end, percentage):
+ start = get_epoch_seconds(timestamp_start)
+ end = get_epoch_seconds(timestamp_end)
+ return from_epoch_seconds(start + percentage * (end - start), with_timezone=False)
+
+ def get_utc_datetime(self, *args, **kwargs):
+ result = datetime.datetime(*args, **kwargs)
+ if 'tzinfo' in kwargs or len(args) >= 8:
+ result = remove_timezone(result)
+ return result
+
@abc.abstractmethod
def parse_key(self, key_file=None, key_content=None, passphrase=None):
'''
@@ -74,3 +167,12 @@ class CryptoBackend(object):
'''
Given a Criterium object, creates a ChainMatcher object.
'''
+
+ def get_cert_information(self, cert_filename=None, cert_content=None):
+ '''
+ Return some information on a X.509 certificate as a CertificateInformation object.
+ '''
+ # Not implementing this method in a backend is DEPRECATED and will be
+ # disallowed in community.crypto 3.0.0. This method will be marked as
+ # @abstractmethod by then.
+ raise BackendException('This backend does not support get_cert_information()')
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/challenges.py b/ansible_collections/community/crypto/plugins/module_utils/acme/challenges.py
index 3a87ffec1..116ca4206 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/challenges.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/challenges.py
@@ -103,7 +103,7 @@ class Challenge(object):
# https://tools.ietf.org/html/rfc8555#section-8.4
resource = '_acme-challenge'
value = nopad_b64(hashlib.sha256(to_bytes(key_authorization)).digest())
- record = (resource + identifier[1:]) if identifier.startswith('*.') else '{0}.{1}'.format(resource, identifier)
+ record = '{0}.{1}'.format(resource, identifier[2:] if identifier.startswith('*.') else identifier)
return {
'resource': resource,
'resource_value': value,
@@ -283,13 +283,21 @@ class Authorization(object):
return self.status == 'valid'
return self.wait_for_validation(client, challenge_type)
+ def can_deactivate(self):
+ '''
+ Deactivates this authorization.
+ https://community.letsencrypt.org/t/authorization-deactivation/19860/2
+ https://tools.ietf.org/html/rfc8555#section-7.5.2
+ '''
+ return self.status in ('valid', 'pending')
+
def deactivate(self, client):
'''
Deactivates this authorization.
https://community.letsencrypt.org/t/authorization-deactivation/19860/2
https://tools.ietf.org/html/rfc8555#section-7.5.2
'''
- if self.status != 'valid':
+ if not self.can_deactivate():
return
authz_deactivate = {
'status': 'deactivated'
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/orders.py b/ansible_collections/community/crypto/plugins/module_utils/acme/orders.py
index 732b430df..98c28445f 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/orders.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/orders.py
@@ -32,6 +32,7 @@ class Order(object):
self.identifiers = []
for identifier in data['identifiers']:
self.identifiers.append((identifier['type'], identifier['value']))
+ self.replaces_cert_id = data.get('replaces')
self.finalize_uri = data.get('finalize')
self.certificate_uri = data.get('certificate')
self.authorization_uris = data['authorizations']
@@ -44,6 +45,7 @@ class Order(object):
self.status = None
self.identifiers = []
+ self.replaces_cert_id = None
self.finalize_uri = None
self.certificate_uri = None
self.authorization_uris = []
@@ -62,7 +64,7 @@ class Order(object):
return result
@classmethod
- def create(cls, client, identifiers):
+ def create(cls, client, identifiers, replaces_cert_id=None):
'''
Start a new certificate order (ACME v2 protocol).
https://tools.ietf.org/html/rfc8555#section-7.4
@@ -76,6 +78,8 @@ class Order(object):
new_order = {
"identifiers": acme_identifiers
}
+ if replaces_cert_id is not None:
+ new_order["replaces"] = replaces_cert_id
result, info = client.send_signed_request(
client.directory['newOrder'], new_order, error_msg='Failed to start new order', expected_status_codes=[201])
return cls.from_json(client, result, info['location'])
diff --git a/ansible_collections/community/crypto/plugins/module_utils/acme/utils.py b/ansible_collections/community/crypto/plugins/module_utils/acme/utils.py
index 217b6de47..ba460444b 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/acme/utils.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/acme/utils.py
@@ -10,6 +10,7 @@ __metaclass__ = type
import base64
+import datetime
import re
import textwrap
import traceback
@@ -19,6 +20,10 @@ from ansible.module_utils.six.moves.urllib.parse import unquote
from ansible_collections.community.crypto.plugins.module_utils.acme.errors import ModuleFailException
+from ansible_collections.community.crypto.plugins.module_utils.crypto.math import convert_int_to_bytes
+
+from ansible_collections.community.crypto.plugins.module_utils.time import get_now_datetime
+
def nopad_b64(data):
return base64.urlsafe_b64encode(data).decode('utf8').replace("=", "")
@@ -65,8 +70,61 @@ def pem_to_der(pem_filename=None, pem_content=None):
def process_links(info, callback):
'''
Process link header, calls callback for every link header with the URL and relation as options.
+
+ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link
'''
if 'link' in info:
link = info['link']
for url, relation in re.findall(r'<([^>]+)>;\s*rel="(\w+)"', link):
callback(unquote(url), relation)
+
+
+def parse_retry_after(value, relative_with_timezone=True, now=None):
+ '''
+ Parse the value of a Retry-After header and return a timestamp.
+
+ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
+ '''
+ # First try a number of seconds
+ try:
+ delta = datetime.timedelta(seconds=int(value))
+ if now is None:
+ now = get_now_datetime(relative_with_timezone)
+ return now + delta
+ except ValueError:
+ pass
+
+ try:
+ return datetime.datetime.strptime(value, '%a, %d %b %Y %H:%M:%S GMT')
+ except ValueError:
+ pass
+
+ raise ValueError('Cannot parse Retry-After header value %s' % repr(value))
+
+
+def compute_cert_id(
+ backend,
+ cert_info=None,
+ cert_filename=None,
+ cert_content=None,
+ none_if_required_information_is_missing=False,
+):
+ # Obtain certificate info if not provided
+ if cert_info is None:
+ cert_info = backend.get_cert_information(cert_filename=cert_filename, cert_content=cert_content)
+
+ # Convert Authority Key Identifier to string
+ if cert_info.authority_key_identifier is None:
+ if none_if_required_information_is_missing:
+ return None
+ raise ModuleFailException('Certificate has no Authority Key Identifier extension')
+ aki = to_native(base64.urlsafe_b64encode(cert_info.authority_key_identifier)).replace('=', '')
+
+ # Convert serial number to string
+ serial_bytes = convert_int_to_bytes(cert_info.serial_number)
+ if ord(serial_bytes[:1]) >= 128:
+ serial_bytes = b'\x00' + serial_bytes
+ serial = to_native(base64.urlsafe_b64encode(serial_bytes)).replace('=', '')
+
+ # Compose cert ID
+ return '{aki}.{serial}'.format(aki=aki, serial=serial)
diff --git a/ansible_collections/community/crypto/plugins/module_utils/argspec.py b/ansible_collections/community/crypto/plugins/module_utils/argspec.py
new file mode 100644
index 000000000..e583609dd
--- /dev/null
+++ b/ansible_collections/community/crypto/plugins/module_utils/argspec.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2020, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def _ensure_list(value):
+ if value is None:
+ return []
+ return list(value)
+
+
+class ArgumentSpec:
+ def __init__(self, argument_spec=None, mutually_exclusive=None, required_together=None, required_one_of=None, required_if=None, required_by=None):
+ self.argument_spec = argument_spec or {}
+ self.mutually_exclusive = _ensure_list(mutually_exclusive)
+ self.required_together = _ensure_list(required_together)
+ self.required_one_of = _ensure_list(required_one_of)
+ self.required_if = _ensure_list(required_if)
+ self.required_by = required_by or {}
+
+ def update_argspec(self, **kwargs):
+ self.argument_spec.update(kwargs)
+ return self
+
+ def update(self, mutually_exclusive=None, required_together=None, required_one_of=None, required_if=None, required_by=None):
+ if mutually_exclusive:
+ self.mutually_exclusive.extend(mutually_exclusive)
+ if required_together:
+ self.required_together.extend(required_together)
+ if required_one_of:
+ self.required_one_of.extend(required_one_of)
+ if required_if:
+ self.required_if.extend(required_if)
+ if required_by:
+ for k, v in required_by.items():
+ if k in self.required_by:
+ v = list(self.required_by[k]) + list(v)
+ self.required_by[k] = v
+ return self
+
+ def merge(self, other):
+ self.update_argspec(**other.argument_spec)
+ self.update(
+ mutually_exclusive=other.mutually_exclusive,
+ required_together=other.required_together,
+ required_one_of=other.required_one_of,
+ required_if=other.required_if,
+ required_by=other.required_by,
+ )
+ return self
+
+ def create_ansible_module_helper(self, clazz, args, **kwargs):
+ return clazz(
+ *args,
+ argument_spec=self.argument_spec,
+ mutually_exclusive=self.mutually_exclusive,
+ required_together=self.required_together,
+ required_one_of=self.required_one_of,
+ required_if=self.required_if,
+ required_by=self.required_by,
+ **kwargs)
+
+ def create_ansible_module(self, **kwargs):
+ return self.create_ansible_module_helper(AnsibleModule, (), **kwargs)
+
+
+__all__ = ('ArgumentSpec', )
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/math.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/math.py
index f56f22d33..1ec43e9f2 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/math.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/math.py
@@ -42,9 +42,18 @@ def quick_is_not_prime(n):
that we could not detect quickly whether it is not prime.
'''
if n <= 2:
- return True
+ return n < 2
# The constant in the next line is the product of all primes < 200
- if simple_gcd(n, 7799922041683461553249199106329813876687996789903550945093032474868511536164700810) > 1:
+ prime_product = 7799922041683461553249199106329813876687996789903550945093032474868511536164700810
+ gcd = simple_gcd(n, prime_product)
+ if gcd > 1:
+ if n < 200 and gcd == n:
+ # Explicitly check for all primes < 200
+ return n not in (
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
+ 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199,
+ )
return True
# TODO: maybe do some iterations of Miller-Rabin to increase confidence
# (https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test)
@@ -101,16 +110,27 @@ if sys.version_info[0] >= 3:
def _convert_int_to_bytes(count, no):
return no.to_bytes(count, byteorder='big')
+ def _convert_bytes_to_int(data):
+ return int.from_bytes(data, byteorder='big', signed=False)
+
def _to_hex(no):
return hex(no)[2:]
else:
# Python 2
def _convert_int_to_bytes(count, n):
+ if n == 0 and count == 0:
+ return ''
h = '%x' % n
if len(h) > 2 * count:
raise Exception('Number {1} needs more than {0} bytes!'.format(count, n))
return ('0' * (2 * count - len(h)) + h).decode('hex')
+ def _convert_bytes_to_int(data):
+ v = 0
+ for x in data:
+ v = (v << 8) | ord(x)
+ return v
+
def _to_hex(no):
return '%x' % no
@@ -144,3 +164,10 @@ def convert_int_to_hex(no, digits=None):
if digits is not None and len(value) < digits:
value = '0' * (digits - len(value)) + value
return value
+
+
+def convert_bytes_to_int(data):
+ """
+ Convert a byte string to an unsigned integer in network byte order.
+ """
+ return _convert_bytes_to_int(data)
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate.py
index 7bc93d934..595748fb9 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate.py
@@ -15,9 +15,9 @@ import traceback
from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
-from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
+from ansible_collections.community.crypto.plugins.module_utils.argspec import ArgumentSpec
-from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.common import ArgumentSpec
+from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
OpenSSLObjectError,
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_entrust.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_entrust.py
index 7dc4641e1..37351daeb 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_entrust.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_entrust.py
@@ -18,8 +18,6 @@ from ansible_collections.community.crypto.plugins.module_utils.ecs.api import EC
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
load_certificate,
- get_now_datetime,
- get_relative_time_option,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
@@ -34,6 +32,11 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
CertificateProvider,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_now_datetime,
+ get_relative_time_option,
+)
+
try:
from cryptography.x509.oid import NameOID
except ImportError:
@@ -44,7 +47,12 @@ class EntrustCertificateBackend(CertificateBackend):
def __init__(self, module, backend):
super(EntrustCertificateBackend, self).__init__(module, backend)
self.trackingId = None
- self.notAfter = get_relative_time_option(module.params['entrust_not_after'], 'entrust_not_after', backend=self.backend)
+ self.notAfter = get_relative_time_option(
+ module.params['entrust_not_after'],
+ 'entrust_not_after',
+ backend=self.backend,
+ with_timezone=CRYPTOGRAPHY_TIMEZONE,
+ )
if self.csr_content is None and self.csr_path is None:
raise CertificateError(
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py
index 5db6c3586..b612f8b18 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py
@@ -23,7 +23,6 @@ from ansible_collections.community.crypto.plugins.module_utils.version import Lo
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
load_certificate,
get_fingerprint_of_bytes,
- get_now_datetime,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
@@ -40,6 +39,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
get_publickey_info,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_now_datetime,
+)
+
MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
CRYPTOGRAPHY_IMP_ERR = None
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py
index 4d312e6b7..bd4860dff 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py
@@ -22,11 +22,11 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.basic impo
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
load_privatekey,
load_certificate,
- get_relative_time_option,
select_message_digest,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
+ CRYPTOGRAPHY_TIMEZONE,
cryptography_compare_public_keys,
cryptography_key_needs_digest_for_signing,
cryptography_serial_number_of_cert,
@@ -44,6 +44,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
CertificateProvider,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_relative_time_option,
+)
+
try:
import cryptography
from cryptography import x509
@@ -59,8 +63,18 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
self.create_subject_key_identifier = module.params['ownca_create_subject_key_identifier']
self.create_authority_key_identifier = module.params['ownca_create_authority_key_identifier']
- self.notBefore = get_relative_time_option(module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend)
- self.notAfter = get_relative_time_option(module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend)
+ self.notBefore = get_relative_time_option(
+ module.params['ownca_not_before'],
+ 'ownca_not_before',
+ backend=self.backend,
+ with_timezone=CRYPTOGRAPHY_TIMEZONE,
+ )
+ self.notAfter = get_relative_time_option(
+ module.params['ownca_not_after'],
+ 'ownca_not_after',
+ backend=self.backend,
+ with_timezone=CRYPTOGRAPHY_TIMEZONE,
+ )
self.digest = select_message_digest(module.params['ownca_digest'])
self.version = module.params['ownca_version']
self.serial_number = x509.random_serial_number()
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_selfsigned.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_selfsigned.py
index edd8d8d77..d7135d355 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_selfsigned.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_selfsigned.py
@@ -14,11 +14,11 @@ import os
from random import randrange
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
- get_relative_time_option,
select_message_digest,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
+ CRYPTOGRAPHY_TIMEZONE,
cryptography_key_needs_digest_for_signing,
cryptography_serial_number_of_cert,
cryptography_verify_certificate_signature,
@@ -34,6 +34,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
CertificateProvider,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_relative_time_option,
+)
+
try:
import cryptography
from cryptography import x509
@@ -48,8 +52,18 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
super(SelfSignedCertificateBackendCryptography, self).__init__(module, 'cryptography')
self.create_subject_key_identifier = module.params['selfsigned_create_subject_key_identifier']
- self.notBefore = get_relative_time_option(module.params['selfsigned_not_before'], 'selfsigned_not_before', backend=self.backend)
- self.notAfter = get_relative_time_option(module.params['selfsigned_not_after'], 'selfsigned_not_after', backend=self.backend)
+ self.notBefore = get_relative_time_option(
+ module.params['selfsigned_not_before'],
+ 'selfsigned_not_before',
+ backend=self.backend,
+ with_timezone=CRYPTOGRAPHY_TIMEZONE,
+ )
+ self.notAfter = get_relative_time_option(
+ module.params['selfsigned_not_after'],
+ 'selfsigned_not_after',
+ backend=self.backend,
+ with_timezone=CRYPTOGRAPHY_TIMEZONE,
+ )
self.digest = select_message_digest(module.params['selfsigned_digest'])
self.version = module.params['selfsigned_version']
self.serial_number = x509.random_serial_number()
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/common.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/common.py
index 67f87dd0c..6616249c4 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/common.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/common.py
@@ -10,26 +10,19 @@ __metaclass__ = type
from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.community.crypto.plugins.module_utils.argspec import ArgumentSpec as _ArgumentSpec
-class ArgumentSpec:
- def __init__(self, argument_spec, mutually_exclusive=None, required_together=None, required_one_of=None, required_if=None, required_by=None):
- self.argument_spec = argument_spec
- self.mutually_exclusive = mutually_exclusive or []
- self.required_together = required_together or []
- self.required_one_of = required_one_of or []
- self.required_if = required_if or []
- self.required_by = required_by or {}
+class ArgumentSpec(_ArgumentSpec):
def create_ansible_module_helper(self, clazz, args, **kwargs):
- return clazz(
- *args,
- argument_spec=self.argument_spec,
- mutually_exclusive=self.mutually_exclusive,
- required_together=self.required_together,
- required_one_of=self.required_one_of,
- required_if=self.required_if,
- required_by=self.required_by,
- **kwargs)
-
- def create_ansible_module(self, **kwargs):
- return self.create_ansible_module_helper(AnsibleModule, (), **kwargs)
+ result = super(ArgumentSpec, self).create_ansible_module_helper(clazz, args, **kwargs)
+ result.deprecate(
+ "The crypto.module_backends.common module utils is deprecated and will be removed from community.crypto 3.0.0."
+ " Use the argspec module utils from community.crypto instead.",
+ version='3.0.0',
+ collection_name='community.crypto',
+ )
+ return result
+
+
+__all__ = ('AnsibleModule', 'ArgumentSpec')
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/csr.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/csr.py
index 4ab14e527..6ce7e2438 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/csr.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/csr.py
@@ -17,6 +17,8 @@ from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_native, to_text
+from ansible_collections.community.crypto.plugins.module_utils.argspec import ArgumentSpec
+
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
@@ -49,8 +51,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
get_csr_info,
)
-from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.common import ArgumentSpec
-
MINIMAL_CRYPTOGRAPHY_VERSION = '1.3'
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey.py
index dc13107b7..36d50ae3c 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey.py
@@ -17,6 +17,8 @@ from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes
+from ansible_collections.community.crypto.plugins.module_utils.argspec import ArgumentSpec
+
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
@@ -42,8 +44,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
get_privatekey_info,
)
-from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.common import ArgumentSpec
-
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2.3'
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey_convert.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey_convert.py
index fdcc901e0..4a1aca600 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey_convert.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/privatekey_convert.py
@@ -15,12 +15,14 @@ from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes
-from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
+from ansible_collections.community.crypto.plugins.module_utils.argspec import ArgumentSpec
from ansible_collections.community.crypto.plugins.module_utils.io import (
load_file,
)
+from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
+
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_X25519,
CRYPTOGRAPHY_HAS_X448,
@@ -37,8 +39,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import
identify_private_key_format,
)
-from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.common import ArgumentSpec
-
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2.3'
diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py
index 8b59a3b70..862f5b8fc 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py
@@ -9,19 +9,25 @@ __metaclass__ = type
import abc
-import datetime
import errno
import hashlib
import os
-import re
from ansible.module_utils import six
-from ansible.module_utils.common.text.converters import to_native, to_bytes
+from ansible.module_utils.common.text.converters import to_bytes
from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
identify_pem_format,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import ( # noqa: F401, pylint: disable=unused-import
+ # These imports are for backwards compatibility
+ get_now_datetime,
+ ensure_utc_timezone,
+ convert_relative_to_datetime,
+ get_relative_time_option,
+)
+
try:
from OpenSSL import crypto
HAS_PYOPENSSL = True
@@ -279,86 +285,6 @@ def parse_ordered_name_field(input_list, name_field_name):
return result
-def get_now_datetime(with_timezone):
- if with_timezone:
- return datetime.datetime.now(tz=datetime.timezone.utc)
- return datetime.datetime.utcnow()
-
-
-def ensure_utc_timezone(timestamp):
- if timestamp.tzinfo is not None:
- return timestamp
- return timestamp.astimezone(datetime.timezone.utc)
-
-
-def convert_relative_to_datetime(relative_time_string, with_timezone=False):
- """Get a datetime.datetime or None from a string in the time format described in sshd_config(5)"""
-
- parsed_result = re.match(
- r"^(?P<prefix>[+-])((?P<weeks>\d+)[wW])?((?P<days>\d+)[dD])?((?P<hours>\d+)[hH])?((?P<minutes>\d+)[mM])?((?P<seconds>\d+)[sS]?)?$",
- relative_time_string)
-
- if parsed_result is None or len(relative_time_string) == 1:
- # not matched or only a single "+" or "-"
- return None
-
- offset = datetime.timedelta(0)
- if parsed_result.group("weeks") is not None:
- offset += datetime.timedelta(weeks=int(parsed_result.group("weeks")))
- if parsed_result.group("days") is not None:
- offset += datetime.timedelta(days=int(parsed_result.group("days")))
- if parsed_result.group("hours") is not None:
- offset += datetime.timedelta(hours=int(parsed_result.group("hours")))
- if parsed_result.group("minutes") is not None:
- offset += datetime.timedelta(
- minutes=int(parsed_result.group("minutes")))
- if parsed_result.group("seconds") is not None:
- offset += datetime.timedelta(
- seconds=int(parsed_result.group("seconds")))
-
- now = get_now_datetime(with_timezone=with_timezone)
- if parsed_result.group("prefix") == "+":
- return now + offset
- else:
- return now - offset
-
-
-def get_relative_time_option(input_string, input_name, backend='cryptography', with_timezone=False):
- """Return an absolute timespec if a relative timespec or an ASN1 formatted
- string is provided.
-
- The return value will be a datetime object for the cryptography backend,
- and a ASN1 formatted string for the pyopenssl backend."""
- result = to_native(input_string)
- if result is None:
- raise OpenSSLObjectError(
- 'The timespec "%s" for %s is not valid' %
- input_string, input_name)
- # Relative time
- if result.startswith("+") or result.startswith("-"):
- result_datetime = convert_relative_to_datetime(result, with_timezone=with_timezone)
- if backend == 'pyopenssl':
- return result_datetime.strftime("%Y%m%d%H%M%SZ")
- elif backend == 'cryptography':
- return result_datetime
- # Absolute time
- if backend == 'cryptography':
- for date_fmt in ['%Y%m%d%H%M%SZ', '%Y%m%d%H%MZ', '%Y%m%d%H%M%S%z', '%Y%m%d%H%M%z']:
- try:
- res = datetime.datetime.strptime(result, date_fmt)
- except ValueError:
- pass
- else:
- if with_timezone:
- res = res.astimezone(datetime.timezone.utc)
- return res
-
- raise OpenSSLObjectError(
- 'The time spec "%s" for %s is invalid' %
- (input_string, input_name)
- )
-
-
def select_message_digest(digest_string):
digest = None
if digest_string == 'sha256':
diff --git a/ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py b/ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py
index f59766651..8efb2ad9c 100644
--- a/ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py
+++ b/ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py
@@ -31,11 +31,15 @@ from hashlib import sha256
from ansible.module_utils import six
from ansible.module_utils.common.text.converters import to_text
-from ansible_collections.community.crypto.plugins.module_utils.crypto.support import convert_relative_to_datetime
from ansible_collections.community.crypto.plugins.module_utils.openssh.utils import (
OpensshParser,
_OpensshWriter,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ add_or_remove_timezone as _add_or_remove_timezone,
+ convert_relative_to_datetime,
+ UTC as _UTC,
+)
# See https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD
_USER_TYPE = 1
@@ -66,14 +70,8 @@ _ECDSA_CURVE_IDENTIFIERS_LOOKUP = {
_USE_TIMEZONE = sys.version_info >= (3, 6)
-def _ensure_utc_timezone_if_use_timezone(value):
- if not _USE_TIMEZONE or value.tzinfo is not None:
- return value
- return value.astimezone(_datetime.timezone.utc)
-
-
-_ALWAYS = _ensure_utc_timezone_if_use_timezone(datetime(1970, 1, 1))
-_FOREVER = datetime(9999, 12, 31, 23, 59, 59, 999999, _datetime.timezone.utc) if _USE_TIMEZONE else datetime.max
+_ALWAYS = _add_or_remove_timezone(datetime(1970, 1, 1), with_timezone=_USE_TIMEZONE)
+_FOREVER = datetime(9999, 12, 31, 23, 59, 59, 999999, _UTC) if _USE_TIMEZONE else datetime.max
_CRITICAL_OPTIONS = (
'force-command',
@@ -198,7 +196,7 @@ class OpensshCertificateTimeParameters(object):
else:
for time_format in ("%Y-%m-%d", "%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"):
try:
- result = _ensure_utc_timezone_if_use_timezone(datetime.strptime(time_string, time_format))
+ result = _add_or_remove_timezone(datetime.strptime(time_string, time_format), with_timezone=_USE_TIMEZONE)
except ValueError:
pass
if result is None:
diff --git a/ansible_collections/community/crypto/plugins/module_utils/time.py b/ansible_collections/community/crypto/plugins/module_utils/time.py
new file mode 100644
index 000000000..4adc4620e
--- /dev/null
+++ b/ansible_collections/community/crypto/plugins/module_utils/time.py
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+import datetime
+import re
+import sys
+
+from ansible.module_utils.common.text.converters import to_native
+
+from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
+ OpenSSLObjectError,
+)
+
+
+try:
+ UTC = datetime.timezone.utc
+except AttributeError:
+ _DURATION_ZERO = datetime.timedelta(0)
+
+ class _UTCClass(datetime.tzinfo):
+ def utcoffset(self, dt):
+ return _DURATION_ZERO
+
+ def dst(self, dt):
+ return _DURATION_ZERO
+
+ def tzname(self, dt):
+ return 'UTC'
+
+ def fromutc(self, dt):
+ return dt
+
+ def __repr__(self):
+ return 'UTC'
+
+ UTC = _UTCClass()
+
+
+def get_now_datetime(with_timezone):
+ if with_timezone:
+ return datetime.datetime.now(tz=UTC)
+ return datetime.datetime.utcnow()
+
+
+def ensure_utc_timezone(timestamp):
+ if timestamp.tzinfo is UTC:
+ return timestamp
+ if timestamp.tzinfo is None:
+ # We assume that naive datetime objects use timezone UTC!
+ return timestamp.replace(tzinfo=UTC)
+ return timestamp.astimezone(UTC)
+
+
+def remove_timezone(timestamp):
+ # Convert to native datetime object
+ if timestamp.tzinfo is None:
+ return timestamp
+ if timestamp.tzinfo is not UTC:
+ timestamp = timestamp.astimezone(UTC)
+ return timestamp.replace(tzinfo=None)
+
+
+def add_or_remove_timezone(timestamp, with_timezone):
+ return ensure_utc_timezone(timestamp) if with_timezone else remove_timezone(timestamp)
+
+
+if sys.version_info < (3, 3):
+ def get_epoch_seconds(timestamp):
+ epoch = datetime.datetime(1970, 1, 1, tzinfo=UTC if timestamp.tzinfo is not None else None)
+ delta = timestamp - epoch
+ try:
+ return delta.total_seconds()
+ except AttributeError:
+ # Python 2.6 and earlier: total_seconds() does not yet exist, so we use the formula from
+ # https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
+ return (delta.microseconds + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
+else:
+ def get_epoch_seconds(timestamp):
+ return timestamp.timestamp()
+
+
+def from_epoch_seconds(timestamp, with_timezone):
+ if with_timezone:
+ return datetime.datetime.fromtimestamp(timestamp, UTC)
+ return datetime.datetime.utcfromtimestamp(timestamp)
+
+
+def convert_relative_to_datetime(relative_time_string, with_timezone=False, now=None):
+ """Get a datetime.datetime or None from a string in the time format described in sshd_config(5)"""
+
+ parsed_result = re.match(
+ r"^(?P<prefix>[+-])((?P<weeks>\d+)[wW])?((?P<days>\d+)[dD])?((?P<hours>\d+)[hH])?((?P<minutes>\d+)[mM])?((?P<seconds>\d+)[sS]?)?$",
+ relative_time_string)
+
+ if parsed_result is None or len(relative_time_string) == 1:
+ # not matched or only a single "+" or "-"
+ return None
+
+ offset = datetime.timedelta(0)
+ if parsed_result.group("weeks") is not None:
+ offset += datetime.timedelta(weeks=int(parsed_result.group("weeks")))
+ if parsed_result.group("days") is not None:
+ offset += datetime.timedelta(days=int(parsed_result.group("days")))
+ if parsed_result.group("hours") is not None:
+ offset += datetime.timedelta(hours=int(parsed_result.group("hours")))
+ if parsed_result.group("minutes") is not None:
+ offset += datetime.timedelta(
+ minutes=int(parsed_result.group("minutes")))
+ if parsed_result.group("seconds") is not None:
+ offset += datetime.timedelta(
+ seconds=int(parsed_result.group("seconds")))
+
+ if now is None:
+ now = get_now_datetime(with_timezone=with_timezone)
+ else:
+ now = add_or_remove_timezone(now, with_timezone=with_timezone)
+
+ if parsed_result.group("prefix") == "+":
+ return now + offset
+ else:
+ return now - offset
+
+
+def get_relative_time_option(input_string, input_name, backend='cryptography', with_timezone=False, now=None):
+ """Return an absolute timespec if a relative timespec or an ASN1 formatted
+ string is provided.
+
+ The return value will be a datetime object for the cryptography backend,
+ and a ASN1 formatted string for the pyopenssl backend."""
+ result = to_native(input_string)
+ if result is None:
+ raise OpenSSLObjectError(
+ 'The timespec "%s" for %s is not valid' %
+ input_string, input_name)
+ # Relative time
+ if result.startswith("+") or result.startswith("-"):
+ result_datetime = convert_relative_to_datetime(result, with_timezone=with_timezone, now=now)
+ if backend == 'pyopenssl':
+ return result_datetime.strftime("%Y%m%d%H%M%SZ")
+ elif backend == 'cryptography':
+ return result_datetime
+ # Absolute time
+ if backend == 'pyopenssl':
+ return input_string
+ elif backend == 'cryptography':
+ for date_fmt, length in [
+ ('%Y%m%d%H%M%SZ', 15), # this also parses '202401020304Z', but as datetime(2024, 1, 2, 3, 0, 4)
+ ('%Y%m%d%H%MZ', 13),
+ ('%Y%m%d%H%M%S%z', 14 + 5), # this also parses '202401020304+0000', but as datetime(2024, 1, 2, 3, 0, 4, tzinfo=...)
+ ('%Y%m%d%H%M%z', 12 + 5),
+ ]:
+ if len(result) != length:
+ continue
+ try:
+ res = datetime.datetime.strptime(result, date_fmt)
+ except ValueError:
+ pass
+ else:
+ return add_or_remove_timezone(res, with_timezone=with_timezone)
+
+ raise OpenSSLObjectError(
+ 'The time spec "%s" for %s is invalid' %
+ (input_string, input_name)
+ )
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_account.py b/ansible_collections/community/crypto/plugins/modules/acme_account.py
index 1e8d64a57..960bad313 100644
--- a/ansible_collections/community/crypto/plugins/modules/acme_account.py
+++ b/ansible_collections/community/crypto/plugins/modules/acme_account.py
@@ -37,7 +37,8 @@ seealso:
- module: community.crypto.acme_inspect
description: Allows to debug problems.
extends_documentation_fragment:
- - community.crypto.acme
+ - community.crypto.acme.basic
+ - community.crypto.acme.account
- community.crypto.attributes
- community.crypto.attributes.actiongroup_acme
attributes:
@@ -169,11 +170,9 @@ account_uri:
import base64
-from ansible.module_utils.basic import AnsibleModule
-
from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
create_backend,
- get_default_argspec,
+ create_default_argspec,
ACMEClient,
)
@@ -188,8 +187,8 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.errors impor
def main():
- argument_spec = get_default_argspec()
- argument_spec.update(dict(
+ argument_spec = create_default_argspec()
+ argument_spec.update_argspec(
terms_agreed=dict(type='bool', default=False),
state=dict(type='str', required=True, choices=['absent', 'present', 'changed_key']),
allow_creation=dict(type='bool', default=True),
@@ -202,14 +201,9 @@ def main():
alg=dict(type='str', required=True, choices=['HS256', 'HS384', 'HS512']),
key=dict(type='str', required=True, no_log=True),
))
- ))
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_one_of=(
- ['account_key_src', 'account_key_content'],
- ),
+ )
+ argument_spec.update(
mutually_exclusive=(
- ['account_key_src', 'account_key_content'],
['new_account_key_src', 'new_account_key_content'],
),
required_if=(
@@ -217,8 +211,8 @@ def main():
# new_account_key_src and new_account_key_content are specified
['state', 'changed_key', ['new_account_key_src', 'new_account_key_content'], True],
),
- supports_check_mode=True,
)
+ module = argument_spec.create_ansible_module(supports_check_mode=True)
backend = create_backend(module, True)
if module.params['external_account_binding']:
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_account_info.py b/ansible_collections/community/crypto/plugins/modules/acme_account_info.py
index ac4617c90..33313fe75 100644
--- a/ansible_collections/community/crypto/plugins/modules/acme_account_info.py
+++ b/ansible_collections/community/crypto/plugins/modules/acme_account_info.py
@@ -25,7 +25,8 @@ notes:
- "This module was called C(acme_account_facts) before Ansible 2.8. The usage
did not change."
extends_documentation_fragment:
- - community.crypto.acme
+ - community.crypto.acme.basic
+ - community.crypto.acme.account
- community.crypto.attributes
- community.crypto.attributes.actiongroup_acme
- community.crypto.attributes.info_module
@@ -213,11 +214,9 @@ order_uris:
version_added: 1.5.0
'''
-from ansible.module_utils.basic import AnsibleModule
-
from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
create_backend,
- get_default_argspec,
+ create_default_argspec,
ACMEClient,
)
@@ -270,20 +269,11 @@ def get_order(client, order_url):
def main():
- argument_spec = get_default_argspec()
- argument_spec.update(dict(
+ argument_spec = create_default_argspec()
+ argument_spec.update_argspec(
retrieve_orders=dict(type='str', default='ignore', choices=['ignore', 'url_list', 'object_list']),
- ))
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_one_of=(
- ['account_key_src', 'account_key_content'],
- ),
- mutually_exclusive=(
- ['account_key_src', 'account_key_content'],
- ),
- supports_check_mode=True,
)
+ module = argument_spec.create_ansible_module(supports_check_mode=True)
backend = create_backend(module, True)
try:
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_ari_info.py b/ansible_collections/community/crypto/plugins/modules/acme_ari_info.py
new file mode 100644
index 000000000..7783236f0
--- /dev/null
+++ b/ansible_collections/community/crypto/plugins/modules/acme_ari_info.py
@@ -0,0 +1,142 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2018 Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: acme_ari_info
+author: "Felix Fontein (@felixfontein)"
+version_added: 2.20.0
+short_description: Retrieves ACME Renewal Information (ARI) for a certificate
+description:
+ - "Allows to retrieve renewal information on a certificate obtained with the
+ L(ACME protocol,https://tools.ietf.org/html/rfc8555)."
+ - "This module only works with the ACME v2 protocol, and requires the ACME server
+ to support the ARI extension (U(https://datatracker.ietf.org/doc/draft-ietf-acme-ari/)).
+ This module implements version 3 of the ARI draft."
+extends_documentation_fragment:
+ - community.crypto.acme.basic
+ - community.crypto.acme.no_account
+ - community.crypto.attributes
+ - community.crypto.attributes.info_module
+options:
+ certificate_path:
+ description:
+ - A path to the X.509 certificate to request information for.
+ - Exactly one of O(certificate_path) and O(certificate_content) must be provided.
+ type: path
+ certificate_content:
+ description:
+ - The content of the X.509 certificate to request information for.
+ - Exactly one of O(certificate_path) and O(certificate_content) must be provided.
+ type: str
+seealso:
+ - module: community.crypto.acme_certificate
+ description: Allows to obtain a certificate using the ACME protocol
+ - module: community.crypto.acme_certificate_revoke
+ description: Allows to revoke a certificate using the ACME protocol
+'''
+
+EXAMPLES = '''
+- name: Retrieve renewal information for a certificate
+ community.crypto.acme_ari_info:
+ certificate_path: /etc/httpd/ssl/sample.com.crt
+ register: cert_data
+
+- name: Show the certificate renewal information
+ ansible.builtin.debug:
+ var: cert_data.renewal_info
+'''
+
+RETURN = '''
+renewal_info:
+ description: The ARI renewal info object (U(https://www.ietf.org/archive/id/draft-ietf-acme-ari-03.html#section-4.2)).
+ returned: success
+ type: dict
+ contains:
+ suggestedWindow:
+ description:
+ - Describes the window during which the certificate should be renewed.
+ type: dict
+ returned: always
+ contains:
+ start:
+ description:
+ - The start of the window during which the certificate should be renewed.
+ - The format is specified in L(RFC 3339,https://www.rfc-editor.org/info/rfc3339).
+ returned: always
+ type: str
+ sample: '2021-01-03T00:00:00Z'
+ end:
+ description:
+ - The end of the window during which the certificate should be renewed.
+ - The format is specified in L(RFC 3339,https://www.rfc-editor.org/info/rfc3339).
+ returned: always
+ type: str
+ sample: '2021-01-03T00:00:00Z'
+ explanationURL:
+ description:
+ - A URL pointing to a page which may explain why the suggested renewal window is what it is.
+ - For example, it may be a page explaining the CA's dynamic load-balancing strategy, or a
+ page documenting which certificates are affected by a mass revocation event. Should be shown
+ to the user.
+ returned: depends on the ACME server
+ type: str
+ sample: https://example.com/docs/ari
+ retryAfter:
+ description:
+ - A timestamp before the next retry to ask for this information should not be made.
+ returned: depends on the ACME server
+ type: str
+ sample: '2024-04-29T01:17:10.236921+00:00'
+'''
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
+ create_backend,
+ create_default_argspec,
+ ACMEClient,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.errors import ModuleFailException
+
+
+def main():
+ argument_spec = create_default_argspec(with_account=False)
+ argument_spec.update_argspec(
+ certificate_path=dict(type='path'),
+ certificate_content=dict(type='str'),
+ )
+ argument_spec.update(
+ required_one_of=(
+ ['certificate_path', 'certificate_content'],
+ ),
+ mutually_exclusive=(
+ ['certificate_path', 'certificate_content'],
+ ),
+ )
+ module = argument_spec.create_ansible_module(supports_check_mode=True)
+ backend = create_backend(module, True)
+
+ try:
+ client = ACMEClient(module, backend)
+ if not client.directory.has_renewal_info_endpoint():
+ module.fail_json(msg='The ACME endpoint does not support ACME Renewal Information retrieval')
+ renewal_info = client.get_renewal_info(
+ cert_filename=module.params['certificate_path'],
+ cert_content=module.params['certificate_content'],
+ include_retry_after=True,
+ )
+ module.exit_json(renewal_info=renewal_info)
+ except ModuleFailException as e:
+ e.do_fail(module)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_certificate.py b/ansible_collections/community/crypto/plugins/modules/acme_certificate.py
index 21a6d6ae9..8729996c0 100644
--- a/ansible_collections/community/crypto/plugins/modules/acme_certificate.py
+++ b/ansible_collections/community/crypto/plugins/modules/acme_certificate.py
@@ -58,7 +58,7 @@ seealso:
link: https://tools.ietf.org/html/rfc8555
- name: ACME TLS ALPN Challenge Extension
description: The specification of the V(tls-alpn-01) challenge (RFC 8737).
- link: https://www.rfc-editor.org/rfc/rfc8737.html-05
+ link: https://www.rfc-editor.org/rfc/rfc8737.html
- module: community.crypto.acme_challenge_cert_helper
description: Helps preparing V(tls-alpn-01) challenges.
- module: community.crypto.openssl_privatekey
@@ -77,8 +77,12 @@ seealso:
description: Allows to create, modify or delete an ACME account.
- module: community.crypto.acme_inspect
description: Allows to debug problems.
+ - module: community.crypto.acme_certificate_deactivate_authz
+ description: Allows to deactivate (invalidate) ACME v2 orders.
extends_documentation_fragment:
- - community.crypto.acme
+ - community.crypto.acme.basic
+ - community.crypto.acme.account
+ - community.crypto.acme.certificate
- community.crypto.attributes
- community.crypto.attributes.files
- community.crypto.attributes.actiongroup_acme
@@ -138,32 +142,8 @@ options:
- 'tls-alpn-01'
- 'no challenge'
csr:
- description:
- - "File containing the CSR for the new certificate."
- - "Can be created with M(community.crypto.openssl_csr) or C(openssl req ...)."
- - "The CSR may contain multiple Subject Alternate Names, but each one
- will lead to an individual challenge that must be fulfilled for the
- CSR to be signed."
- - "I(Note): the private key used to create the CSR I(must not) be the
- account key. This is a bad idea from a security point of view, and
- the CA should not accept the CSR. The ACME server should return an
- error in this case."
- - Precisely one of O(csr) or O(csr_content) must be specified.
- type: path
aliases: ['src']
csr_content:
- description:
- - "Content of the CSR for the new certificate."
- - "Can be created with M(community.crypto.openssl_csr_pipe) or C(openssl req ...)."
- - "The CSR may contain multiple Subject Alternate Names, but each one
- will lead to an individual challenge that must be fulfilled for the
- CSR to be signed."
- - "I(Note): the private key used to create the CSR I(must not) be the
- account key. This is a bad idea from a security point of view, and
- the CA should not accept the CSR. The ACME server should return an
- error in this case."
- - Precisely one of O(csr) or O(csr_content) must be specified.
- type: str
version_added: 1.2.0
data:
description:
@@ -292,6 +272,32 @@ options:
- "The identifier must be of the form
V(C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10)."
type: str
+ include_renewal_cert_id:
+ description:
+ - Determines whether to request renewal of an existing certificate according to
+ L(the ACME ARI draft 3, https://www.ietf.org/archive/id/draft-ietf-acme-ari-03.html#section-5).
+ - This is only used when the certificate specified in O(dest) or O(fullchain_dest) already exists.
+ - V(never) never sends the certificate ID of the certificate to renew. V(always) will always send it.
+ - V(when_ari_supported) only sends the certificate ID if the ARI endpoint is found in the ACME directory.
+ - Generally you should use V(when_ari_supported) if you know that the ACME service supports a compatible
+ draft (or final version, once it is out) of the ARI extension. V(always) should never be necessary.
+ If you are not sure, or if you receive strange errors on invalid C(replaces) values in order objects,
+ use V(never), which also happens to be the default.
+ - ACME servers might refuse to create new orders with C(replaces) for certificates that already have an
+ existing order. This can happen if this module is used to create an order, and then the playbook/role
+ fails in case the challenges cannot be set up. If the playbook/role does not record the order data to
+ continue with the existing order, but tries to create a new one on the next run, creating the new order
+ might fail. For this reason, this option should only be set to a value different from V(never) if the
+ role/playbook using it keeps track of order data accross restarts, or if it takes care to deactivate
+ orders whose processing is aborted. Orders can be deactivated with the
+ M(community.crypto.acme_certificate_deactivate_authz) module.
+ type: str
+ choices:
+ - never
+ - when_ari_supported
+ - always
+ default: never
+ version_added: 2.20.0
'''
EXAMPLES = r'''
@@ -375,7 +381,7 @@ EXAMPLES = r'''
# state: present
# wait: true
# # Note: route53 requires TXT entries to be enclosed in quotes
-# value: "{{ sample_com_challenge.challenge_data['sample.com']['dns-01'].resource_value | regex_replace('^(.*)$', '\"\\1\"') }}"
+# value: "{{ sample_com_challenge.challenge_data['sample.com']['dns-01'].resource_value | community.dns.quote_txt(always_quote=true) }}"
# when: sample_com_challenge is changed and 'sample.com' in sample_com_challenge.challenge_data
#
# Alternative way:
@@ -390,7 +396,7 @@ EXAMPLES = r'''
# wait: true
# # Note: item.value is a list of TXT entries, and route53
# # requires every entry to be enclosed in quotes
-# value: "{{ item.value | map('regex_replace', '^(.*)$', '\"\\1\"' ) | list }}"
+# value: "{{ item.value | map('community.dns.quote_txt', always_quote=true) | list }}"
# loop: "{{ sample_com_challenge.challenge_data_dns | dict2items }}"
# when: sample_com_challenge is changed
@@ -446,39 +452,55 @@ challenge_data:
- Per identifier / challenge type challenge data.
- Since Ansible 2.8.5, only challenges which are not yet valid are returned.
returned: changed
- type: list
- elements: dict
+ type: dict
contains:
- resource:
- description: The challenge resource that must be created for validation.
- returned: changed
- type: str
- sample: .well-known/acme-challenge/evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA
- resource_original:
- description:
- - The original challenge resource including type identifier for V(tls-alpn-01)
- challenges.
- returned: changed and O(challenge) is V(tls-alpn-01)
- type: str
- sample: DNS:example.com
- resource_value:
+ identifier:
description:
- - The value the resource has to produce for the validation.
- - For V(http-01) and V(dns-01) challenges, the value can be used as-is.
- - "For V(tls-alpn-01) challenges, note that this return value contains a
- Base64 encoded version of the correct binary blob which has to be put
- into the acmeValidation x509 extension; see
- U(https://www.rfc-editor.org/rfc/rfc8737.html#section-3)
- for details. To do this, you might need the P(ansible.builtin.b64decode#filter) Jinja filter
- to extract the binary blob from this return value."
+ - For every identifier, provides a dictionary of challenge types mapping to challenge data.
+ - The keys in this dictionary are the identifiers. C(identifier) is a placeholder used in the documentation.
+ - Note that the keys are not valid Jinja2 identifiers.
returned: changed
- type: str
- sample: IlirfxKKXA...17Dt3juxGJ-PCt92wr-oA
- record:
- description: The full DNS record's name for the challenge.
- returned: changed and challenge is V(dns-01)
- type: str
- sample: _acme-challenge.example.com
+ type: dict
+ contains:
+ challenge-type:
+ description:
+ - Data for every challenge type.
+ - The keys in this dictionary are the challenge types. C(challenge-type) is a placeholder used in the documentation.
+ Possible keys are V(http-01), V(dns-01), and V(tls-alpn-01).
+ - Note that the keys are not valid Jinja2 identifiers.
+ returned: changed
+ type: dict
+ contains:
+ resource:
+ description: The challenge resource that must be created for validation.
+ returned: changed
+ type: str
+ sample: .well-known/acme-challenge/evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA
+ resource_original:
+ description:
+ - The original challenge resource including type identifier for V(tls-alpn-01)
+ challenges.
+ returned: changed and O(challenge) is V(tls-alpn-01)
+ type: str
+ sample: DNS:example.com
+ resource_value:
+ description:
+ - The value the resource has to produce for the validation.
+ - For V(http-01) and V(dns-01) challenges, the value can be used as-is.
+ - "For V(tls-alpn-01) challenges, note that this return value contains a
+ Base64 encoded version of the correct binary blob which has to be put
+ into the acmeValidation x509 extension; see
+ U(https://www.rfc-editor.org/rfc/rfc8737.html#section-3)
+ for details. To do this, you might need the P(ansible.builtin.b64decode#filter) Jinja filter
+ to extract the binary blob from this return value."
+ returned: changed
+ type: str
+ sample: IlirfxKKXA...17Dt3juxGJ-PCt92wr-oA
+ record:
+ description: The full DNS record's name for the challenge.
+ returned: changed and challenge is V(dns-01)
+ type: str
+ sample: _acme-challenge.example.com
challenge_data_dns:
description:
- List of TXT values per DNS record, in case challenge is V(dns-01).
@@ -547,11 +569,9 @@ all_chains:
import os
-from ansible.module_utils.basic import AnsibleModule
-
from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
create_backend,
- get_default_argspec,
+ create_default_argspec,
ACMEClient,
)
@@ -585,6 +605,7 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.orders impor
)
from ansible_collections.community.crypto.plugins.module_utils.acme.utils import (
+ compute_cert_id,
pem_to_der,
)
@@ -621,6 +642,7 @@ class ACMECertificateClient(object):
self.order_uri = self.data.get('order_uri') if self.data else None
self.all_chains = None
self.select_chain_matcher = []
+ self.include_renewal_cert_id = module.params['include_renewal_cert_id']
if self.module.params['select_chain']:
for criterium_idx, criterium in enumerate(self.module.params['select_chain']):
@@ -678,6 +700,15 @@ class ACMECertificateClient(object):
# stored in self.order_uri by the constructor).
return self.order_uri is None
+ def _get_cert_info_or_none(self):
+ if self.module.params.get('dest'):
+ filename = self.module.params['dest']
+ else:
+ filename = self.module.params['fullchain_dest']
+ if not os.path.exists(filename):
+ return None
+ return self.client.backend.get_cert_information(cert_filename=filename)
+
def start_challenges(self):
'''
Create new authorizations for all identifiers of the CSR,
@@ -692,7 +723,19 @@ class ACMECertificateClient(object):
authz = Authorization.create(self.client, identifier_type, identifier)
self.authorizations[authz.combined_identifier] = authz
else:
- self.order = Order.create(self.client, self.identifiers)
+ replaces_cert_id = None
+ if (
+ self.include_renewal_cert_id == 'always' or
+ (self.include_renewal_cert_id == 'when_ari_supported' and self.client.directory.has_renewal_info_endpoint())
+ ):
+ cert_info = self._get_cert_info_or_none()
+ if cert_info is not None:
+ replaces_cert_id = compute_cert_id(
+ self.client.backend,
+ cert_info=cert_info,
+ none_if_required_information_is_missing=True,
+ )
+ self.order = Order.create(self.client, self.identifiers, replaces_cert_id)
self.order_uri = self.order.url
self.order.load_authorizations(self.client)
self.authorizations.update(self.order.authorizations)
@@ -854,15 +897,14 @@ class ACMECertificateClient(object):
def main():
- argument_spec = get_default_argspec()
- argument_spec.update(dict(
+ argument_spec = create_default_argspec(with_certificate=True)
+ argument_spec.argument_spec['csr']['aliases'] = ['src']
+ argument_spec.update_argspec(
modify_account=dict(type='bool', default=True),
account_email=dict(type='str'),
agreement=dict(type='str'),
terms_agreed=dict(type='bool', default=False),
challenge=dict(type='str', default='http-01', choices=['http-01', 'dns-01', 'tls-alpn-01', NO_CHALLENGE]),
- csr=dict(type='path', aliases=['src']),
- csr_content=dict(type='str'),
data=dict(type='dict'),
dest=dict(type='path', aliases=['cert']),
fullchain_dest=dict(type='path', aliases=['fullchain']),
@@ -878,20 +920,14 @@ def main():
subject_key_identifier=dict(type='str'),
authority_key_identifier=dict(type='str'),
)),
- ))
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_one_of=(
- ['account_key_src', 'account_key_content'],
+ include_renewal_cert_id=dict(type='str', choices=['never', 'when_ari_supported', 'always'], default='never'),
+ )
+ argument_spec.update(
+ required_one_of=[
['dest', 'fullchain_dest'],
- ['csr', 'csr_content'],
- ),
- mutually_exclusive=(
- ['account_key_src', 'account_key_content'],
- ['csr', 'csr_content'],
- ),
- supports_check_mode=True,
+ ],
)
+ module = argument_spec.create_ansible_module(supports_check_mode=True)
backend = create_backend(module, False)
try:
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_certificate_deactivate_authz.py b/ansible_collections/community/crypto/plugins/modules/acme_certificate_deactivate_authz.py
new file mode 100644
index 000000000..133f777d6
--- /dev/null
+++ b/ansible_collections/community/crypto/plugins/modules/acme_certificate_deactivate_authz.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2016 Michael Gruener <michael.gruener@chaosmoon.net>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: acme_certificate_deactivate_authz
+author: "Felix Fontein (@felixfontein)"
+version_added: 2.20.0
+short_description: Deactivate all authz for an ACME v2 order
+description:
+ - "Deactivate all authentication objects (authz) for an ACME v2 order,
+ which effectively deactivates (invalidates) the order itself."
+ - "Authentication objects are bound to an account key and remain valid
+ for a certain amount of time, and can be used to issue certificates
+ without having to re-authenticate the domain. This can be a security
+ concern."
+ - "Another reason to use this module is to deactivate an order whose
+ processing failed when using O(community.crypto.acme_certificate#module:include_renewal_cert_id)."
+seealso:
+ - module: community.crypto.acme_certificate
+extends_documentation_fragment:
+ - community.crypto.acme.basic
+ - community.crypto.acme.account
+ - community.crypto.attributes
+ - community.crypto.attributes.actiongroup_acme
+attributes:
+ check_mode:
+ support: full
+ diff_mode:
+ support: none
+options:
+ order_uri:
+ description:
+ - The ACME v2 order to deactivate.
+ - Can be obtained from RV(community.crypto.acme_certificate#module:order_uri).
+ type: str
+ required: true
+'''
+
+EXAMPLES = r'''
+- name: Deactivate all authzs for an order
+ community.crypto.acme_certificate_deactivate_authz:
+ account_key_content: "{{ account_private_key }}"
+ order_uri: "{{ certificate_result.order_uri }}"
+'''
+
+RETURN = '''#'''
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
+ create_backend,
+ create_default_argspec,
+ ACMEClient,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.account import (
+ ACMEAccount,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.errors import (
+ ModuleFailException,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.orders import (
+ Order,
+)
+
+
+def main():
+ argument_spec = create_default_argspec()
+ argument_spec.update_argspec(
+ order_uri=dict(type='str', required=True),
+ )
+ module = argument_spec.create_ansible_module(supports_check_mode=True)
+ if module.params['acme_version'] == 1:
+ module.fail_json('The module does not support acme_version=1')
+
+ backend = create_backend(module, False)
+
+ try:
+ client = ACMEClient(module, backend)
+ account = ACMEAccount(client)
+
+ dummy, account_data = account.setup_account(allow_creation=False)
+ if account_data is None:
+ raise ModuleFailException(msg='Account does not exist or is deactivated.')
+
+ order = Order.from_url(client, module.params['order_uri'])
+ order.load_authorizations(client)
+
+ changed = False
+ for authz in order.authorizations.values():
+ if not authz.can_deactivate():
+ continue
+ changed = True
+ if module.check_mode:
+ continue
+ try:
+ authz.deactivate(client)
+ except Exception:
+ # ignore errors
+ pass
+ if authz.status != 'deactivated':
+ module.warn(warning='Could not deactivate authz object {0}.'.format(authz.url))
+
+ module.exit_json(changed=changed)
+ except ModuleFailException as e:
+ e.do_fail(module)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_certificate_renewal_info.py b/ansible_collections/community/crypto/plugins/modules/acme_certificate_renewal_info.py
new file mode 100644
index 000000000..1e2b16918
--- /dev/null
+++ b/ansible_collections/community/crypto/plugins/modules/acme_certificate_renewal_info.py
@@ -0,0 +1,245 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2018 Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = '''
+---
+module: acme_certificate_renewal_info
+author: "Felix Fontein (@felixfontein)"
+version_added: 2.20.0
+short_description: Determine whether a certificate should be renewed or not
+description:
+ - Uses various information to determine whether a certificate should be renewed or not.
+ - If available, the ARI extension (ACME Renewal Information, U(https://datatracker.ietf.org/doc/draft-ietf-acme-ari/))
+ is used. This module implements version 3 of the ARI draft."
+extends_documentation_fragment:
+ - community.crypto.acme.basic
+ - community.crypto.acme.no_account
+ - community.crypto.attributes
+ - community.crypto.attributes.info_module
+options:
+ certificate_path:
+ description:
+ - A path to the X.509 certificate to determine renewal of.
+ - In case the certificate does not exist, the module will always return RV(should_renew=true).
+ - O(certificate_path) and O(certificate_content) are mutually exclusive.
+ type: path
+ certificate_content:
+ description:
+ - The content of the X.509 certificate to determine renewal of.
+ - O(certificate_path) and O(certificate_content) are mutually exclusive.
+ type: str
+ use_ari:
+ description:
+ - Whether to use ARI information, if available.
+ - Set this to V(false) if the ACME server implements ARI in a way that is incompatible with this module.
+ type: bool
+ default: true
+ ari_algorithm:
+ description:
+ - If ARI information is used, selects which algorithm is used to determine whether to renew now.
+ - V(standard) selects the L(algorithm provided in the the ARI specification,
+ https://www.ietf.org/archive/id/draft-ietf-acme-ari-03.html#name-renewalinfo-objects).
+ - V(start) returns RV(should_renew=true) once the start of the renewal interval has been reached.
+ type: str
+ choices:
+ - standard
+ - start
+ default: standard
+ remaining_days:
+ description:
+ - The number of days the certificate must have left being valid.
+ - For example, if O(remaining_days=20), this check causes RV(should_renew=true) if the
+ certificate is valid for less than 20 days.
+ type: int
+ remaining_percentage:
+ description:
+ - The percentage of the certificate's validity period that should be left.
+ - For example, if O(remaining_percentage=0.1), and the certificate's validity period is 90 days,
+ this check causes RV(should_renew=true) if the certificate is valid for less than 9 days.
+ - Must be a value between 0 and 1.
+ type: float
+ now:
+ description:
+ - Use this timestamp instead of the current timestamp to determine whether a certificate should be renewed.
+ - Time can be specified either as relative time or as absolute timestamp.
+ - Time will always be interpreted as UTC.
+ - Valid format is C([+-]timespec | ASN.1 TIME) where timespec can be an integer
+ + C([w | d | h | m | s]) (for example V(+32w1d2h)).
+ type: str
+seealso:
+ - module: community.crypto.acme_certificate
+ description: Allows to obtain a certificate using the ACME protocol
+ - module: community.crypto.acme_ari_info
+ description: Obtain renewal information for a certificate
+'''
+
+EXAMPLES = '''
+- name: Retrieve renewal information for a certificate
+ community.crypto.acme_certificate_renewal_info:
+ certificate_path: /etc/httpd/ssl/sample.com.crt
+ register: cert_data
+
+- name: Should the certificate be renewed?
+ ansible.builtin.debug:
+ var: cert_data.should_renew
+'''
+
+RETURN = '''
+should_renew:
+ description:
+ - Whether the certificate should be renewed.
+ - If no certificate is provided, or the certificate is expired, will always be V(true).
+ returned: success
+ type: bool
+ sample: true
+
+msg:
+ description:
+ - Information on the reason for renewal.
+ - Should be shown to the user, as in case of ARI triggered renewal it can contain important
+ information, for example on forced revocations for misissued certificates.
+ type: str
+ returned: success
+ sample: The certificate does not exist.
+
+supports_ari:
+ description:
+ - Whether ARI information was used to determine renewal. This can be used to determine whether to
+ specify O(community.crypto.acme_certificate#module:include_renewal_cert_id=when_ari_supported)
+ for the M(community.crypto.acme_certificate) module.
+ - If O(use_ari=false), this will always be V(false).
+ returned: success
+ type: bool
+ sample: true
+
+cert_id:
+ description:
+ - The certificate ID according to the L(ARI specification, https://www.ietf.org/archive/id/draft-ietf-acme-ari-03.html#section-4.1).
+ returned: success, the certificate exists, and has an Authority Key Identifier X.509 extension
+ type: str
+ sample: aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE
+'''
+
+import os
+import random
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
+ create_backend,
+ create_default_argspec,
+ ACMEClient,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.errors import ModuleFailException
+
+from ansible_collections.community.crypto.plugins.module_utils.acme.utils import compute_cert_id
+
+
+def main():
+ argument_spec = create_default_argspec(with_account=False)
+ argument_spec.update_argspec(
+ certificate_path=dict(type='path'),
+ certificate_content=dict(type='str'),
+ use_ari=dict(type='bool', default=True),
+ ari_algorithm=dict(type='str', choices=['standard', 'start'], default='standard'),
+ remaining_days=dict(type='int'),
+ remaining_percentage=dict(type='float'),
+ now=dict(type='str'),
+ )
+ argument_spec.update(
+ mutually_exclusive=(
+ ['certificate_path', 'certificate_content'],
+ ),
+ )
+ module = argument_spec.create_ansible_module(supports_check_mode=True)
+ backend = create_backend(module, True)
+
+ result = dict(
+ changed=False,
+ msg='The certificate is still valid and no condition was reached',
+ supports_ari=False,
+ )
+
+ def complete(should_renew, **kwargs):
+ result['should_renew'] = should_renew
+ result.update(kwargs)
+ module.exit_json(**result)
+
+ if not module.params['certificate_path'] and not module.params['certificate_content']:
+ complete(True, msg='No certificate was specified')
+
+ if module.params['certificate_path'] is not None and not os.path.exists(module.params['certificate_path']):
+ complete(True, msg='The certificate file does not exist')
+
+ try:
+ cert_info = backend.get_cert_information(
+ cert_filename=module.params['certificate_path'],
+ cert_content=module.params['certificate_content'],
+ )
+ cert_id = compute_cert_id(backend, cert_info=cert_info, none_if_required_information_is_missing=True)
+ if cert_id is not None:
+ result['cert_id'] = cert_id
+
+ if module.params['now']:
+ now = backend.parse_module_parameter(module.params['now'], 'now')
+ else:
+ now = backend.get_now()
+
+ if now >= cert_info.not_valid_after:
+ complete(True, msg='The certificate has already expired')
+
+ client = ACMEClient(module, backend)
+ if cert_id is not None and module.params['use_ari'] and client.directory.has_renewal_info_endpoint():
+ renewal_info = client.get_renewal_info(cert_id=cert_id)
+ window_start = backend.parse_acme_timestamp(renewal_info['suggestedWindow']['start'])
+ window_end = backend.parse_acme_timestamp(renewal_info['suggestedWindow']['end'])
+ msg_append = ''
+ if 'explanationURL' in renewal_info:
+ msg_append = '. Information on renewal interval: {0}'.format(renewal_info['explanationURL'])
+ result['supports_ari'] = True
+ if now > window_end:
+ complete(True, msg='The suggested renewal interval provided by ARI is in the past{0}'.format(msg_append))
+ if module.params['ari_algorithm'] == 'start':
+ if now > window_start:
+ complete(True, msg='The suggested renewal interval provided by ARI has begun{0}'.format(msg_append))
+ else:
+ random_time = backend.interpolate_timestamp(window_start, window_end, random.random())
+ if now > random_time:
+ complete(
+ True,
+ msg='The picked random renewal time {0} in sugested renewal internal provided by ARI is in the past{1}'.format(
+ random_time,
+ msg_append,
+ ),
+ )
+
+ if module.params['remaining_days'] is not None:
+ remaining_days = (cert_info.not_valid_after - now).days
+ if remaining_days < module.params['remaining_days']:
+ complete(True, msg='The certificate expires in {0} days'.format(remaining_days))
+
+ if module.params['remaining_percentage'] is not None:
+ timestamp = backend.interpolate_timestamp(cert_info.not_valid_before, cert_info.not_valid_after, 1 - module.params['remaining_percentage'])
+ if timestamp < now:
+ complete(
+ True,
+ msg="The remaining percentage {0}% of the certificate's lifespan was reached on {1}".format(
+ module.params['remaining_percentage'] * 100,
+ timestamp,
+ ),
+ )
+
+ complete(False)
+ except ModuleFailException as e:
+ e.do_fail(module)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_certificate_revoke.py b/ansible_collections/community/crypto/plugins/modules/acme_certificate_revoke.py
index 022862e60..2661a1525 100644
--- a/ansible_collections/community/crypto/plugins/modules/acme_certificate_revoke.py
+++ b/ansible_collections/community/crypto/plugins/modules/acme_certificate_revoke.py
@@ -37,7 +37,8 @@ seealso:
- module: community.crypto.acme_inspect
description: Allows to debug problems.
extends_documentation_fragment:
- - community.crypto.acme
+ - community.crypto.acme.basic
+ - community.crypto.acme.account
- community.crypto.attributes
- community.crypto.attributes.actiongroup_acme
attributes:
@@ -127,11 +128,9 @@ EXAMPLES = '''
RETURN = '''#'''
-from ansible.module_utils.basic import AnsibleModule
-
from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
create_backend,
- get_default_argspec,
+ create_default_argspec,
ACMEClient,
)
@@ -152,24 +151,23 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.utils import
def main():
- argument_spec = get_default_argspec()
- argument_spec.update(dict(
+ argument_spec = create_default_argspec(require_account_key=False)
+ argument_spec.update_argspec(
private_key_src=dict(type='path'),
private_key_content=dict(type='str', no_log=True),
private_key_passphrase=dict(type='str', no_log=True),
certificate=dict(type='path', required=True),
revoke_reason=dict(type='int'),
- ))
- module = AnsibleModule(
- argument_spec=argument_spec,
+ )
+ argument_spec.update(
required_one_of=(
['account_key_src', 'account_key_content', 'private_key_src', 'private_key_content'],
),
mutually_exclusive=(
['account_key_src', 'account_key_content', 'private_key_src', 'private_key_content'],
),
- supports_check_mode=False,
)
+ module = argument_spec.create_ansible_module()
backend = create_backend(module, False)
try:
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_challenge_cert_helper.py b/ansible_collections/community/crypto/plugins/modules/acme_challenge_cert_helper.py
index 48b65f998..edd2c3331 100644
--- a/ansible_collections/community/crypto/plugins/modules/acme_challenge_cert_helper.py
+++ b/ansible_collections/community/crypto/plugins/modules/acme_challenge_cert_helper.py
@@ -165,16 +165,16 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.io import (
read_file,
)
-from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
- get_now_datetime,
-)
-
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
set_not_valid_after,
set_not_valid_before,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_now_datetime,
+)
+
CRYPTOGRAPHY_IMP_ERR = None
try:
import cryptography
diff --git a/ansible_collections/community/crypto/plugins/modules/acme_inspect.py b/ansible_collections/community/crypto/plugins/modules/acme_inspect.py
index a2c76507e..c7ee49765 100644
--- a/ansible_collections/community/crypto/plugins/modules/acme_inspect.py
+++ b/ansible_collections/community/crypto/plugins/modules/acme_inspect.py
@@ -42,7 +42,8 @@ seealso:
description: The specification of the C(tls-alpn-01) challenge (RFC 8737).
link: https://www.rfc-editor.org/rfc/rfc8737.html
extends_documentation_fragment:
- - community.crypto.acme
+ - community.crypto.acme.basic
+ - community.crypto.acme.account
- community.crypto.attributes
- community.crypto.attributes.actiongroup_acme
attributes:
@@ -247,12 +248,11 @@ output_json:
- ...
'''
-from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native, to_bytes, to_text
from ansible_collections.community.crypto.plugins.module_utils.acme.acme import (
create_backend,
- get_default_argspec,
+ create_default_argspec,
ACMEClient,
)
@@ -263,18 +263,14 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.errors impor
def main():
- argument_spec = get_default_argspec()
- argument_spec.update(dict(
+ argument_spec = create_default_argspec(require_account_key=False)
+ argument_spec.update_argspec(
url=dict(type='str'),
method=dict(type='str', choices=['get', 'post', 'directory-only'], default='get'),
content=dict(type='str'),
fail_on_acme_error=dict(type='bool', default=True),
- ))
- module = AnsibleModule(
- argument_spec=argument_spec,
- mutually_exclusive=(
- ['account_key_src', 'account_key_content'],
- ),
+ )
+ argument_spec.update(
required_if=(
['method', 'get', ['url']],
['method', 'post', ['url', 'content']],
@@ -282,6 +278,7 @@ def main():
['method', 'post', ['account_key_src', 'account_key_content'], True],
),
)
+ module = argument_spec.create_ansible_module()
backend = create_backend(module, False)
result = dict()
diff --git a/ansible_collections/community/crypto/plugins/modules/ecs_certificate.py b/ansible_collections/community/crypto/plugins/modules/ecs_certificate.py
index 2c1238d48..0276556ab 100644
--- a/ansible_collections/community/crypto/plugins/modules/ecs_certificate.py
+++ b/ansible_collections/community/crypto/plugins/modules/ecs_certificate.py
@@ -938,8 +938,8 @@ def main():
module.fail_json(msg='The cert_expiry field is invalid when request_type="reissue".')
elif module.params['cert_lifetime']:
module.fail_json(msg='The cert_lifetime field is invalid when request_type="reissue".')
- # Only a reissued request can omit the CSR
- else:
+ # Reissued or renew request can omit the CSR
+ elif module.params['request_type'] != 'renew':
module_params_csr = module.params['csr']
if module_params_csr is None:
module.fail_json(msg='The csr field is required when request_type={0}'.format(module.params['request_type']))
diff --git a/ansible_collections/community/crypto/plugins/modules/get_certificate.py b/ansible_collections/community/crypto/plugins/modules/get_certificate.py
index 6ae9439d3..d4b38afbd 100644
--- a/ansible_collections/community/crypto/plugins/modules/get_certificate.py
+++ b/ansible_collections/community/crypto/plugins/modules/get_certificate.py
@@ -220,10 +220,6 @@ from ansible.module_utils.common.text.converters import to_bytes
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
-from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
- get_now_datetime,
-)
-
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
cryptography_oid_to_name,
@@ -232,6 +228,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
get_not_valid_before,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_now_datetime,
+)
+
MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
CREATE_DEFAULT_CONTEXT_IMP_ERR = None
diff --git a/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py b/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py
index 8379937f7..9e8c20e29 100644
--- a/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py
+++ b/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py
@@ -406,10 +406,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.basic impo
OpenSSLObjectError,
)
-from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
- get_relative_time_option,
-)
-
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
)
@@ -418,6 +414,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
select_backend,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_relative_time_option,
+)
+
def main():
module = AnsibleModule(
diff --git a/ansible_collections/community/crypto/plugins/modules/x509_crl.py b/ansible_collections/community/crypto/plugins/modules/x509_crl.py
index 527975b88..f8eb8d85e 100644
--- a/ansible_collections/community/crypto/plugins/modules/x509_crl.py
+++ b/ansible_collections/community/crypto/plugins/modules/x509_crl.py
@@ -470,7 +470,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
load_certificate,
parse_name_field,
parse_ordered_name_field,
- get_relative_time_option,
select_message_digest,
)
@@ -506,6 +505,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.module_bac
get_crl_info,
)
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ get_relative_time_option,
+)
+
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2'
CRYPTOGRAPHY_IMP_ERR = None
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/aliases b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/aliases
new file mode 100644
index 000000000..b7f6d4f48
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/generic/1
+azp/posix/1
+cloud/acme
+
+# For some reason connecting to helper containers does not work on the Alpine VMs
+skip/alpine
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/meta/main.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/meta/main.yml
new file mode 100644
index 000000000..2e8ad10b8
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_acme
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/impl.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/impl.yml
new file mode 100644
index 000000000..28a889684
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/impl.yml
@@ -0,0 +1,154 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- vars:
+ certificate_name: cert-1
+ subject_alt_name: DNS:example.com
+ account_email: example@example.org
+ block:
+ - name: Generate account key
+ openssl_privatekey:
+ path: "{{ remote_tmp_dir }}/account-ec256.pem"
+ type: ECC
+ curve: secp256r1
+ force: true
+ - name: Create cert private key
+ openssl_privatekey:
+ path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
+ type: ECC
+ curve: secp256r1
+ force: true
+ - name: Create cert CSR
+ openssl_csr:
+ path: "{{ remote_tmp_dir }}/{{ certificate_name }}.csr"
+ privatekey_path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
+ subject_alt_name: "{{ subject_alt_name }}"
+ - name: Start process of obtaining certificate
+ acme_certificate:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ modify_account: true
+ csr: "{{ remote_tmp_dir }}/{{ certificate_name }}.csr"
+ dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem"
+ challenge: http-01
+ force: true
+ terms_agreed: true
+ account_email: "{{ account_email }}"
+ register: certificate_data
+
+- name: Inspect order
+ acme_inspect:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ url: "{{ certificate_data.order_uri }}"
+ method: get
+ register: order_1
+- name: Show order
+ debug:
+ var: order_1.output_json
+
+- name: Deactivate order (check mode)
+ acme_certificate_deactivate_authz:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ order_uri: "{{ certificate_data.order_uri }}"
+ check_mode: true
+ register: deactivate_1
+
+- name: Inspect order again
+ acme_inspect:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ url: "{{ certificate_data.order_uri }}"
+ method: get
+ register: order_2
+- name: Show order
+ debug:
+ var: order_2.output_json
+
+- name: Deactivate order
+ acme_certificate_deactivate_authz:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ order_uri: "{{ certificate_data.order_uri }}"
+ register: deactivate_2
+
+- name: Inspect order again
+ acme_inspect:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ url: "{{ certificate_data.order_uri }}"
+ method: get
+ register: order_3
+- name: Show order
+ debug:
+ var: order_3.output_json
+
+- name: Deactivate order (check mode, idempotent)
+ acme_certificate_deactivate_authz:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ order_uri: "{{ certificate_data.order_uri }}"
+ check_mode: true
+ register: deactivate_3
+
+- name: Inspect order again
+ acme_inspect:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ url: "{{ certificate_data.order_uri }}"
+ method: get
+ register: order_4
+- name: Show order
+ debug:
+ var: order_4.output_json
+
+- name: Deactivate order (idempotent)
+ acme_certificate_deactivate_authz:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ order_uri: "{{ certificate_data.order_uri }}"
+ register: deactivate_4
+
+- name: Inspect order again
+ acme_inspect:
+ acme_directory: https://{{ acme_host }}:14000/dir
+ acme_version: 2
+ validate_certs: false
+ account_key_src: "{{ remote_tmp_dir }}/account-ec256.pem"
+ account_uri: "{{ certificate_data.account_uri }}"
+ url: "{{ certificate_data.order_uri }}"
+ method: get
+ register: order_5
+- name: Show order
+ debug:
+ var: order_5.output_json
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/main.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/main.yml
new file mode 100644
index 000000000..68d47973d
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tasks/main.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+- block:
+ - name: Running tests with OpenSSL backend
+ include_tasks: impl.yml
+ vars:
+ select_crypto_backend: openssl
+
+ - import_tasks: ../tests/validate.yml
+
+ # Old 0.9.8 versions have insufficient CLI support for signing with EC keys
+ when: openssl_version.stdout is version('1.0.0', '>=')
+
+- name: Remove output directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+
+- name: Re-create output directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: directory
+
+- block:
+ - name: Running tests with cryptography backend
+ include_tasks: impl.yml
+ vars:
+ select_crypto_backend: cryptography
+
+ - import_tasks: ../tests/validate.yml
+
+ when: cryptography_version.stdout is version('1.5', '>=')
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml
new file mode 100644
index 000000000..603c7d7cc
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_deactivate_authz/tests/validate.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Checks
+ assert:
+ that:
+ - order_1.output_json.status == 'pending'
+ - deactivate_1 is changed
+ - order_2.output_json.status == 'pending'
+ - deactivate_2 is changed
+ - order_3.output_json.status == 'deactivated'
+ - deactivate_3 is not changed
+ - order_4.output_json.status == 'deactivated'
+ - deactivate_4 is not changed
+ - order_5.output_json.status == 'deactivated'
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/aliases b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/aliases
new file mode 100644
index 000000000..b7f6d4f48
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/generic/1
+azp/posix/1
+cloud/acme
+
+# For some reason connecting to helper containers does not work on the Alpine VMs
+skip/alpine
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/meta/main.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/meta/main.yml
new file mode 100644
index 000000000..2e8ad10b8
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_acme
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/impl.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/impl.yml
new file mode 100644
index 000000000..b30808ed5
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/impl.yml
@@ -0,0 +1,145 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## SET UP ACCOUNT KEYS ########################################################################
+- block:
+ - name: Generate account keys
+ openssl_privatekey:
+ path: "{{ remote_tmp_dir }}/{{ item.name }}.pem"
+ type: "{{ item.type }}"
+ size: "{{ item.size | default(omit) }}"
+ curve: "{{ item.curve | default(omit) }}"
+ force: true
+ loop: "{{ account_keys }}"
+
+ vars:
+ account_keys:
+ - name: account-ec256
+ type: ECC
+ curve: secp256r1
+## CREATE ACCOUNTS AND OBTAIN CERTIFICATES ####################################################
+- name: Obtain cert 1
+ include_tasks: obtain-cert.yml
+ vars:
+ certgen_title: Certificate 1 for renewal check
+ certificate_name: cert-1
+ key_type: rsa
+ rsa_bits: "{{ default_rsa_key_size }}"
+ subject_alt_name: "DNS:example.com"
+ subject_alt_name_critical: false
+ account_key: account-ec256
+ challenge: http-01
+ modify_account: true
+ deactivate_authzs: false
+ force: true
+ remaining_days: "{{ omit }}"
+ terms_agreed: true
+ account_email: "example@example.org"
+## OBTAIN CERTIFICATE INFOS ###################################################################
+- name: Dump OpenSSL x509 info
+ command:
+ cmd: openssl x509 -in {{ remote_tmp_dir }}/cert-1.pem -noout -text
+- name: Obtain certificate information
+ x509_certificate_info:
+ path: "{{ remote_tmp_dir }}/cert-1.pem"
+ register: cert_1_info
+- name: Read certificate
+ slurp:
+ src: '{{ remote_tmp_dir }}/cert-1.pem'
+ register: slurp_cert_1
+- name: Obtain certificate information (1/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-1.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ # Certificate is valid for ~1826 days
+ register: cert_1_renewal_1
+- name: Obtain certificate information (2/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-1.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ # Certificate is valid for ~1826 days
+ remaining_days: 1000
+ remaining_percentage: 0.5
+ register: cert_1_renewal_2
+- name: Obtain certificate information (3/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_content: "{{ slurp_cert_1.content | b64decode }}"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ now: +1800d
+ # Certificate is valid for ~26 days
+ register: cert_1_renewal_3
+- name: Obtain certificate information (4/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-1.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ now: +1800d
+ # Certificate is valid for ~26 days
+ remaining_days: 30
+ remaining_percentage: 0.1
+ register: cert_1_renewal_4
+- name: Obtain certificate information (5/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-1.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ now: +1800d
+ # Certificate is valid for ~26 days
+ remaining_days: 30
+ remaining_percentage: 0.01
+ register: cert_1_renewal_5
+- name: Obtain certificate information (6/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-1.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ now: +1800d
+ # Certificate is valid for ~26 days
+ remaining_days: 10
+ remaining_percentage: 0.03
+ register: cert_1_renewal_6
+- name: Obtain certificate information (7/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-1.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ now: +1830d
+ # Certificate is no longer valid
+ register: cert_1_renewal_7
+- name: Obtain certificate information (8/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ now: +1830d
+ # Certificate is no longer valid
+ register: cert_1_renewal_8
+- name: Obtain certificate information (9/9)
+ acme_certificate_renewal_info:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ certificate_path: "{{ remote_tmp_dir }}/cert-does-not-exist.pem"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ # Certificate is no longer valid
+ register: cert_1_renewal_9
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/main.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/main.yml
new file mode 100644
index 000000000..68d47973d
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/main.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+- block:
+ - name: Running tests with OpenSSL backend
+ include_tasks: impl.yml
+ vars:
+ select_crypto_backend: openssl
+
+ - import_tasks: ../tests/validate.yml
+
+ # Old 0.9.8 versions have insufficient CLI support for signing with EC keys
+ when: openssl_version.stdout is version('1.0.0', '>=')
+
+- name: Remove output directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+
+- name: Re-create output directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: directory
+
+- block:
+ - name: Running tests with cryptography backend
+ include_tasks: impl.yml
+ vars:
+ select_crypto_backend: cryptography
+
+ - import_tasks: ../tests/validate.yml
+
+ when: cryptography_version.stdout is version('1.5', '>=')
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/obtain-cert.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/obtain-cert.yml
new file mode 100644
index 000000000..6882e5339
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tasks/obtain-cert.yml
@@ -0,0 +1,159 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## PRIVATE KEY ################################################################################
+- name: ({{ certgen_title }}) Create cert private key
+ openssl_privatekey:
+ path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
+ type: "{{ 'RSA' if key_type == 'rsa' else 'ECC' }}"
+ size: "{{ rsa_bits if key_type == 'rsa' else omit }}"
+ curve: >-
+ {{ omit if key_type == 'rsa' else
+ 'secp256r1' if key_type == 'ec256' else
+ 'secp384r1' if key_type == 'ec384' else
+ 'secp521r1' if key_type == 'ec521' else
+ 'invalid value for key_type!' }}
+ passphrase: "{{ certificate_passphrase | default(omit) | default(omit, true) }}"
+ cipher: "{{ 'auto' if certificate_passphrase | default() else omit }}"
+ force: true
+## CSR ########################################################################################
+- name: ({{ certgen_title }}) Create cert CSR
+ openssl_csr:
+ path: "{{ remote_tmp_dir }}/{{ certificate_name }}.csr"
+ privatekey_path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
+ privatekey_passphrase: "{{ certificate_passphrase | default(omit) | default(omit, true) }}"
+ subject_alt_name: "{{ subject_alt_name }}"
+ subject_alt_name_critical: "{{ subject_alt_name_critical }}"
+ return_content: true
+ register: csr_result
+## ACME STEP 1 ################################################################################
+- name: ({{ certgen_title }}) Obtain cert, step 1
+ acme_certificate:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ account_key: "{{ (remote_tmp_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}"
+ account_key_content: "{{ account_key_content | default(omit) }}"
+ account_key_passphrase: "{{ account_key_passphrase | default(omit) | default(omit, true) }}"
+ modify_account: "{{ modify_account }}"
+ csr: "{{ omit if use_csr_content | default(false) else remote_tmp_dir ~ '/' ~ certificate_name ~ '.csr' }}"
+ csr_content: "{{ csr_result.csr if use_csr_content | default(false) else omit }}"
+ dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem"
+ fullchain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-fullchain.pem"
+ chain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-chain.pem"
+ challenge: "{{ challenge }}"
+ deactivate_authzs: "{{ deactivate_authzs }}"
+ force: "{{ force }}"
+ remaining_days: "{{ remaining_days }}"
+ terms_agreed: "{{ terms_agreed }}"
+ account_email: "{{ account_email }}"
+ register: challenge_data
+- name: ({{ certgen_title }}) Print challenge data
+ debug:
+ var: challenge_data
+- name: ({{ certgen_title }}) Create HTTP challenges
+ uri:
+ url: "http://{{ acme_host }}:5000/http/{{ item.key }}/{{ item.value['http-01'].resource[('.well-known/acme-challenge/'|length):] }}"
+ method: PUT
+ body_format: raw
+ body: "{{ item.value['http-01'].resource_value }}"
+ headers:
+ content-type: "application/octet-stream"
+ with_dict: "{{ challenge_data.challenge_data }}"
+ when: "challenge_data is changed and challenge == 'http-01'"
+- name: ({{ certgen_title }}) Create DNS challenges
+ uri:
+ url: "http://{{ acme_host }}:5000/dns/{{ item.key }}"
+ method: PUT
+ body_format: json
+ body: "{{ item.value }}"
+ with_dict: "{{ challenge_data.challenge_data_dns }}"
+ when: "challenge_data is changed and challenge == 'dns-01'"
+- name: ({{ certgen_title }}) Create TLS ALPN challenges (acme_challenge_cert_helper)
+ acme_challenge_cert_helper:
+ challenge: tls-alpn-01
+ challenge_data: "{{ item.value['tls-alpn-01'] }}"
+ private_key_src: "{{ remote_tmp_dir }}/{{ certificate_name }}.key"
+ private_key_passphrase: "{{ certificate_passphrase | default(omit) | default(omit, true) }}"
+ with_dict: "{{ challenge_data.challenge_data if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper') else {} }}"
+ register: tls_alpn_challenges
+ when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper')"
+- name: ({{ certgen_title }}) Read private key
+ slurp:
+ src: '{{ remote_tmp_dir }}/{{ certificate_name }}.key'
+ register: slurp
+ when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper')"
+- name: ({{ certgen_title }}) Set TLS ALPN challenges (acme_challenge_cert_helper)
+ uri:
+ url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.domain }}/{{ item.identifier }}/certificate-and-key"
+ method: PUT
+ body_format: raw
+ body: "{{ item.challenge_certificate }}\n{{ slurp.content | b64decode }}"
+ headers:
+ content-type: "application/pem-certificate-chain"
+ with_items: "{{ tls_alpn_challenges.results if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper') else [] }}"
+ when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper')"
+- name: ({{ certgen_title }}) Create TLS ALPN challenges (der-value-b64)
+ uri:
+ url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.value['tls-alpn-01'].resource }}/{{ item.value['tls-alpn-01'].resource_original }}/der-value-b64"
+ method: PUT
+ body_format: raw
+ body: "{{ item.value['tls-alpn-01'].resource_value }}"
+ headers:
+ content-type: "application/octet-stream"
+ with_dict: "{{ challenge_data.challenge_data if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'der-value-b64') else {} }}"
+ when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'der-value-b64')"
+## ACME STEP 2 ################################################################################
+- name: ({{ certgen_title }}) Obtain cert, step 2
+ acme_certificate:
+ select_crypto_backend: "{{ select_crypto_backend }}"
+ acme_version: 2
+ acme_directory: https://{{ acme_host }}:14000/dir
+ validate_certs: false
+ account_key: "{{ (remote_tmp_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}"
+ account_key_content: "{{ account_key_content | default(omit) }}"
+ account_key_passphrase: "{{ account_key_passphrase | default(omit) | default(omit, true) }}"
+ account_uri: "{{ challenge_data.account_uri }}"
+ modify_account: "{{ modify_account }}"
+ csr: "{{ omit if use_csr_content | default(false) else remote_tmp_dir ~ '/' ~ certificate_name ~ '.csr' }}"
+ csr_content: "{{ csr_result.csr if use_csr_content | default(false) else omit }}"
+ dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem"
+ fullchain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-fullchain.pem"
+ chain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-chain.pem"
+ challenge: "{{ challenge }}"
+ deactivate_authzs: "{{ deactivate_authzs }}"
+ force: "{{ force }}"
+ remaining_days: "{{ remaining_days }}"
+ terms_agreed: "{{ terms_agreed }}"
+ account_email: "{{ account_email }}"
+ data: "{{ challenge_data }}"
+ retrieve_all_alternates: "{{ retrieve_all_alternates | default(omit) }}"
+ select_chain: "{{ select_chain | default(omit) if select_crypto_backend == 'cryptography' else omit }}"
+ register: certificate_obtain_result
+ when: challenge_data is changed
+- name: ({{ certgen_title }}) Deleting HTTP challenges
+ uri:
+ url: "http://{{ acme_host }}:5000/http/{{ item.key }}/{{ item.value['http-01'].resource[('.well-known/acme-challenge/'|length):] }}"
+ method: DELETE
+ with_dict: "{{ challenge_data.challenge_data }}"
+ when: "challenge_data is changed and challenge == 'http-01'"
+- name: ({{ certgen_title }}) Deleting DNS challenges
+ uri:
+ url: "http://{{ acme_host }}:5000/dns/{{ item.key }}"
+ method: DELETE
+ with_dict: "{{ challenge_data.challenge_data_dns }}"
+ when: "challenge_data is changed and challenge == 'dns-01'"
+- name: ({{ certgen_title }}) Deleting TLS ALPN challenges
+ uri:
+ url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.value['tls-alpn-01'].resource }}"
+ method: DELETE
+ with_dict: "{{ challenge_data.challenge_data }}"
+ when: "challenge_data is changed and challenge == 'tls-alpn-01'"
+- name: ({{ certgen_title }}) Get root certificate
+ get_url:
+ url: "http://{{ acme_host }}:5000/root-certificate-for-ca/{{ acme_expected_root_number | default(0) if select_crypto_backend == 'cryptography' else 0 }}"
+ dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-root.pem"
+###############################################################################################
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tests/validate.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tests/validate.yml
new file mode 100644
index 000000000..116e524c4
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_certificate_renewal_info/tests/validate.yml
@@ -0,0 +1,47 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Validate results
+ assert:
+ that:
+ - cert_1_renewal_1.should_renew == false
+ - cert_1_renewal_1.msg == 'The certificate is still valid and no condition was reached'
+ - cert_1_renewal_1.supports_ari == supports_ari
+ - cert_1_renewal_1.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_2.should_renew == false
+ - cert_1_renewal_2.msg == 'The certificate is still valid and no condition was reached'
+ - cert_1_renewal_2.supports_ari == supports_ari
+ - cert_1_renewal_2.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_3.should_renew == false
+ - cert_1_renewal_3.msg == 'The certificate is still valid and no condition was reached'
+ - cert_1_renewal_3.supports_ari == supports_ari
+ - cert_1_renewal_3.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_4.should_renew == true
+ - cert_1_renewal_4.msg == 'The certificate expires in 25 days'
+ - cert_1_renewal_4.supports_ari == supports_ari
+ - cert_1_renewal_4.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_5.should_renew == true
+ - cert_1_renewal_5.msg == 'The certificate expires in 25 days'
+ - cert_1_renewal_5.supports_ari == supports_ari
+ - cert_1_renewal_5.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_6.should_renew == true
+ - cert_1_renewal_6.msg.startswith("The remaining percentage 3.0% of the certificate's lifespan was reached on ")
+ - cert_1_renewal_6.supports_ari == supports_ari
+ - cert_1_renewal_6.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_7.should_renew == true
+ - cert_1_renewal_7.msg == 'The certificate has already expired'
+ - cert_1_renewal_7.supports_ari == false
+ - cert_1_renewal_7.cert_id is string or not can_have_cert_id
+ - cert_1_renewal_8.should_renew == true
+ - cert_1_renewal_8.msg == 'No certificate was specified'
+ - cert_1_renewal_8.supports_ari == false
+ - cert_1_renewal_8.cert_id is not defined
+ - cert_1_renewal_9.should_renew == true
+ - cert_1_renewal_9.msg == 'The certificate file does not exist'
+ - cert_1_renewal_9.supports_ari == false
+ - cert_1_renewal_9.cert_id is not defined
+ vars:
+ can_have_cert_id: cert_1_info.authority_key_identifier is string
+ supports_ari: false
diff --git a/ansible_collections/community/crypto/tests/integration/targets/acme_inspect/tasks/impl.yml b/ansible_collections/community/crypto/tests/integration/targets/acme_inspect/tasks/impl.yml
index 4eed1031a..d87501884 100644
--- a/ansible_collections/community/crypto/tests/integration/targets/acme_inspect/tasks/impl.yml
+++ b/ansible_collections/community/crypto/tests/integration/targets/acme_inspect/tasks/impl.yml
@@ -28,6 +28,7 @@
acme_version: 2
validate_certs: false
method: directory-only
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: directory
- debug: var=directory
@@ -40,6 +41,7 @@
url: "{{ directory.directory.newAccount}}"
method: post
content: '{"termsOfServiceAgreed":true}'
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: account_creation
# account_creation.headers.location contains the account URI
# if creation was successful
@@ -54,6 +56,7 @@
account_uri: "{{ account_creation.headers.location }}"
url: "{{ account_creation.headers.location }}"
method: get
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: account_get
- debug: var=account_get
@@ -67,6 +70,7 @@
url: "{{ account_creation.headers.location }}"
method: post
content: '{{ account_info | to_json }}'
+ select_crypto_backend: "{{ select_crypto_backend }}"
vars:
account_info:
# For valid values, see
@@ -86,6 +90,7 @@
url: "{{ directory.directory.newOrder }}"
method: post
content: '{{ create_order | to_json }}'
+ select_crypto_backend: "{{ select_crypto_backend }}"
vars:
create_order:
# For valid values, see
@@ -108,6 +113,7 @@
account_uri: "{{ account_creation.headers.location }}"
url: "{{ new_order.headers.location }}"
method: get
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: order
- debug: var=order
@@ -120,6 +126,7 @@
account_uri: "{{ account_creation.headers.location }}"
url: "{{ item }}"
method: get
+ select_crypto_backend: "{{ select_crypto_backend }}"
loop: "{{ order.output_json.authorizations }}"
register: authz
- debug: var=authz
@@ -133,6 +140,7 @@
account_uri: "{{ account_creation.headers.location }}"
url: "{{ (item.challenges | selectattr('type', 'equalto', 'http-01') | list)[0].url }}"
method: get
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: http01challenge
loop: "{{ authz.results | map(attribute='output_json') | list }}"
- debug: var=http01challenge
@@ -147,6 +155,7 @@
url: "{{ item.url }}"
method: post
content: '{}'
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: activation
loop: "{{ http01challenge.results | map(attribute='output_json') | list }}"
- debug: var=activation
@@ -160,6 +169,7 @@
account_uri: "{{ account_creation.headers.location }}"
url: "{{ item.url }}"
method: get
+ select_crypto_backend: "{{ select_crypto_backend }}"
register: validation_result
loop: "{{ http01challenge.results | map(attribute='output_json') | list }}"
until: "validation_result.output_json.status not in ['pending', 'processing']"
diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/ownca.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/ownca.yml
index 99832a517..4bbd818ee 100644
--- a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/ownca.yml
+++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/ownca.yml
@@ -249,10 +249,24 @@
ownca_not_after: 20191023133742Z
path: "{{ remote_tmp_dir }}/ownca_cert3.pem"
csr_path: "{{ remote_tmp_dir }}/csr.csr"
- privatekey_path: "{{ remote_tmp_dir }}/privatekey3.pem"
+ privatekey_path: "{{ remote_tmp_dir }}/privatekey.pem"
+ ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
+ ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
+ select_crypto_backend: '{{ select_crypto_backend }}'
+
+- name: (OwnCA, {{select_crypto_backend}}) Create ownca certificate with notBefore and notAfter (idempotent)
+ x509_certificate:
+ provider: ownca
+ ownca_not_before: 20181023133742Z
+ ownca_not_after: 20191023133742Z
+ ignore_timestamps: false
+ path: "{{ remote_tmp_dir }}/ownca_cert3.pem"
+ csr_path: "{{ remote_tmp_dir }}/csr.csr"
+ privatekey_path: "{{ remote_tmp_dir }}/privatekey.pem"
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
select_crypto_backend: '{{ select_crypto_backend }}'
+ register: ownca_cert3_idem
- name: (OwnCA, {{select_crypto_backend}}) Create ownca certificate with relative notBefore and notAfter
x509_certificate:
diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/selfsigned.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/selfsigned.yml
index a0f23643b..eeea25ddd 100644
--- a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/selfsigned.yml
+++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tasks/selfsigned.yml
@@ -220,6 +220,18 @@
privatekey_path: "{{ remote_tmp_dir }}/privatekey3.pem"
select_crypto_backend: '{{ select_crypto_backend }}'
+- name: (Selfsigned, {{select_crypto_backend}}) Create certificate3 with notBefore and notAfter (idempotent)
+ x509_certificate:
+ provider: selfsigned
+ selfsigned_not_before: 20181023133742Z
+ selfsigned_not_after: 20191023133742Z
+ ignore_timestamps: false
+ path: "{{ remote_tmp_dir }}/cert3.pem"
+ csr_path: "{{ remote_tmp_dir }}/csr3.pem"
+ privatekey_path: "{{ remote_tmp_dir }}/privatekey3.pem"
+ select_crypto_backend: '{{ select_crypto_backend }}'
+ register: cert3_selfsigned_idem
+
- name: (Selfsigned, {{select_crypto_backend}}) Generate privatekey
openssl_privatekey:
path: '{{ remote_tmp_dir }}/privatekey_ecc.pem'
diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_ownca.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_ownca.yml
index ac25b6295..ade7e6f51 100644
--- a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_ownca.yml
+++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_ownca.yml
@@ -98,6 +98,11 @@
that:
- ownca_cert3_notAfter.stdout == 'Oct 23 13:37:42 2019'
+- name: (OwnCA validation, {{select_crypto_backend}}) Validate idempotency
+ assert:
+ that:
+ - ownca_cert3_idem is not changed
+
- name: (OwnCA validation, {{select_crypto_backend}}) Validate ownca ECC certificate (test - ownca certificate pubkey)
shell: '{{ openssl_binary }} x509 -noout -pubkey -in {{ remote_tmp_dir }}/ownca_cert_ecc.pem'
register: ownca_cert_ecc_pubkey
diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_selfsigned.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_selfsigned.yml
index c76310437..c7254eb3e 100644
--- a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_selfsigned.yml
+++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate/tests/validate_selfsigned.yml
@@ -139,6 +139,11 @@
that:
- cert3_notAfter.stdout == 'Oct 23 13:37:42 2019'
+- name: (Selfsigned validation, {{select_crypto_backend}}) Validate idempotency
+ assert:
+ that:
+ - cert3_selfsigned_idem is not changed
+
- name: (Selfsigned validation, {{select_crypto_backend}}) Validate ECC certificate (test - privatekey's pubkey)
shell: '{{ openssl_binary }} ec -pubout -in {{ remote_tmp_dir }}/privatekey_ecc.pem'
register: privatekey_ecc_pubkey
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/backend_data.py b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/backend_data.py
index 988bcdaeb..c4aa09a6a 100644
--- a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/backend_data.py
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/backend_data.py
@@ -9,8 +9,10 @@ __metaclass__ = type
import base64
import datetime
import os
+import sys
from ansible_collections.community.crypto.plugins.module_utils.acme.backends import (
+ CertificateInformation,
CryptoBackend,
)
@@ -79,6 +81,12 @@ TEST_CSRS = [
TEST_CERT = load_fixture("cert_1.pem")
+TEST_CERT_2 = load_fixture("cert_2.pem")
+
+
+TEST_CERT_OPENSSL_OUTPUT = load_fixture("cert_1.txt") # OpenSSL 3.3.0 output
+TEST_CERT_OPENSSL_OUTPUT_2 = load_fixture("cert_2.txt") # OpenSSL 3.3.0 output
+TEST_CERT_OPENSSL_OUTPUT_2B = load_fixture("cert_2-b.txt") # OpenSSL 1.1.1f output
TEST_CERT_DAYS = [
@@ -88,6 +96,81 @@ TEST_CERT_DAYS = [
]
+TEST_CERT_INFO = CertificateInformation(
+ not_valid_after=datetime.datetime(2018, 11, 26, 15, 28, 24),
+ not_valid_before=datetime.datetime(2018, 11, 25, 15, 28, 23),
+ serial_number=1,
+ subject_key_identifier=b'\x98\xD2\xFD\x3C\xCC\xCD\x69\x45\xFB\xE2\x8C\x30\x2C\x54\x62\x18\x34\xB7\x07\x73',
+ authority_key_identifier=None,
+)
+
+
+TEST_CERT_INFO_2 = CertificateInformation(
+ not_valid_before=datetime.datetime(2024, 5, 4, 20, 42, 21),
+ not_valid_after=datetime.datetime(2029, 5, 4, 20, 42, 20),
+ serial_number=4218235397573492796,
+ subject_key_identifier=b'\x17\xE5\x83\x22\x14\xEF\x74\xD3\xBE\x7E\x30\x76\x56\x1F\x51\x74\x65\x1F\xE9\xF0',
+ authority_key_identifier=b'\x13\xC3\x4C\x3E\x59\x45\xDD\xE3\x63\x51\xA3\x46\x80\xC4\x08\xC7\x14\xC0\x64\x4E',
+)
+
+
+TEST_CERT_INFO = [
+ (TEST_CERT, TEST_CERT_INFO, TEST_CERT_OPENSSL_OUTPUT),
+ (TEST_CERT_2, TEST_CERT_INFO_2, TEST_CERT_OPENSSL_OUTPUT_2),
+ (TEST_CERT_2, TEST_CERT_INFO_2, TEST_CERT_OPENSSL_OUTPUT_2B),
+]
+
+
+TEST_PARSE_ACME_TIMESTAMP = [
+ (
+ '2024-01-01T00:11:22Z',
+ dict(year=2024, month=1, day=1, hour=0, minute=11, second=22),
+ ),
+ (
+ '2024-01-01T00:11:22.123Z',
+ dict(year=2024, month=1, day=1, hour=0, minute=11, second=22, microsecond=123000),
+ ),
+ (
+ '2024-04-17T06:54:13.333333334Z',
+ dict(year=2024, month=4, day=17, hour=6, minute=54, second=13, microsecond=333333),
+ ),
+]
+
+if sys.version_info >= (3, 5):
+ TEST_PARSE_ACME_TIMESTAMP.extend([
+ (
+ '2024-01-01T00:11:22+0100',
+ dict(year=2023, month=12, day=31, hour=23, minute=11, second=22),
+ ),
+ (
+ '2024-01-01T00:11:22.123+0100',
+ dict(year=2023, month=12, day=31, hour=23, minute=11, second=22, microsecond=123000),
+ ),
+ ])
+
+
+TEST_INTERPOLATE_TIMESTAMP = [
+ (
+ dict(year=2024, month=1, day=1, hour=0, minute=0, second=0),
+ dict(year=2024, month=1, day=1, hour=1, minute=0, second=0),
+ 0.0,
+ dict(year=2024, month=1, day=1, hour=0, minute=0, second=0),
+ ),
+ (
+ dict(year=2024, month=1, day=1, hour=0, minute=0, second=0),
+ dict(year=2024, month=1, day=1, hour=1, minute=0, second=0),
+ 0.5,
+ dict(year=2024, month=1, day=1, hour=0, minute=30, second=0),
+ ),
+ (
+ dict(year=2024, month=1, day=1, hour=0, minute=0, second=0),
+ dict(year=2024, month=1, day=1, hour=1, minute=0, second=0),
+ 1.0,
+ dict(year=2024, month=1, day=1, hour=1, minute=0, second=0),
+ ),
+]
+
+
class FakeBackend(CryptoBackend):
def parse_key(self, key_file=None, key_content=None, passphrase=None):
raise BackendException('Not implemented in fake backend')
@@ -98,6 +181,9 @@ class FakeBackend(CryptoBackend):
def create_mac_key(self, alg, key):
raise BackendException('Not implemented in fake backend')
+ def get_ordered_csr_identifiers(self, csr_filename=None, csr_content=None):
+ raise BackendException('Not implemented in fake backend')
+
def get_csr_identifiers(self, csr_filename=None, csr_content=None):
raise BackendException('Not implemented in fake backend')
@@ -106,3 +192,6 @@ class FakeBackend(CryptoBackend):
def create_chain_matcher(self, criterium):
raise BackendException('Not implemented in fake backend')
+
+ def get_cert_information(self, cert_filename=None, cert_content=None):
+ raise BackendException('Not implemented in fake backend')
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt
new file mode 100644
index 000000000..e989d914d
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt
@@ -0,0 +1,38 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN=ansible.com
+ Validity
+ Not Before: Nov 25 15:28:23 2018 GMT
+ Not After : Nov 26 15:28:24 2018 GMT
+ Subject: CN=ansible.com
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:00:9c:f4:c8:00:17:03:01:26:3a:14:d1:92:35:
+ f1:c2:07:9d:6d:63:ba:82:86:d8:33:79:56:b3:3a:
+ d2:eb:c1:bc:41:2c:e1:5d:1e:80:99:0d:c8:cd:90:
+ e2:9a:74:d3:5c:ee:d7:85:5c:a5:0d:3f:12:2f:31:
+ 38:e3:f1:29:9b
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ X509v3 extensions:
+ X509v3 Subject Alternative Name:
+ DNS:example.com, DNS:example.org
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Key Usage: critical
+ Digital Signature
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 Subject Key Identifier:
+ 98:D2:FD:3C:CC:CD:69:45:FB:E2:8C:30:2C:54:62:18:34:B7:07:73
+ Signature Algorithm: ecdsa-with-SHA256
+ Signature Value:
+ 30:46:02:21:00:bc:fb:52:bf:7a:93:2d:0e:7c:ce:43:f4:cc:
+ 05:98:28:36:8d:c7:2a:9b:f5:20:94:62:3d:fb:82:9e:38:42:
+ 32:02:21:00:c0:55:f8:b5:d9:65:41:2a:dd:d4:76:3f:8c:cb:
+ 07:c1:d2:b9:c0:7d:c9:90:af:fd:f9:f1:b0:c9:13:f5:d5:52
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt.license b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_1.txt.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt
new file mode 100644
index 000000000..78326443b
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt
@@ -0,0 +1,57 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4218235397573492796 (0x3a8a2ebeb358c03c)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN = Pebble Intermediate CA 734609
+ Validity
+ Not Before: May 4 20:42:21 2024 GMT
+ Not After : May 4 20:42:20 2029 GMT
+ Subject: CN = example.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (1024 bit)
+ Modulus:
+ 00:c1:43:a5:f9:ad:00:b7:bb:1b:73:27:00:b3:a2:
+ 4e:27:0d:ff:ae:64:3e:a0:7e:f9:28:56:48:47:21:
+ 9e:0f:d8:fb:69:b5:21:e8:98:84:60:6c:aa:73:b9:
+ 6e:d9:f6:19:ad:85:e0:c2:f6:80:d3:22:b8:5a:d6:
+ 3a:89:3e:2a:7a:fc:1d:bf:fc:69:20:e5:91:b8:34:
+ 52:26:c8:15:74:e1:36:0c:cd:ab:01:4a:ad:83:f5:
+ 0b:77:96:31:cf:1c:ea:6f:88:75:23:ac:51:a6:d8:
+ 77:43:1b:b3:44:93:2c:8d:05:25:fb:77:41:36:94:
+ 81:d5:ca:56:ff:b5:23:b2:a5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 17:E5:83:22:14:EF:74:D3:BE:7E:30:76:56:1F:51:74:65:1F:E9:F0
+ X509v3 Authority Key Identifier:
+ keyid:13:C3:4C:3E:59:45:DD:E3:63:51:A3:46:80:C4:08:C7:14:C0:64:4E
+
+ Authority Information Access:
+ OCSP - URI:http://10.88.0.74:5000/ocsp
+
+ X509v3 Subject Alternative Name:
+ DNS:example.com
+ Signature Algorithm: sha256WithRSAEncryption
+ 31:43:de:b6:48:f4:b8:30:46:25:65:e6:91:22:33:1b:d1:ba:
+ 3f:60:f8:c3:18:32:72:e9:f8:d1:88:11:5a:0a:86:dc:1d:6d:
+ a5:ea:58:cd:05:ea:cd:5e:40:86:c1:ae:d5:cd:2e:8a:ca:50:
+ ee:df:bd:cf:6c:d9:20:3b:4b:49:f8:d5:8a:e3:be:f3:dd:24:
+ b2:7f:3f:3b:bf:e6:8d:7a:f8:8f:4b:6e:25:60:80:33:6f:0f:
+ 53:b7:7d:94:2a:d2:4a:db:3a:2f:70:79:d7:bf:05:ed:df:10:
+ 61:e7:24:ac:b2:fc:03:bd:ad:8c:e1:f3:1d:cc:78:99:e3:22:
+ 59:bf:c5:92:57:95:92:56:35:fc:05:8b:26:10:c5:1b:87:17:
+ 64:0b:bd:33:a9:54:d5:c0:2b:43:56:1b:52:d3:4f:8b:6f:25:
+ 06:58:7f:6f:aa:27:35:05:d5:57:6d:83:a0:73:de:40:3f:67:
+ 1c:5a:92:c6:37:e6:8f:c7:b8:91:d7:50:b9:4d:d4:f2:92:1f:
+ 8b:93:0c:e2:b4:b8:d7:1d:8e:ce:6d:19:dc:8f:12:8e:c0:f2:
+ 92:3b:95:5a:8c:c8:69:0e:0b:f7:fa:1f:55:62:80:7c:e2:f6:
+ 41:3f:7d:69:36:9e:7c:90:7e:d7:3b:e6:a3:15:de:a4:7d:95:
+ 13:46:c6:1a
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt.license b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2-b.txt.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem
new file mode 100644
index 000000000..92aecb621
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDDjCCAfagAwIBAgIIOoouvrNYwDwwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UE
+AxMdUGViYmxlIEludGVybWVkaWF0ZSBDQSA3MzQ2MDkwHhcNMjQwNTA0MjA0MjIx
+WhcNMjkwNTA0MjA0MjIwWjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCBnzANBgkq
+hkiG9w0BAQEFAAOBjQAwgYkCgYEAwUOl+a0At7sbcycAs6JOJw3/rmQ+oH75KFZI
+RyGeD9j7abUh6JiEYGyqc7lu2fYZrYXgwvaA0yK4WtY6iT4qevwdv/xpIOWRuDRS
+JsgVdOE2DM2rAUqtg/ULd5Yxzxzqb4h1I6xRpth3QxuzRJMsjQUl+3dBNpSB1cpW
+/7UjsqUCAwEAAaOB0TCBzjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBflgyIU73TT
+vn4wdlYfUXRlH+nwMB8GA1UdIwQYMBaAFBPDTD5ZRd3jY1GjRoDECMcUwGROMDcG
+CCsGAQUFBwEBBCswKTAnBggrBgEFBQcwAYYbaHR0cDovLzEwLjg4LjAuNzQ6NTAw
+MC9vY3NwMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IB
+AQAxQ962SPS4MEYlZeaRIjMb0bo/YPjDGDJy6fjRiBFaCobcHW2l6ljNBerNXkCG
+wa7VzS6KylDu373PbNkgO0tJ+NWK477z3SSyfz87v+aNeviPS24lYIAzbw9Tt32U
+KtJK2zovcHnXvwXt3xBh5ySssvwDva2M4fMdzHiZ4yJZv8WSV5WSVjX8BYsmEMUb
+hxdkC70zqVTVwCtDVhtS00+LbyUGWH9vqic1BdVXbYOgc95AP2ccWpLGN+aPx7iR
+11C5TdTykh+LkwzitLjXHY7ObRncjxKOwPKSO5VajMhpDgv3+h9VYoB84vZBP31p
+Np58kH7XO+ajFd6kfZUTRsYa
+-----END CERTIFICATE-----
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem.license b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.pem.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt
new file mode 100644
index 000000000..3cda74955
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt
@@ -0,0 +1,56 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4218235397573492796 (0x3a8a2ebeb358c03c)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Pebble Intermediate CA 734609
+ Validity
+ Not Before: May 4 20:42:21 2024 GMT
+ Not After : May 4 20:42:20 2029 GMT
+ Subject: CN=example.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (1024 bit)
+ Modulus:
+ 00:c1:43:a5:f9:ad:00:b7:bb:1b:73:27:00:b3:a2:
+ 4e:27:0d:ff:ae:64:3e:a0:7e:f9:28:56:48:47:21:
+ 9e:0f:d8:fb:69:b5:21:e8:98:84:60:6c:aa:73:b9:
+ 6e:d9:f6:19:ad:85:e0:c2:f6:80:d3:22:b8:5a:d6:
+ 3a:89:3e:2a:7a:fc:1d:bf:fc:69:20:e5:91:b8:34:
+ 52:26:c8:15:74:e1:36:0c:cd:ab:01:4a:ad:83:f5:
+ 0b:77:96:31:cf:1c:ea:6f:88:75:23:ac:51:a6:d8:
+ 77:43:1b:b3:44:93:2c:8d:05:25:fb:77:41:36:94:
+ 81:d5:ca:56:ff:b5:23:b2:a5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 17:E5:83:22:14:EF:74:D3:BE:7E:30:76:56:1F:51:74:65:1F:E9:F0
+ X509v3 Authority Key Identifier:
+ 13:C3:4C:3E:59:45:DD:E3:63:51:A3:46:80:C4:08:C7:14:C0:64:4E
+ Authority Information Access:
+ OCSP - URI:http://10.88.0.74:5000/ocsp
+ X509v3 Subject Alternative Name:
+ DNS:example.com
+ Signature Algorithm: sha256WithRSAEncryption
+ Signature Value:
+ 31:43:de:b6:48:f4:b8:30:46:25:65:e6:91:22:33:1b:d1:ba:
+ 3f:60:f8:c3:18:32:72:e9:f8:d1:88:11:5a:0a:86:dc:1d:6d:
+ a5:ea:58:cd:05:ea:cd:5e:40:86:c1:ae:d5:cd:2e:8a:ca:50:
+ ee:df:bd:cf:6c:d9:20:3b:4b:49:f8:d5:8a:e3:be:f3:dd:24:
+ b2:7f:3f:3b:bf:e6:8d:7a:f8:8f:4b:6e:25:60:80:33:6f:0f:
+ 53:b7:7d:94:2a:d2:4a:db:3a:2f:70:79:d7:bf:05:ed:df:10:
+ 61:e7:24:ac:b2:fc:03:bd:ad:8c:e1:f3:1d:cc:78:99:e3:22:
+ 59:bf:c5:92:57:95:92:56:35:fc:05:8b:26:10:c5:1b:87:17:
+ 64:0b:bd:33:a9:54:d5:c0:2b:43:56:1b:52:d3:4f:8b:6f:25:
+ 06:58:7f:6f:aa:27:35:05:d5:57:6d:83:a0:73:de:40:3f:67:
+ 1c:5a:92:c6:37:e6:8f:c7:b8:91:d7:50:b9:4d:d4:f2:92:1f:
+ 8b:93:0c:e2:b4:b8:d7:1d:8e:ce:6d:19:dc:8f:12:8e:c0:f2:
+ 92:3b:95:5a:8c:c8:69:0e:0b:f7:fa:1f:55:62:80:7c:e2:f6:
+ 41:3f:7d:69:36:9e:7c:90:7e:d7:3b:e6:a3:15:de:a4:7d:95:
+ 13:46:c6:1a
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt.license b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/fixtures/cert_2.txt.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_cryptography.py b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_cryptography.py
index 59da68a3b..9186e2430 100644
--- a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_cryptography.py
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_cryptography.py
@@ -16,11 +16,22 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.backend_cryp
CryptographyBackend,
)
+from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
+ ensure_utc_timezone,
+)
+
+from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
+ CRYPTOGRAPHY_TIMEZONE,
+)
+
from .backend_data import (
TEST_KEYS,
TEST_CSRS,
TEST_CERT,
TEST_CERT_DAYS,
+ TEST_CERT_INFO,
+ TEST_PARSE_ACME_TIMESTAMP,
+ TEST_INTERPOLATE_TIMESTAMP,
)
@@ -64,3 +75,49 @@ def test_certdays_cryptography(now, expected_days, tmpdir):
assert days == expected_days
days = backend.get_cert_days(cert_content=TEST_CERT, now=now)
assert days == expected_days
+
+
+@pytest.mark.parametrize("cert_content, expected_cert_info, openssl_output", TEST_CERT_INFO)
+def test_get_cert_information(cert_content, expected_cert_info, openssl_output, tmpdir):
+ fn = tmpdir / 'test-cert.pem'
+ fn.write(cert_content)
+ module = MagicMock()
+ backend = CryptographyBackend(module)
+
+ if CRYPTOGRAPHY_TIMEZONE:
+ expected_cert_info = expected_cert_info._replace(
+ not_valid_after=ensure_utc_timezone(expected_cert_info.not_valid_after),
+ not_valid_before=ensure_utc_timezone(expected_cert_info.not_valid_before),
+ )
+
+ cert_info = backend.get_cert_information(cert_filename=str(fn))
+ assert cert_info == expected_cert_info
+ cert_info = backend.get_cert_information(cert_content=cert_content)
+ assert cert_info == expected_cert_info
+
+
+def test_now():
+ module = MagicMock()
+ backend = CryptographyBackend(module)
+ now = backend.get_now()
+ assert CRYPTOGRAPHY_TIMEZONE == (now.tzinfo is not None)
+
+
+@pytest.mark.parametrize("input, expected", TEST_PARSE_ACME_TIMESTAMP)
+def test_parse_acme_timestamp(input, expected):
+ module = MagicMock()
+ backend = CryptographyBackend(module)
+ ts_expected = backend.get_utc_datetime(**expected)
+ timestamp = backend.parse_acme_timestamp(input)
+ assert ts_expected == timestamp
+
+
+@pytest.mark.parametrize("start, end, percentage, expected", TEST_INTERPOLATE_TIMESTAMP)
+def test_interpolate_timestamp(start, end, percentage, expected):
+ module = MagicMock()
+ backend = CryptographyBackend(module)
+ ts_start = backend.get_utc_datetime(**start)
+ ts_end = backend.get_utc_datetime(**end)
+ ts_expected = backend.get_utc_datetime(**expected)
+ timestamp = backend.interpolate_timestamp(ts_start, ts_end, percentage)
+ assert ts_expected == timestamp
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_openssl_cli.py b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_openssl_cli.py
index dd30cf795..5138a6202 100644
--- a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_openssl_cli.py
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_backend_openssl_cli.py
@@ -18,6 +18,12 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.backend_open
from .backend_data import (
TEST_KEYS,
TEST_CSRS,
+ TEST_CERT,
+ TEST_CERT_OPENSSL_OUTPUT,
+ TEST_CERT_DAYS,
+ TEST_CERT_INFO,
+ TEST_PARSE_ACME_TIMESTAMP,
+ TEST_INTERPOLATE_TIMESTAMP,
)
@@ -61,3 +67,56 @@ def test_normalize_ip(ip, result):
module = MagicMock()
backend = OpenSSLCLIBackend(module, openssl_binary='openssl')
assert backend._normalize_ip(ip) == result
+
+
+@pytest.mark.parametrize("now, expected_days", TEST_CERT_DAYS)
+def test_certdays_cryptography(now, expected_days, tmpdir):
+ fn = tmpdir / 'test-cert.pem'
+ fn.write(TEST_CERT)
+ module = MagicMock()
+ module.run_command = MagicMock(return_value=(0, TEST_CERT_OPENSSL_OUTPUT, 0))
+ backend = OpenSSLCLIBackend(module, openssl_binary='openssl')
+ days = backend.get_cert_days(cert_filename=str(fn), now=now)
+ assert days == expected_days
+ days = backend.get_cert_days(cert_content=TEST_CERT, now=now)
+ assert days == expected_days
+
+
+@pytest.mark.parametrize("cert_content, expected_cert_info, openssl_output", TEST_CERT_INFO)
+def test_get_cert_information(cert_content, expected_cert_info, openssl_output, tmpdir):
+ fn = tmpdir / 'test-cert.pem'
+ fn.write(cert_content)
+ module = MagicMock()
+ module.run_command = MagicMock(return_value=(0, openssl_output, 0))
+ backend = OpenSSLCLIBackend(module, openssl_binary='openssl')
+ cert_info = backend.get_cert_information(cert_filename=str(fn))
+ assert cert_info == expected_cert_info
+ cert_info = backend.get_cert_information(cert_content=cert_content)
+ assert cert_info == expected_cert_info
+
+
+def test_now():
+ module = MagicMock()
+ backend = OpenSSLCLIBackend(module, openssl_binary='openssl')
+ now = backend.get_now()
+ assert now.tzinfo is None
+
+
+@pytest.mark.parametrize("input, expected", TEST_PARSE_ACME_TIMESTAMP)
+def test_parse_acme_timestamp(input, expected):
+ module = MagicMock()
+ backend = OpenSSLCLIBackend(module, openssl_binary='openssl')
+ ts_expected = backend.get_utc_datetime(**expected)
+ timestamp = backend.parse_acme_timestamp(input)
+ assert ts_expected == timestamp
+
+
+@pytest.mark.parametrize("start, end, percentage, expected", TEST_INTERPOLATE_TIMESTAMP)
+def test_interpolate_timestamp(start, end, percentage, expected):
+ module = MagicMock()
+ backend = OpenSSLCLIBackend(module, openssl_binary='openssl')
+ ts_start = backend.get_utc_datetime(**start)
+ ts_end = backend.get_utc_datetime(**end)
+ ts_expected = backend.get_utc_datetime(**expected)
+ timestamp = backend.interpolate_timestamp(ts_start, ts_end, percentage)
+ assert ts_expected == timestamp
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_utils.py b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_utils.py
index 9bdd8eb6e..5cc318ac2 100644
--- a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_utils.py
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/acme/test_utils.py
@@ -6,12 +6,20 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
+import datetime
+
import pytest
+from ansible_collections.community.crypto.plugins.module_utils.acme.backends import (
+ CertificateInformation,
+)
from ansible_collections.community.crypto.plugins.module_utils.acme.utils import (
nopad_b64,
pem_to_der,
+ process_links,
+ parse_retry_after,
+ compute_cert_id,
)
from .backend_data import (
@@ -27,6 +35,73 @@ NOPAD_B64 = [
]
+TEST_LINKS_HEADER = [
+ (
+ {},
+ [],
+ ),
+ (
+ {
+ 'link': '<foo>; rel="bar"'
+ },
+ [
+ ('foo', 'bar'),
+ ],
+ ),
+ (
+ {
+ 'link': '<foo>; rel="bar", <baz>; rel="bam"'
+ },
+ [
+ ('foo', 'bar'),
+ ('baz', 'bam'),
+ ],
+ ),
+ (
+ {
+ 'link': '<https://one.example.com>; rel="preconnect", <https://two.example.com>; rel="preconnect", <https://three.example.com>; rel="preconnect"'
+ },
+ [
+ ('https://one.example.com', 'preconnect'),
+ ('https://two.example.com', 'preconnect'),
+ ('https://three.example.com', 'preconnect'),
+ ],
+ ),
+]
+
+
+TEST_RETRY_AFTER_HEADER = [
+ ('120', datetime.datetime(2024, 4, 29, 0, 2, 0)),
+ ('Wed, 21 Oct 2015 07:28:00 GMT', datetime.datetime(2015, 10, 21, 7, 28, 0)),
+]
+
+
+TEST_COMPUTE_CERT_ID = [
+ (
+ CertificateInformation(
+ not_valid_after=datetime.datetime(2018, 11, 26, 15, 28, 24),
+ not_valid_before=datetime.datetime(2018, 11, 25, 15, 28, 23),
+ serial_number=1,
+ subject_key_identifier=None,
+ authority_key_identifier=b'\x00\xff',
+ ),
+ 'AP8.AQ',
+ ),
+ (
+ # AKI, serial number, and expected result taken from
+ # https://letsencrypt.org/2024/04/25/guide-to-integrating-ari-into-existing-acme-clients.html#step-3-constructing-the-ari-certid
+ CertificateInformation(
+ not_valid_after=datetime.datetime(2018, 11, 26, 15, 28, 24),
+ not_valid_before=datetime.datetime(2018, 11, 25, 15, 28, 23),
+ serial_number=0x87654321,
+ subject_key_identifier=None,
+ authority_key_identifier=b'\x69\x88\x5B\x6B\x87\x46\x40\x41\xE1\xB3\x7B\x84\x7B\xA0\xAE\x2C\xDE\x01\xC8\xD4',
+ ),
+ 'aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE',
+ ),
+]
+
+
@pytest.mark.parametrize("value, result", NOPAD_B64)
def test_nopad_b64(value, result):
assert nopad_b64(value.encode('utf-8')) == result
@@ -37,3 +112,25 @@ def test_pem_to_der(pem, der, tmpdir):
fn = tmpdir / 'test.pem'
fn.write(pem)
assert pem_to_der(str(fn)) == der
+
+
+@pytest.mark.parametrize("value, expected_result", TEST_LINKS_HEADER)
+def test_process_links(value, expected_result):
+ data = []
+
+ def callback(url, rel):
+ data.append((url, rel))
+
+ process_links(value, callback)
+
+ assert expected_result == data
+
+
+@pytest.mark.parametrize("value, expected_result", TEST_RETRY_AFTER_HEADER)
+def test_parse_retry_after(value, expected_result):
+ assert expected_result == parse_retry_after(value, now=datetime.datetime(2024, 4, 29, 0, 0, 0))
+
+
+@pytest.mark.parametrize("cert_info, expected_result", TEST_COMPUTE_CERT_ID)
+def test_compute_cert_id(cert_info, expected_result):
+ assert expected_result == compute_cert_id(backend=None, cert_info=cert_info)
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/crypto/test_math.py b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/crypto/test_math.py
new file mode 100644
index 000000000..4fd917713
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/crypto/test_math.py
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import pytest
+
+from ansible_collections.community.crypto.plugins.module_utils.crypto.math import (
+ binary_exp_mod,
+ simple_gcd,
+ quick_is_not_prime,
+ convert_int_to_bytes,
+ convert_int_to_hex,
+ convert_bytes_to_int,
+)
+
+
+@pytest.mark.parametrize('f, e, m, result', [
+ (0, 0, 5, 1),
+ (0, 1, 5, 0),
+ (2, 1, 5, 2),
+ (2, 2, 5, 4),
+ (2, 3, 5, 3),
+ (2, 10, 5, 4),
+])
+def test_binary_exp_mod(f, e, m, result):
+ value = binary_exp_mod(f, e, m)
+ print(value)
+ assert value == result
+
+
+@pytest.mark.parametrize('a, b, result', [
+ (0, -123, -123),
+ (0, 123, 123),
+ (-123, 0, -123),
+ (123, 0, 123),
+ (-123, 1, 1),
+ (123, 1, 1),
+ (1, -123, -1),
+ (1, 123, 1),
+ (1024, 10, 2),
+])
+def test_simple_gcd(a, b, result):
+ value = simple_gcd(a, b)
+ print(value)
+ assert value == result
+
+
+@pytest.mark.parametrize('n, result', [
+ (-2, True),
+ (0, True),
+ (1, True),
+ (2, False),
+ (3, False),
+ (4, True),
+ (5, False),
+ (6, True),
+ (7, False),
+ (8, True),
+ (9, True),
+ (10, True),
+ (211, False), # the smallest prime number >= 200
+])
+def test_quick_is_not_prime(n, result):
+ value = quick_is_not_prime(n)
+ print(value)
+ assert value == result
+
+
+@pytest.mark.parametrize('no, count, result', [
+ (0, None, b''),
+ (0, 1, b'\x00'),
+ (0, 2, b'\x00\x00'),
+ (1, None, b'\x01'),
+ (1, 2, b'\x00\x01'),
+ (255, None, b'\xff'),
+ (256, None, b'\x01\x00'),
+])
+def test_convert_int_to_bytes(no, count, result):
+ value = convert_int_to_bytes(no, count=count)
+ print(value)
+ assert value == result
+
+
+@pytest.mark.parametrize('no, digits, result', [
+ (0, None, '0'),
+ (1, None, '1'),
+ (16, None, '10'),
+ (1, 3, '001'),
+ (255, None, 'ff'),
+ (256, None, '100'),
+ (256, 2, '100'),
+ (256, 3, '100'),
+ (256, 4, '0100'),
+])
+def test_convert_int_to_hex(no, digits, result):
+ value = convert_int_to_hex(no, digits=digits)
+ print(value)
+ assert value == result
+
+
+@pytest.mark.parametrize('data, result', [
+ (b'', 0),
+ (b'\x00', 0),
+ (b'\x00\x01', 1),
+ (b'\x01', 1),
+ (b'\xff', 255),
+ (b'\x01\x00', 256),
+])
+def test_convert_bytes_to_int(data, result):
+ value = convert_bytes_to_int(data)
+ print(value)
+ assert value == result
diff --git a/ansible_collections/community/crypto/tests/unit/plugins/module_utils/test_time.py b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/test_time.py
new file mode 100644
index 000000000..35a83f4e4
--- /dev/null
+++ b/ansible_collections/community/crypto/tests/unit/plugins/module_utils/test_time.py
@@ -0,0 +1,323 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+import datetime
+import sys
+
+import pytest
+
+
+from ansible_collections.community.crypto.plugins.module_utils.time import (
+ add_or_remove_timezone,
+ get_now_datetime,
+ convert_relative_to_datetime,
+ ensure_utc_timezone,
+ from_epoch_seconds,
+ get_epoch_seconds,
+ get_relative_time_option,
+ remove_timezone,
+ UTC,
+)
+
+
+TEST_REMOVE_TIMEZONE = [
+ (
+ datetime.datetime(2024, 1, 1, 0, 1, 2, tzinfo=UTC),
+ datetime.datetime(2024, 1, 1, 0, 1, 2),
+ ),
+ (
+ datetime.datetime(2024, 1, 1, 0, 1, 2),
+ datetime.datetime(2024, 1, 1, 0, 1, 2),
+ ),
+]
+
+TEST_UTC_TIMEZONE = [
+ (
+ datetime.datetime(2024, 1, 1, 0, 1, 2),
+ datetime.datetime(2024, 1, 1, 0, 1, 2, tzinfo=UTC),
+ ),
+ (
+ datetime.datetime(2024, 1, 1, 0, 1, 2, tzinfo=UTC),
+ datetime.datetime(2024, 1, 1, 0, 1, 2, tzinfo=UTC),
+ ),
+]
+
+TEST_EPOCH_SECONDS = [
+ (0, dict(year=1970, day=1, month=1, hour=0, minute=0, second=0, microsecond=0)),
+ (1E-6, dict(year=1970, day=1, month=1, hour=0, minute=0, second=0, microsecond=1)),
+ (1E-3, dict(year=1970, day=1, month=1, hour=0, minute=0, second=0, microsecond=1000)),
+ (3691.2, dict(year=1970, day=1, month=1, hour=1, minute=1, second=31, microsecond=200000)),
+]
+
+TEST_EPOCH_TO_SECONDS = [
+ (datetime.datetime(1970, 1, 1, 0, 1, 2, 0), 62),
+ (datetime.datetime(1970, 1, 1, 0, 1, 2, 0, tzinfo=UTC), 62),
+]
+
+TEST_CONVERT_RELATIVE_TO_DATETIME = [
+ (
+ '+0',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ ),
+ (
+ '+1s',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0, tzinfo=UTC),
+ datetime.datetime(2024, 1, 1, 0, 0, 1),
+ ),
+ (
+ '-10w20d30h40m50s',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0, tzinfo=UTC),
+ datetime.datetime(2023, 10, 1, 17, 19, 10),
+ ),
+ (
+ '+0',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 1, 0, 0, 0, tzinfo=UTC),
+ ),
+ (
+ '+1s',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0, tzinfo=UTC),
+ datetime.datetime(2024, 1, 1, 0, 0, 1, tzinfo=UTC),
+ ),
+ (
+ '-10w20d30h40m50s',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2023, 10, 1, 17, 19, 10, tzinfo=UTC),
+ ),
+]
+
+TEST_GET_RELATIVE_TIME_OPTION = [
+ (
+ '+1d2h3m4s',
+ 'foo',
+ 'cryptography',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 2, 3, 4),
+ ),
+ (
+ '-1w10d24h',
+ 'foo',
+ 'cryptography',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2023, 12, 14, 0, 0, 0),
+ ),
+ (
+ '20240102040506Z',
+ 'foo',
+ 'cryptography',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 4, 5, 6),
+ ),
+ (
+ '202401020405Z',
+ 'foo',
+ 'cryptography',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 4, 5, 0),
+ ),
+ (
+ '+1d2h3m4s',
+ 'foo',
+ 'cryptography',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 2, 3, 4, tzinfo=UTC),
+ ),
+ (
+ '-1w10d24h',
+ 'foo',
+ 'cryptography',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2023, 12, 14, 0, 0, 0, tzinfo=UTC),
+ ),
+ (
+ '20240102040506Z',
+ 'foo',
+ 'cryptography',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 4, 5, 6, tzinfo=UTC),
+ ),
+ (
+ '202401020405Z',
+ 'foo',
+ 'cryptography',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 4, 5, 0, tzinfo=UTC),
+ ),
+ (
+ '+1d2h3m4s',
+ 'foo',
+ 'pyopenssl',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ '20240102020304Z',
+ ),
+ (
+ '-1w10d24h',
+ 'foo',
+ 'pyopenssl',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ '20231214000000Z',
+ ),
+ (
+ '20240102040506Z',
+ 'foo',
+ 'pyopenssl',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ '20240102040506Z',
+ ),
+ (
+ '202401020405Z',
+ 'foo',
+ 'pyopenssl',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ '202401020405Z',
+ ),
+]
+
+
+if sys.version_info >= (3, 5):
+ ONE_HOUR_PLUS = datetime.timezone(datetime.timedelta(hours=1))
+
+ TEST_REMOVE_TIMEZONE.extend([
+ (
+ datetime.datetime(2024, 1, 1, 0, 1, 2, tzinfo=ONE_HOUR_PLUS),
+ datetime.datetime(2023, 12, 31, 23, 1, 2),
+ ),
+ ])
+ TEST_UTC_TIMEZONE.extend([
+ (
+ datetime.datetime(2024, 1, 1, 0, 1, 2, tzinfo=ONE_HOUR_PLUS),
+ datetime.datetime(2023, 12, 31, 23, 1, 2, tzinfo=UTC),
+ ),
+ ])
+ TEST_EPOCH_TO_SECONDS.extend([
+ (datetime.datetime(1970, 1, 1, 0, 1, 2, 0, tzinfo=ONE_HOUR_PLUS), 62 - 3600),
+ ])
+ TEST_GET_RELATIVE_TIME_OPTION.extend([
+ (
+ '20240102040506+0100',
+ 'foo',
+ 'cryptography',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 3, 5, 6),
+ ),
+ (
+ '202401020405+0100',
+ 'foo',
+ 'cryptography',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 3, 5, 0),
+ ),
+ (
+ '20240102040506+0100',
+ 'foo',
+ 'cryptography',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 3, 5, 6, tzinfo=UTC),
+ ),
+ (
+ '202401020405+0100',
+ 'foo',
+ 'cryptography',
+ True,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ datetime.datetime(2024, 1, 2, 3, 5, 0, tzinfo=UTC),
+ ),
+ (
+ '20240102040506+0100',
+ 'foo',
+ 'pyopenssl',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ '20240102040506+0100',
+ ),
+ (
+ '202401020405+0100',
+ 'foo',
+ 'pyopenssl',
+ False,
+ datetime.datetime(2024, 1, 1, 0, 0, 0),
+ '202401020405+0100',
+ ),
+ ])
+
+
+@pytest.mark.parametrize("input, expected", TEST_REMOVE_TIMEZONE)
+def test_remove_timezone(input, expected):
+ output_1 = remove_timezone(input)
+ assert expected == output_1
+ output_2 = add_or_remove_timezone(input, with_timezone=False)
+ assert expected == output_2
+
+
+@pytest.mark.parametrize("input, expected", TEST_UTC_TIMEZONE)
+def test_utc_timezone(input, expected):
+ output_1 = ensure_utc_timezone(input)
+ assert expected == output_1
+ output_2 = add_or_remove_timezone(input, with_timezone=True)
+ assert expected == output_2
+
+
+def test_get_now_datetime():
+ output_1 = get_now_datetime(with_timezone=False)
+ assert output_1.tzinfo is None
+ output_2 = get_now_datetime(with_timezone=True)
+ assert output_2.tzinfo is not None
+ assert output_2.tzinfo == UTC
+
+
+@pytest.mark.parametrize("seconds, timestamp", TEST_EPOCH_SECONDS)
+def test_epoch_seconds(seconds, timestamp):
+ ts_wo_tz = datetime.datetime(**timestamp)
+ assert seconds == get_epoch_seconds(ts_wo_tz)
+ timestamp_w_tz = dict(timestamp)
+ timestamp_w_tz['tzinfo'] = UTC
+ ts_w_tz = datetime.datetime(**timestamp_w_tz)
+ assert seconds == get_epoch_seconds(ts_w_tz)
+ output_1 = from_epoch_seconds(seconds, with_timezone=False)
+ assert ts_wo_tz == output_1
+ output_2 = from_epoch_seconds(seconds, with_timezone=True)
+ assert ts_w_tz == output_2
+
+
+@pytest.mark.parametrize("timestamp, expected_seconds", TEST_EPOCH_TO_SECONDS)
+def test_epoch_to_seconds(timestamp, expected_seconds):
+ assert expected_seconds == get_epoch_seconds(timestamp)
+
+
+@pytest.mark.parametrize("relative_time_string, with_timezone, now, expected", TEST_CONVERT_RELATIVE_TO_DATETIME)
+def test_convert_relative_to_datetime(relative_time_string, with_timezone, now, expected):
+ output = convert_relative_to_datetime(relative_time_string, with_timezone=with_timezone, now=now)
+ assert expected == output
+
+
+@pytest.mark.parametrize("input_string, input_name, backend, with_timezone, now, expected", TEST_GET_RELATIVE_TIME_OPTION)
+def test_get_relative_time_option(input_string, input_name, backend, with_timezone, now, expected):
+ output = get_relative_time_option(input_string, input_name, backend=backend, with_timezone=with_timezone, now=now)
+ assert expected == output
diff --git a/ansible_collections/community/dns/.github/workflows/ansible-test.yml b/ansible_collections/community/dns/.github/workflows/ansible-test.yml
index 186079a41..d8121c8f7 100644
--- a/ansible_collections/community/dns/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/dns/.github/workflows/ansible-test.yml
@@ -29,53 +29,30 @@ jobs:
ansible:
# It's important that Sanity is tested against all stable-X.Y branches
# Testing against `devel` may fail as new tests are added.
- - stable-2.9
- - stable-2.10
- - stable-2.11
- - stable-2.12
- - stable-2.13
- stable-2.14
- stable-2.15
- stable-2.16
- stable-2.17
- devel
- # Ansible-test on various stable branches does not yet work well with cgroups v2.
- # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
- # image for these stable branches. The list of branches where this is necessary will
- # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
- # for the latest list.
- runs-on: >-
- ${{ contains(fromJson(
- '["stable-2.9", "stable-2.10", "stable-2.11"]'
- ), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
+ runs-on: ubuntu-latest
steps:
- name: Perform sanity testing
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: ${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
testing-type: sanity
+ test-deps: >-
+ git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1
units:
- # Ansible-test on various stable branches does not yet work well with cgroups v2.
- # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
- # image for these stable branches. The list of branches where this is necessary will
- # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
- # for the latest list.
- runs-on: >-
- ${{ contains(fromJson(
- '["stable-2.9", "stable-2.10", "stable-2.11"]'
- ), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
+ runs-on: ubuntu-latest
name: Units (â’¶${{ matrix.ansible }})
strategy:
# As soon as the first unit test fails, cancel the others to free up the CI queue
fail-fast: true
matrix:
ansible:
- - stable-2.9
- - stable-2.10
- - stable-2.11
- - stable-2.12
- - stable-2.13
- stable-2.14
- stable-2.15
- stable-2.16
@@ -89,12 +66,13 @@ jobs:
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: ${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
testing-type: units
- # NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
pre-test-cmd: >-
- git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ../../community/internal_test_tools
- ;
tests/unit/replace-requirements.sh requirements-${{ matrix.ansible }}.txt
+ test-deps: >-
+ git+https://github.com/ansible-collections/community.internal_test_tools.git,main
+ git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1
integration:
# Ansible-test on various stable branches does not yet work well with cgroups v2.
@@ -119,26 +97,11 @@ jobs:
- "3.11"
- "3.12"
include:
- # 2.9
- - ansible: stable-2.9
- python: "2.7"
- - ansible: stable-2.9
- python: "3.6"
- # 2.10
- - ansible: stable-2.10
- python: "3.5"
- # 2.11
- - ansible: stable-2.11
+ # 2.14
+ - ansible: stable-2.14
python: "2.7"
- # 2.12
- - ansible: stable-2.12
- python: "2.6"
- - ansible: stable-2.12
+ - ansible: stable-2.14
python: "3.5"
- # 2.13
- - ansible: stable-2.13
- python: "3.6"
- # 2.14
- ansible: stable-2.14
python: "3.9"
# 2.15
@@ -165,11 +128,13 @@ jobs:
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: ${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
integration-continue-on-error: 'false'
integration-diff: 'false'
integration-retry-on-error: 'true'
- # NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
pre-test-cmd: >-
tests/integration/replace-requirements.sh requirements-${{ matrix.ansible }}.txt
+ test-deps: >-
+ git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1
target-python-version: ${{ matrix.python }}
testing-type: integration
diff --git a/ansible_collections/community/dns/.github/workflows/ee.yml b/ansible_collections/community/dns/.github/workflows/ee.yml
index 9a2f1164b..afa820d0d 100644
--- a/ansible_collections/community/dns/.github/workflows/ee.yml
+++ b/ansible_collections/community/dns/.github/workflows/ee.yml
@@ -62,22 +62,6 @@ jobs:
ansible_runner: ansible-runner
base_image: quay.io/centos/centos:stream9
pre_base: '"#"'
- - name: ansible-core 2.13 @ RHEL UBI 8
- ansible_core: https://github.com/ansible/ansible/archive/stable-2.13.tar.gz
- ansible_runner: ansible-runner
- other_deps: |2
- python_interpreter:
- package_system: python39 python39-pip python39-wheel python39-cryptography
- base_image: docker.io/redhat/ubi8:latest
- pre_base: '"#"'
- - name: ansible-core 2.12 @ CentOS Stream 8
- ansible_core: https://github.com/ansible/ansible/archive/stable-2.12.tar.gz
- ansible_runner: ansible-runner
- other_deps: |2
- python_interpreter:
- package_system: python39 python39-pip python39-wheel python39-cryptography
- base_image: quay.io/centos/centos:stream8
- pre_base: '"#"'
runs-on: ubuntu-latest
steps:
- name: Check out code
@@ -88,7 +72,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Install ansible-builder and ansible-navigator
run: pip install ansible-builder ansible-navigator
diff --git a/ansible_collections/community/dns/.github/workflows/extra-tests.yml b/ansible_collections/community/dns/.github/workflows/extra-tests.yml
index 975404fa5..397b22af7 100644
--- a/ansible_collections/community/dns/.github/workflows/extra-tests.yml
+++ b/ansible_collections/community/dns/.github/workflows/extra-tests.yml
@@ -33,15 +33,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Install ansible-core
run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
- name: Install collection dependencies
- run: git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ./ansible_collections/community/internal_test_tools
- # NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
- # run: ansible-galaxy collection install community.internal_test_tools -p .
+ run: >-
+ ansible-galaxy collection install -p .
+ git+https://github.com/ansible-collections/community.internal_test_tools.git,main
+ git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1
- name: Run sanity tests
run: ../../community/internal_test_tools/tools/run.py --color
diff --git a/ansible_collections/community/dns/CHANGELOG.md b/ansible_collections/community/dns/CHANGELOG.md
index 9881ee7ed..95a940b1c 100644
--- a/ansible_collections/community/dns/CHANGELOG.md
+++ b/ansible_collections/community/dns/CHANGELOG.md
@@ -2,193 +2,239 @@
**Topics**
-- <a href="#v2-9-0">v2\.9\.0</a>
+- <a href="#v3-0-0">v3\.0\.0</a>
- <a href="#release-summary">Release Summary</a>
+ - <a href="#major-changes">Major Changes</a>
+ - <a href="#minor-changes">Minor Changes</a>
+ - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
+ - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- <a href="#bugfixes">Bugfixes</a>
+- <a href="#v2-9-0">v2\.9\.0</a>
+ - <a href="#release-summary-1">Release Summary</a>
+ - <a href="#bugfixes-1">Bugfixes</a>
- <a href="#new-plugins">New Plugins</a>
- <a href="#filter">Filter</a>
- <a href="#v2-8-3">v2\.8\.3</a>
- - <a href="#release-summary-1">Release Summary</a>
- - <a href="#bugfixes-1">Bugfixes</a>
-- <a href="#v2-8-2">v2\.8\.2</a>
- <a href="#release-summary-2">Release Summary</a>
- - <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-2">Bugfixes</a>
-- <a href="#v2-8-1">v2\.8\.1</a>
+- <a href="#v2-8-2">v2\.8\.2</a>
- <a href="#release-summary-3">Release Summary</a>
+ - <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-3">Bugfixes</a>
-- <a href="#v2-8-0">v2\.8\.0</a>
+- <a href="#v2-8-1">v2\.8\.1</a>
- <a href="#release-summary-4">Release Summary</a>
- - <a href="#minor-changes">Minor Changes</a>
- - <a href="#deprecated-features">Deprecated Features</a>
- <a href="#bugfixes-4">Bugfixes</a>
-- <a href="#v2-7-0">v2\.7\.0</a>
+- <a href="#v2-8-0">v2\.8\.0</a>
- <a href="#release-summary-5">Release Summary</a>
- <a href="#minor-changes-1">Minor Changes</a>
+ - <a href="#deprecated-features">Deprecated Features</a>
- <a href="#bugfixes-5">Bugfixes</a>
-- <a href="#v2-6-4">v2\.6\.4</a>
+- <a href="#v2-7-0">v2\.7\.0</a>
- <a href="#release-summary-6">Release Summary</a>
+ - <a href="#minor-changes-2">Minor Changes</a>
- <a href="#bugfixes-6">Bugfixes</a>
-- <a href="#v2-6-3">v2\.6\.3</a>
+- <a href="#v2-6-4">v2\.6\.4</a>
- <a href="#release-summary-7">Release Summary</a>
- <a href="#bugfixes-7">Bugfixes</a>
-- <a href="#v2-6-2">v2\.6\.2</a>
+- <a href="#v2-6-3">v2\.6\.3</a>
- <a href="#release-summary-8">Release Summary</a>
- <a href="#bugfixes-8">Bugfixes</a>
-- <a href="#v2-6-1">v2\.6\.1</a>
+- <a href="#v2-6-2">v2\.6\.2</a>
- <a href="#release-summary-9">Release Summary</a>
- <a href="#bugfixes-9">Bugfixes</a>
-- <a href="#v2-6-0">v2\.6\.0</a>
+- <a href="#v2-6-1">v2\.6\.1</a>
- <a href="#release-summary-10">Release Summary</a>
- - <a href="#minor-changes-2">Minor Changes</a>
- <a href="#bugfixes-10">Bugfixes</a>
+- <a href="#v2-6-0">v2\.6\.0</a>
+ - <a href="#release-summary-11">Release Summary</a>
+ - <a href="#minor-changes-3">Minor Changes</a>
+ - <a href="#bugfixes-11">Bugfixes</a>
- <a href="#new-plugins-1">New Plugins</a>
- <a href="#lookup">Lookup</a>
- <a href="#new-modules">New Modules</a>
- <a href="#v2-5-7">v2\.5\.7</a>
- - <a href="#release-summary-11">Release Summary</a>
- - <a href="#bugfixes-11">Bugfixes</a>
-- <a href="#v2-5-6">v2\.5\.6</a>
- <a href="#release-summary-12">Release Summary</a>
+ - <a href="#bugfixes-12">Bugfixes</a>
+- <a href="#v2-5-6">v2\.5\.6</a>
+ - <a href="#release-summary-13">Release Summary</a>
- <a href="#known-issues">Known Issues</a>
- <a href="#v2-5-5">v2\.5\.5</a>
- - <a href="#release-summary-13">Release Summary</a>
- - <a href="#bugfixes-12">Bugfixes</a>
-- <a href="#v2-5-4">v2\.5\.4</a>
- <a href="#release-summary-14">Release Summary</a>
- <a href="#bugfixes-13">Bugfixes</a>
-- <a href="#v2-5-3">v2\.5\.3</a>
+- <a href="#v2-5-4">v2\.5\.4</a>
- <a href="#release-summary-15">Release Summary</a>
- <a href="#bugfixes-14">Bugfixes</a>
-- <a href="#v2-5-2">v2\.5\.2</a>
+- <a href="#v2-5-3">v2\.5\.3</a>
- <a href="#release-summary-16">Release Summary</a>
- <a href="#bugfixes-15">Bugfixes</a>
-- <a href="#v2-5-1">v2\.5\.1</a>
+- <a href="#v2-5-2">v2\.5\.2</a>
- <a href="#release-summary-17">Release Summary</a>
- <a href="#bugfixes-16">Bugfixes</a>
-- <a href="#v2-5-0">v2\.5\.0</a>
+- <a href="#v2-5-1">v2\.5\.1</a>
- <a href="#release-summary-18">Release Summary</a>
- - <a href="#minor-changes-3">Minor Changes</a>
- - <a href="#deprecated-features-1">Deprecated Features</a>
- <a href="#bugfixes-17">Bugfixes</a>
-- <a href="#v2-4-2">v2\.4\.2</a>
+- <a href="#v2-5-0">v2\.5\.0</a>
- <a href="#release-summary-19">Release Summary</a>
+ - <a href="#minor-changes-4">Minor Changes</a>
+ - <a href="#deprecated-features-1">Deprecated Features</a>
- <a href="#bugfixes-18">Bugfixes</a>
-- <a href="#v2-4-1">v2\.4\.1</a>
+- <a href="#v2-4-2">v2\.4\.2</a>
- <a href="#release-summary-20">Release Summary</a>
- <a href="#bugfixes-19">Bugfixes</a>
-- <a href="#v2-4-0">v2\.4\.0</a>
+- <a href="#v2-4-1">v2\.4\.1</a>
- <a href="#release-summary-21">Release Summary</a>
- - <a href="#minor-changes-4">Minor Changes</a>
- <a href="#bugfixes-20">Bugfixes</a>
-- <a href="#v2-3-4">v2\.3\.4</a>
+- <a href="#v2-4-0">v2\.4\.0</a>
- <a href="#release-summary-22">Release Summary</a>
+ - <a href="#minor-changes-5">Minor Changes</a>
- <a href="#bugfixes-21">Bugfixes</a>
-- <a href="#v2-3-3">v2\.3\.3</a>
+- <a href="#v2-3-4">v2\.3\.4</a>
- <a href="#release-summary-23">Release Summary</a>
- <a href="#bugfixes-22">Bugfixes</a>
-- <a href="#v2-3-2">v2\.3\.2</a>
+- <a href="#v2-3-3">v2\.3\.3</a>
- <a href="#release-summary-24">Release Summary</a>
- <a href="#bugfixes-23">Bugfixes</a>
-- <a href="#v2-3-1">v2\.3\.1</a>
+- <a href="#v2-3-2">v2\.3\.2</a>
- <a href="#release-summary-25">Release Summary</a>
- - <a href="#minor-changes-5">Minor Changes</a>
- <a href="#bugfixes-24">Bugfixes</a>
-- <a href="#v2-3-0">v2\.3\.0</a>
+- <a href="#v2-3-1">v2\.3\.1</a>
- <a href="#release-summary-26">Release Summary</a>
- <a href="#minor-changes-6">Minor Changes</a>
- <a href="#bugfixes-25">Bugfixes</a>
-- <a href="#v2-2-1">v2\.2\.1</a>
+- <a href="#v2-3-0">v2\.3\.0</a>
- <a href="#release-summary-27">Release Summary</a>
+ - <a href="#minor-changes-7">Minor Changes</a>
- <a href="#bugfixes-26">Bugfixes</a>
-- <a href="#v2-2-0">v2\.2\.0</a>
+- <a href="#v2-2-1">v2\.2\.1</a>
- <a href="#release-summary-28">Release Summary</a>
- - <a href="#minor-changes-7">Minor Changes</a>
- <a href="#bugfixes-27">Bugfixes</a>
-- <a href="#v2-1-1">v2\.1\.1</a>
+- <a href="#v2-2-0">v2\.2\.0</a>
- <a href="#release-summary-29">Release Summary</a>
+ - <a href="#minor-changes-8">Minor Changes</a>
- <a href="#bugfixes-28">Bugfixes</a>
-- <a href="#v2-1-0">v2\.1\.0</a>
+- <a href="#v2-1-1">v2\.1\.1</a>
- <a href="#release-summary-30">Release Summary</a>
- - <a href="#minor-changes-8">Minor Changes</a>
- <a href="#bugfixes-29">Bugfixes</a>
-- <a href="#v2-0-9">v2\.0\.9</a>
+- <a href="#v2-1-0">v2\.1\.0</a>
- <a href="#release-summary-31">Release Summary</a>
+ - <a href="#minor-changes-9">Minor Changes</a>
- <a href="#bugfixes-30">Bugfixes</a>
-- <a href="#v2-0-8">v2\.0\.8</a>
+- <a href="#v2-0-9">v2\.0\.9</a>
- <a href="#release-summary-32">Release Summary</a>
- <a href="#bugfixes-31">Bugfixes</a>
-- <a href="#v2-0-7">v2\.0\.7</a>
+- <a href="#v2-0-8">v2\.0\.8</a>
- <a href="#release-summary-33">Release Summary</a>
- <a href="#bugfixes-32">Bugfixes</a>
-- <a href="#v2-0-6">v2\.0\.6</a>
+- <a href="#v2-0-7">v2\.0\.7</a>
- <a href="#release-summary-34">Release Summary</a>
- <a href="#bugfixes-33">Bugfixes</a>
-- <a href="#v2-0-5">v2\.0\.5</a>
+- <a href="#v2-0-6">v2\.0\.6</a>
- <a href="#release-summary-35">Release Summary</a>
- <a href="#bugfixes-34">Bugfixes</a>
-- <a href="#v2-0-4">v2\.0\.4</a>
+- <a href="#v2-0-5">v2\.0\.5</a>
- <a href="#release-summary-36">Release Summary</a>
- <a href="#bugfixes-35">Bugfixes</a>
-- <a href="#v2-0-3">v2\.0\.3</a>
+- <a href="#v2-0-4">v2\.0\.4</a>
- <a href="#release-summary-37">Release Summary</a>
- - <a href="#minor-changes-9">Minor Changes</a>
-- <a href="#v2-0-2">v2\.0\.2</a>
- - <a href="#release-summary-38">Release Summary</a>
- <a href="#bugfixes-36">Bugfixes</a>
-- <a href="#v2-0-1">v2\.0\.1</a>
+- <a href="#v2-0-3">v2\.0\.3</a>
+ - <a href="#release-summary-38">Release Summary</a>
+ - <a href="#minor-changes-10">Minor Changes</a>
+- <a href="#v2-0-2">v2\.0\.2</a>
- <a href="#release-summary-39">Release Summary</a>
- <a href="#bugfixes-37">Bugfixes</a>
-- <a href="#v2-0-0">v2\.0\.0</a>
+- <a href="#v2-0-1">v2\.0\.1</a>
- <a href="#release-summary-40">Release Summary</a>
- - <a href="#minor-changes-10">Minor Changes</a>
- - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
- - <a href="#deprecated-features-2">Deprecated Features</a>
- <a href="#bugfixes-38">Bugfixes</a>
+- <a href="#v2-0-0">v2\.0\.0</a>
+ - <a href="#release-summary-41">Release Summary</a>
+ - <a href="#minor-changes-11">Minor Changes</a>
+ - <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
+ - <a href="#deprecated-features-2">Deprecated Features</a>
+ - <a href="#bugfixes-39">Bugfixes</a>
- <a href="#new-plugins-2">New Plugins</a>
- <a href="#inventory">Inventory</a>
- <a href="#new-modules-1">New Modules</a>
- <a href="#v1-2-0">v1\.2\.0</a>
- - <a href="#release-summary-41">Release Summary</a>
- - <a href="#minor-changes-11">Minor Changes</a>
- - <a href="#bugfixes-39">Bugfixes</a>
-- <a href="#v1-1-0">v1\.1\.0</a>
- <a href="#release-summary-42">Release Summary</a>
- <a href="#minor-changes-12">Minor Changes</a>
- <a href="#bugfixes-40">Bugfixes</a>
-- <a href="#v1-0-1">v1\.0\.1</a>
+- <a href="#v1-1-0">v1\.1\.0</a>
- <a href="#release-summary-43">Release Summary</a>
+ - <a href="#minor-changes-13">Minor Changes</a>
- <a href="#bugfixes-41">Bugfixes</a>
-- <a href="#v1-0-0">v1\.0\.0</a>
+- <a href="#v1-0-1">v1\.0\.1</a>
- <a href="#release-summary-44">Release Summary</a>
- <a href="#bugfixes-42">Bugfixes</a>
-- <a href="#v0-3-0">v0\.3\.0</a>
+- <a href="#v1-0-0">v1\.0\.0</a>
- <a href="#release-summary-45">Release Summary</a>
- - <a href="#minor-changes-13">Minor Changes</a>
- <a href="#bugfixes-43">Bugfixes</a>
- - <a href="#new-modules-2">New Modules</a>
-- <a href="#v0-2-0">v0\.2\.0</a>
+- <a href="#v0-3-0">v0\.3\.0</a>
- <a href="#release-summary-46">Release Summary</a>
- - <a href="#major-changes">Major Changes</a>
- <a href="#minor-changes-14">Minor Changes</a>
- - <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
- <a href="#bugfixes-44">Bugfixes</a>
+ - <a href="#new-modules-2">New Modules</a>
+- <a href="#v0-2-0">v0\.2\.0</a>
+ - <a href="#release-summary-47">Release Summary</a>
+ - <a href="#major-changes-1">Major Changes</a>
+ - <a href="#minor-changes-15">Minor Changes</a>
+ - <a href="#breaking-changes--porting-guide-2">Breaking Changes / Porting Guide</a>
+ - <a href="#bugfixes-45">Bugfixes</a>
- <a href="#new-modules-3">New Modules</a>
- <a href="#v0-1-0">v0\.1\.0</a>
- - <a href="#release-summary-47">Release Summary</a>
+ - <a href="#release-summary-48">Release Summary</a>
- <a href="#new-plugins-3">New Plugins</a>
- <a href="#filter-1">Filter</a>
- <a href="#new-modules-4">New Modules</a>
+<a id="v3-0-0"></a>
+## v3\.0\.0
+
+<a id="release-summary"></a>
+### Release Summary
+
+\.\.\.
+
+<a id="major-changes"></a>
+### Major Changes
+
+* The <code>community\.dns</code> collection now depends on the <code>community\.library\_inventory\_filtering\_v1</code> collection\. This utility collection provides host filtering functionality for inventory plugins\. If you use the Ansible community package\, both collections are included and you do not have to do anything special\. If you install the collection with <code>ansible\-galaxy collection install</code>\, it will be installed automatically\. If you install the collection by copying the files of the collection to a place where ansible\-core can find it\, for example by cloning the git repository\, you need to make sure that you also have to install the dependency if you are using the inventory plugins \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+
+<a id="minor-changes"></a>
+### Minor Changes
+
+* inventory plugins \- add <code>filter</code> option which allows to include and exclude hosts based on Jinja2 conditions \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+* lookup\, lookup\_as\_dict \- it is now possible to configure whether the input should be treated as an absolute domain name \(<code>search\=false</code>\)\, or potentially as a relative domain name \(<code>search\=true</code>\) \([https\://github\.com/ansible\-collections/community\.dns/issues/200](https\://github\.com/ansible\-collections/community\.dns/issues/200)\, [https\://github\.com/ansible\-collections/community\.dns/pull/201](https\://github\.com/ansible\-collections/community\.dns/pull/201)\)\.
+
+<a id="breaking-changes--porting-guide"></a>
+### Breaking Changes / Porting Guide
+
+* The default for the <code>txt\_character\_encoding</code> options in various modules and plugins changed from <code>octal</code> to <code>decimal</code> \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+* inventory plugins \- <code>filters</code> is now no longer an alias of <code>simple\_filters</code>\, but a new\, different option \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+* inventory plugins \- the <code>plugin</code> option is now required \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+* lookup\, lookup\_as\_dict \- the default for <code>search</code> changed from <code>false</code> \(implicit default for community\.dns 2\.x\.y\) to <code>true</code> \([https\://github\.com/ansible\-collections/community\.dns/issues/200](https\://github\.com/ansible\-collections/community\.dns/issues/200)\, [https\://github\.com/ansible\-collections/community\.dns/pull/201](https\://github\.com/ansible\-collections/community\.dns/pull/201)\)\.
+
+<a id="removed-features-previously-deprecated"></a>
+### Removed Features \(previously deprecated\)
+
+* The collection no longer supports Ansible\, ansible\-base\, and ansible\-core releases that are currently End of Life at the time of the 3\.0\.0 release\. This means that Ansible 2\.9\, ansible\-base 2\.10\, ansible\-core 2\.11\, ansible\-core 2\.12\, ansible\-core 2\.13\, and ansible\-core 2\.14 are no longer supported\. The collection might still work with these versions\, but it can stop working at any moment without advance notice\, and this will not be considered a bug \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+* hetzner\_dns\_record\_set\, hetzner\_dns\_record \- the deprecated alias <code>name</code> of the prefix option was removed \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+* hosttech\_dns\_records \- the redirect to the <code>hosttech\_dns\_record\_sets</code> module has been removed \([https\://github\.com/ansible\-collections/community\.dns/pull/196](https\://github\.com/ansible\-collections/community\.dns/pull/196)\)\.
+
+<a id="bugfixes"></a>
+### Bugfixes
+
+* Update Public Suffix List\.
+
<a id="v2-9-0"></a>
## v2\.9\.0
-<a id="release-summary"></a>
+<a id="release-summary-1"></a>
### Release Summary
Feature and bugfix release\.
-<a id="bugfixes"></a>
+<a id="bugfixes-1"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -206,12 +252,12 @@ Feature and bugfix release\.
<a id="v2-8-3"></a>
## v2\.8\.3
-<a id="release-summary-1"></a>
+<a id="release-summary-2"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-1"></a>
+<a id="bugfixes-2"></a>
### Bugfixes
* DNS record modules\, inventory plugins \- fix the TXT entry encoder to avoid splitting up escape sequences for quotes and backslashes over multiple TXT strings \([https\://github\.com/ansible\-collections/community\.dns/issues/190](https\://github\.com/ansible\-collections/community\.dns/issues/190)\, [https\://github\.com/ansible\-collections/community\.dns/pull/191](https\://github\.com/ansible\-collections/community\.dns/pull/191)\)\.
@@ -220,7 +266,7 @@ Bugfix release\.
<a id="v2-8-2"></a>
## v2\.8\.2
-<a id="release-summary-2"></a>
+<a id="release-summary-3"></a>
### Release Summary
Bugfix release\.
@@ -230,7 +276,7 @@ Bugfix release\.
* hosttech\_dns\_records and hetzner\_dns\_records inventory plugins \- make sure all data received from the remote servers is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.dns/pull/189](https\://github\.com/ansible\-collections/community\.dns/pull/189)\)\.
-<a id="bugfixes-2"></a>
+<a id="bugfixes-3"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -238,12 +284,12 @@ Bugfix release\.
<a id="v2-8-1"></a>
## v2\.8\.1
-<a id="release-summary-3"></a>
+<a id="release-summary-4"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-3"></a>
+<a id="bugfixes-4"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -251,12 +297,12 @@ Maintenance release with updated PSL\.
<a id="v2-8-0"></a>
## v2\.8\.0
-<a id="release-summary-4"></a>
+<a id="release-summary-5"></a>
### Release Summary
Feature and maintenance release with updated PSL\.
-<a id="minor-changes"></a>
+<a id="minor-changes-1"></a>
### Minor Changes
* hetzner\_dns\_records and hosttech\_dns\_records inventory plugins \- the <code>filters</code> option has been renamed to <code>simple\_filters</code>\. The old name still works until community\.hrobot 2\.0\.0\. Then it will change to allow more complex filtering with the <code>community\.library\_inventory\_filtering\_v1</code> collection\'s functionality \([https\://github\.com/ansible\-collections/community\.dns/pull/181](https\://github\.com/ansible\-collections/community\.dns/pull/181)\)\.
@@ -266,7 +312,7 @@ Feature and maintenance release with updated PSL\.
* hetzner\_dns\_records and hosttech\_dns\_records inventory plugins \- the <code>filters</code> option has been renamed to <code>simple\_filters</code>\. The old name will stop working in community\.hrobot 2\.0\.0 \([https\://github\.com/ansible\-collections/community\.dns/pull/181](https\://github\.com/ansible\-collections/community\.dns/pull/181)\)\.
-<a id="bugfixes-4"></a>
+<a id="bugfixes-5"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -274,18 +320,18 @@ Feature and maintenance release with updated PSL\.
<a id="v2-7-0"></a>
## v2\.7\.0
-<a id="release-summary-5"></a>
+<a id="release-summary-6"></a>
### Release Summary
Bugfix and feature release with updated PSL\.
-<a id="minor-changes-1"></a>
+<a id="minor-changes-2"></a>
### Minor Changes
* nameserver\_info and nameserver\_record\_info \- add <code>server</code> parameter to specify custom DNS servers \([https\://github\.com/ansible\-collections/community\.dns/pull/168](https\://github\.com/ansible\-collections/community\.dns/pull/168)\, [https\://github\.com/ansible\-collections/community\.dns/pull/178](https\://github\.com/ansible\-collections/community\.dns/pull/178)\)\.
* wait\_for\_txt \- add <code>server</code> parameter to specify custom DNS servers \([https\://github\.com/ansible\-collections/community\.dns/pull/178](https\://github\.com/ansible\-collections/community\.dns/pull/178)\)\.
-<a id="bugfixes-5"></a>
+<a id="bugfixes-6"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -294,12 +340,12 @@ Bugfix and feature release with updated PSL\.
<a id="v2-6-4"></a>
## v2\.6\.4
-<a id="release-summary-6"></a>
+<a id="release-summary-7"></a>
### Release Summary
Bugfix and maintenance version\.
-<a id="bugfixes-6"></a>
+<a id="bugfixes-7"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -308,12 +354,12 @@ Bugfix and maintenance version\.
<a id="v2-6-3"></a>
## v2\.6\.3
-<a id="release-summary-7"></a>
+<a id="release-summary-8"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-7"></a>
+<a id="bugfixes-8"></a>
### Bugfixes
* HTTP module utils \- make compatible with ansible\-core 2\.17 \([https\://github\.com/ansible\-collections/community\.dns/pull/165](https\://github\.com/ansible\-collections/community\.dns/pull/165)\)\.
@@ -322,12 +368,12 @@ Maintenance release with updated PSL\.
<a id="v2-6-2"></a>
## v2\.6\.2
-<a id="release-summary-8"></a>
+<a id="release-summary-9"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-8"></a>
+<a id="bugfixes-9"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -335,12 +381,12 @@ Maintenance release with updated PSL\.
<a id="v2-6-1"></a>
## v2\.6\.1
-<a id="release-summary-9"></a>
+<a id="release-summary-10"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-9"></a>
+<a id="bugfixes-10"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -348,18 +394,18 @@ Maintenance release with updated PSL\.
<a id="v2-6-0"></a>
## v2\.6\.0
-<a id="release-summary-10"></a>
+<a id="release-summary-11"></a>
### Release Summary
Feature release with an updated Public Suffix List\.
-<a id="minor-changes-2"></a>
+<a id="minor-changes-3"></a>
### Minor Changes
* wait\_for\_txt \- add <code>servfail\_retries</code> parameter that allows retrying after SERVFAIL errors \([https\://github\.com/ansible\-collections/community\.dns/pull/159](https\://github\.com/ansible\-collections/community\.dns/pull/159)\)\.
* wait\_for\_txt\, resolver module utils \- use [EDNS](https\://en\.wikipedia\.org/wiki/Extension\_Mechanisms\_for\_DNS) \([https\://github\.com/ansible\-collections/community\.dns/pull/158](https\://github\.com/ansible\-collections/community\.dns/pull/158)\)\.
-<a id="bugfixes-10"></a>
+<a id="bugfixes-11"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -383,12 +429,12 @@ Feature release with an updated Public Suffix List\.
<a id="v2-5-7"></a>
## v2\.5\.7
-<a id="release-summary-11"></a>
+<a id="release-summary-12"></a>
### Release Summary
Regular maintenance release with updated Public Suffix List\.
-<a id="bugfixes-11"></a>
+<a id="bugfixes-12"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -396,7 +442,7 @@ Regular maintenance release with updated Public Suffix List\.
<a id="v2-5-6"></a>
## v2\.5\.6
-<a id="release-summary-12"></a>
+<a id="release-summary-13"></a>
### Release Summary
Maintenance release\.
@@ -417,12 +463,12 @@ for the rendered HTML version of the documentation of the latest release\.
<a id="v2-5-5"></a>
## v2\.5\.5
-<a id="release-summary-13"></a>
+<a id="release-summary-14"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-12"></a>
+<a id="bugfixes-13"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -430,12 +476,12 @@ Maintenance release with updated PSL\.
<a id="v2-5-4"></a>
## v2\.5\.4
-<a id="release-summary-14"></a>
+<a id="release-summary-15"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-13"></a>
+<a id="bugfixes-14"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -443,12 +489,12 @@ Maintenance release with updated PSL\.
<a id="v2-5-3"></a>
## v2\.5\.3
-<a id="release-summary-15"></a>
+<a id="release-summary-16"></a>
### Release Summary
Maintenance release with updated PSL\.
-<a id="bugfixes-14"></a>
+<a id="bugfixes-15"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -456,12 +502,12 @@ Maintenance release with updated PSL\.
<a id="v2-5-2"></a>
## v2\.5\.2
-<a id="release-summary-16"></a>
+<a id="release-summary-17"></a>
### Release Summary
Maintenance release with improved documentation and updated PSL\.
-<a id="bugfixes-15"></a>
+<a id="bugfixes-16"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -469,12 +515,12 @@ Maintenance release with improved documentation and updated PSL\.
<a id="v2-5-1"></a>
## v2\.5\.1
-<a id="release-summary-17"></a>
+<a id="release-summary-18"></a>
### Release Summary
Maintenance release \(updated PSL\)\.
-<a id="bugfixes-16"></a>
+<a id="bugfixes-17"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -482,12 +528,12 @@ Maintenance release \(updated PSL\)\.
<a id="v2-5-0"></a>
## v2\.5\.0
-<a id="release-summary-18"></a>
+<a id="release-summary-19"></a>
### Release Summary
Feature and bugfix release with updated PSL\.
-<a id="minor-changes-3"></a>
+<a id="minor-changes-4"></a>
### Minor Changes
* hosttech inventory plugin \- allow to configure token\, username\, and password with <code>ANSIBLE\_HOSTTECH\_DNS\_TOKEN</code>\, <code>ANSIBLE\_HOSTTECH\_API\_USERNAME</code>\, and <code>ANSIBLE\_HOSTTECH\_API\_PASSWORD</code> environment variables\, respectively \([https\://github\.com/ansible\-collections/community\.dns/pull/131](https\://github\.com/ansible\-collections/community\.dns/pull/131)\)\.
@@ -498,7 +544,7 @@ Feature and bugfix release with updated PSL\.
* The default of the newly added option <code>txt\_character\_encoding</code> will change from <code>octal</code> to <code>decimal</code> in community\.dns 3\.0\.0\. The new default will be compatible with [RFC 1035](https\://www\.ietf\.org/rfc/rfc1035\.txt) \([https\://github\.com/ansible\-collections/community\.dns/pull/134](https\://github\.com/ansible\-collections/community\.dns/pull/134)\)\.
-<a id="bugfixes-17"></a>
+<a id="bugfixes-18"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -507,12 +553,12 @@ Feature and bugfix release with updated PSL\.
<a id="v2-4-2"></a>
## v2\.4\.2
-<a id="release-summary-19"></a>
+<a id="release-summary-20"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-18"></a>
+<a id="bugfixes-19"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -520,12 +566,12 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-4-1"></a>
## v2\.4\.1
-<a id="release-summary-20"></a>
+<a id="release-summary-21"></a>
### Release Summary
Regular maintenance release\.
-<a id="bugfixes-19"></a>
+<a id="bugfixes-20"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -534,19 +580,19 @@ Regular maintenance release\.
<a id="v2-4-0"></a>
## v2\.4\.0
-<a id="release-summary-21"></a>
+<a id="release-summary-22"></a>
### Release Summary
Feature and maintenance release\.
-<a id="minor-changes-4"></a>
+<a id="minor-changes-5"></a>
### Minor Changes
* Added a <code>community\.dns\.hetzner</code> module defaults group / action group\. Use with <code>group/community\.dns\.hetzner</code> to provide options for all Hetzner DNS modules \([https\://github\.com/ansible\-collections/community\.dns/pull/119](https\://github\.com/ansible\-collections/community\.dns/pull/119)\)\.
* Added a <code>community\.dns\.hosttech</code> module defaults group / action group\. Use with <code>group/community\.dns\.hosttech</code> to provide options for all Hosttech DNS modules \([https\://github\.com/ansible\-collections/community\.dns/pull/119](https\://github\.com/ansible\-collections/community\.dns/pull/119)\)\.
* wait\_for\_txt \- the module now supports check mode\. The only practical change in behavior is that in check mode\, the module is now executed instead of skipped\. Since the module does not change anything\, it should have been marked as supporting check mode since it was originally added \([https\://github\.com/ansible\-collections/community\.dns/pull/119](https\://github\.com/ansible\-collections/community\.dns/pull/119)\)\.
-<a id="bugfixes-20"></a>
+<a id="bugfixes-21"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -554,12 +600,12 @@ Feature and maintenance release\.
<a id="v2-3-4"></a>
## v2\.3\.4
-<a id="release-summary-22"></a>
+<a id="release-summary-23"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-21"></a>
+<a id="bugfixes-22"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -567,12 +613,12 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-3-3"></a>
## v2\.3\.3
-<a id="release-summary-23"></a>
+<a id="release-summary-24"></a>
### Release Summary
Maintenance release including an updated Public Suffix List\.
-<a id="bugfixes-22"></a>
+<a id="bugfixes-23"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -580,12 +626,12 @@ Maintenance release including an updated Public Suffix List\.
<a id="v2-3-2"></a>
## v2\.3\.2
-<a id="release-summary-24"></a>
+<a id="release-summary-25"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-23"></a>
+<a id="bugfixes-24"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -593,17 +639,17 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-3-1"></a>
## v2\.3\.1
-<a id="release-summary-25"></a>
+<a id="release-summary-26"></a>
### Release Summary
Maintenance release including an updated Public Suffix List\.
-<a id="minor-changes-5"></a>
+<a id="minor-changes-6"></a>
### Minor Changes
* The collection repository conforms to the [REUSE specification](https\://reuse\.software/spec/) except for the changelog fragments \([https\://github\.com/ansible\-collections/community\.dns/pull/112](https\://github\.com/ansible\-collections/community\.dns/pull/112)\)\.
-<a id="bugfixes-24"></a>
+<a id="bugfixes-25"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -611,17 +657,17 @@ Maintenance release including an updated Public Suffix List\.
<a id="v2-3-0"></a>
## v2\.3\.0
-<a id="release-summary-26"></a>
+<a id="release-summary-27"></a>
### Release Summary
Maintenance release including an updated Public Suffix List\.
-<a id="minor-changes-6"></a>
+<a id="minor-changes-7"></a>
### Minor Changes
* All software licenses are now in the <code>LICENSES/</code> directory of the collection root\. Moreover\, <code>SPDX\-License\-Identifier\:</code> is used to declare the applicable license for every file that is not automatically generated \([https\://github\.com/ansible\-collections/community\.dns/pull/109](https\://github\.com/ansible\-collections/community\.dns/pull/109)\)\.
-<a id="bugfixes-25"></a>
+<a id="bugfixes-26"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -629,12 +675,12 @@ Maintenance release including an updated Public Suffix List\.
<a id="v2-2-1"></a>
## v2\.2\.1
-<a id="release-summary-27"></a>
+<a id="release-summary-28"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-26"></a>
+<a id="bugfixes-27"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -642,18 +688,18 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-2-0"></a>
## v2\.2\.0
-<a id="release-summary-28"></a>
+<a id="release-summary-29"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-7"></a>
+<a id="minor-changes-8"></a>
### Minor Changes
* hetzner\_dns\_records and hosttech\_dns\_records inventory plugins \- allow to template provider\-specific credentials and the <code>zone\_name</code>\, <code>zone\_id</code> options \([https\://github\.com/ansible\-collections/community\.dns/pull/106](https\://github\.com/ansible\-collections/community\.dns/pull/106)\)\.
* wait\_for\_txt \- improve error messages so that in case of SERVFAILs or other DNS errors it is clear which record was queried from which DNS server \([https\://github\.com/ansible\-collections/community\.dns/pull/105](https\://github\.com/ansible\-collections/community\.dns/pull/105)\)\.
-<a id="bugfixes-27"></a>
+<a id="bugfixes-28"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -661,12 +707,12 @@ Feature release\.
<a id="v2-1-1"></a>
## v2\.1\.1
-<a id="release-summary-29"></a>
+<a id="release-summary-30"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-28"></a>
+<a id="bugfixes-29"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -674,17 +720,17 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-1-0"></a>
## v2\.1\.0
-<a id="release-summary-30"></a>
+<a id="release-summary-31"></a>
### Release Summary
Feature and maintenance release with updated PSL\.
-<a id="minor-changes-8"></a>
+<a id="minor-changes-9"></a>
### Minor Changes
* Prepare collection for inclusion in an Execution Environment by declaring its dependencies \([https\://github\.com/ansible\-collections/community\.dns/pull/93](https\://github\.com/ansible\-collections/community\.dns/pull/93)\)\.
-<a id="bugfixes-29"></a>
+<a id="bugfixes-30"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -692,12 +738,12 @@ Feature and maintenance release with updated PSL\.
<a id="v2-0-9"></a>
## v2\.0\.9
-<a id="release-summary-31"></a>
+<a id="release-summary-32"></a>
### Release Summary
Maintenance release with updated Public Suffix List and added collection links file\.
-<a id="bugfixes-30"></a>
+<a id="bugfixes-31"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -705,12 +751,12 @@ Maintenance release with updated Public Suffix List and added collection links f
<a id="v2-0-8"></a>
## v2\.0\.8
-<a id="release-summary-32"></a>
+<a id="release-summary-33"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-31"></a>
+<a id="bugfixes-32"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -718,12 +764,12 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-0-7"></a>
## v2\.0\.7
-<a id="release-summary-33"></a>
+<a id="release-summary-34"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-32"></a>
+<a id="bugfixes-33"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -731,12 +777,12 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-0-6"></a>
## v2\.0\.6
-<a id="release-summary-34"></a>
+<a id="release-summary-35"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-33"></a>
+<a id="bugfixes-34"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -745,12 +791,12 @@ Bugfix release\.
<a id="v2-0-5"></a>
## v2\.0\.5
-<a id="release-summary-35"></a>
+<a id="release-summary-36"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-34"></a>
+<a id="bugfixes-35"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -758,12 +804,12 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-0-4"></a>
## v2\.0\.4
-<a id="release-summary-36"></a>
+<a id="release-summary-37"></a>
### Release Summary
Maintenance release with updated Public Suffix List\.
-<a id="bugfixes-35"></a>
+<a id="bugfixes-36"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -771,12 +817,12 @@ Maintenance release with updated Public Suffix List\.
<a id="v2-0-3"></a>
## v2\.0\.3
-<a id="release-summary-37"></a>
+<a id="release-summary-38"></a>
### Release Summary
Bugfix release\.
-<a id="minor-changes-9"></a>
+<a id="minor-changes-10"></a>
### Minor Changes
* HTTP API module utils \- fix usage of <code>fetch\_url</code> with changes in latest ansible\-core <code>devel</code> branch \([https\://github\.com/ansible\-collections/community\.dns/pull/73](https\://github\.com/ansible\-collections/community\.dns/pull/73)\)\.
@@ -784,12 +830,12 @@ Bugfix release\.
<a id="v2-0-2"></a>
## v2\.0\.2
-<a id="release-summary-38"></a>
+<a id="release-summary-39"></a>
### Release Summary
Regular maintenance release\.
-<a id="bugfixes-36"></a>
+<a id="bugfixes-37"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -797,12 +843,12 @@ Regular maintenance release\.
<a id="v2-0-1"></a>
## v2\.0\.1
-<a id="release-summary-39"></a>
+<a id="release-summary-40"></a>
### Release Summary
Maintenance release with Public Suffix List updates\.
-<a id="bugfixes-37"></a>
+<a id="bugfixes-38"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -810,12 +856,12 @@ Maintenance release with Public Suffix List updates\.
<a id="v2-0-0"></a>
## v2\.0\.0
-<a id="release-summary-40"></a>
+<a id="release-summary-41"></a>
### Release Summary
This release contains many new features\, modules and plugins\, but also has several breaking changes to the 1\.x\.y versions\. Please read the changelog carefully to determine what to change if you used an earlier version of this collection\.
-<a id="minor-changes-10"></a>
+<a id="minor-changes-11"></a>
### Minor Changes
* Add support for Hetzner DNS \([https\://github\.com/ansible\-collections/community\.dns/pull/27](https\://github\.com/ansible\-collections/community\.dns/pull/27)\)\.
@@ -831,7 +877,7 @@ This release contains many new features\, modules and plugins\, but also has sev
* hosttech\_dns\_record\_sets \- <code>records</code> has been renamed to <code>record\_sets</code>\. The old name <code>records</code> can still be used as an alias \([https\://github\.com/ansible\-collections/community\.dns/pull/31](https\://github\.com/ansible\-collections/community\.dns/pull/31)\)\.
* hosttech\_dns\_zone\_info \- return extra information as <code>zone\_info</code> \([https\://github\.com/ansible\-collections/community\.dns/pull/38](https\://github\.com/ansible\-collections/community\.dns/pull/38)\)\.
-<a id="breaking-changes--porting-guide"></a>
+<a id="breaking-changes--porting-guide-1"></a>
### Breaking Changes / Porting Guide
* All Hetzner modules and plugins which handle DNS records now work with unquoted TXT values by default\. The old behavior can be obtained by setting <code>txt\_transformation\=api</code> \([https\://github\.com/ansible\-collections/community\.dns/issues/48](https\://github\.com/ansible\-collections/community\.dns/issues/48)\, [https\://github\.com/ansible\-collections/community\.dns/pull/57](https\://github\.com/ansible\-collections/community\.dns/pull/57)\, [https\://github\.com/ansible\-collections/community\.dns/pull/60](https\://github\.com/ansible\-collections/community\.dns/pull/60)\)\.
@@ -850,7 +896,7 @@ This release contains many new features\, modules and plugins\, but also has sev
* The hosttech\_dns\_records module has been renamed to hosttech\_dns\_record\_sets\. The old name will stop working in community\.dns 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.dns/pull/31](https\://github\.com/ansible\-collections/community\.dns/pull/31)\)\.
-<a id="bugfixes-38"></a>
+<a id="bugfixes-39"></a>
### Bugfixes
* Hetzner API \- interpret missing TTL as 300\, which is what the web console also does \([https\://github\.com/ansible\-collections/community\.dns/pull/42](https\://github\.com/ansible\-collections/community\.dns/pull/42)\)\.
@@ -888,19 +934,19 @@ This release contains many new features\, modules and plugins\, but also has sev
<a id="v1-2-0"></a>
## v1\.2\.0
-<a id="release-summary-41"></a>
+<a id="release-summary-42"></a>
### Release Summary
Last minor 1\.x\.0 version\. The 2\.0\.0 version will have some backwards incompatible changes to the <code>hosttech\_dns\_record</code> and <code>hosttech\_dns\_records</code> modules which will require user intervention\. These changes should result in a better UX\.
-<a id="minor-changes-11"></a>
+<a id="minor-changes-12"></a>
### Minor Changes
* hosttech modules \- add <code>api\_token</code> alias for <code>hosttech\_token</code> \([https\://github\.com/ansible\-collections/community\.dns/pull/26](https\://github\.com/ansible\-collections/community\.dns/pull/26)\)\.
* hosttech\_dns\_record \- in <code>diff</code> mode\, also return <code>diff</code> data structure when <code>changed</code> is <code>false</code> \([https\://github\.com/ansible\-collections/community\.dns/pull/28](https\://github\.com/ansible\-collections/community\.dns/pull/28)\)\.
* module utils \- add default implementation for some zone/record API functions\, and move common JSON API code to helper class \([https\://github\.com/ansible\-collections/community\.dns/pull/26](https\://github\.com/ansible\-collections/community\.dns/pull/26)\)\.
-<a id="bugfixes-39"></a>
+<a id="bugfixes-40"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -909,17 +955,17 @@ Last minor 1\.x\.0 version\. The 2\.0\.0 version will have some backwards incomp
<a id="v1-1-0"></a>
## v1\.1\.0
-<a id="release-summary-42"></a>
+<a id="release-summary-43"></a>
### Release Summary
Regular maintenance release\.
-<a id="minor-changes-12"></a>
+<a id="minor-changes-13"></a>
### Minor Changes
* Avoid internal ansible\-core module\_utils in favor of equivalent public API available since at least Ansible 2\.9 \([https\://github\.com/ansible\-collections/community\.dns/pull/24](https\://github\.com/ansible\-collections/community\.dns/pull/24)\)\.
-<a id="bugfixes-40"></a>
+<a id="bugfixes-41"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -927,12 +973,12 @@ Regular maintenance release\.
<a id="v1-0-1"></a>
## v1\.0\.1
-<a id="release-summary-43"></a>
+<a id="release-summary-44"></a>
### Release Summary
Regular maintenance release\.
-<a id="bugfixes-41"></a>
+<a id="bugfixes-42"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -940,12 +986,12 @@ Regular maintenance release\.
<a id="v1-0-0"></a>
## v1\.0\.0
-<a id="release-summary-44"></a>
+<a id="release-summary-45"></a>
### Release Summary
First stable release\.
-<a id="bugfixes-42"></a>
+<a id="bugfixes-43"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -953,17 +999,17 @@ First stable release\.
<a id="v0-3-0"></a>
## v0\.3\.0
-<a id="release-summary-45"></a>
+<a id="release-summary-46"></a>
### Release Summary
Fixes bugs\, adds rate limiting for Hosttech JSON API\, and adds a new bulk synchronization module\.
-<a id="minor-changes-13"></a>
+<a id="minor-changes-14"></a>
### Minor Changes
* hosttech\_dns\_\* \- handle <code>419 Too Many Requests</code> with proper rate limiting for JSON API \([https\://github\.com/ansible\-collections/community\.dns/pull/14](https\://github\.com/ansible\-collections/community\.dns/pull/14)\)\.
-<a id="bugfixes-43"></a>
+<a id="bugfixes-44"></a>
### Bugfixes
* Avoid converting ASCII labels which contain underscores or other printable ASCII characters outside <code>\[a\-zA\-Z0\-9\-\]</code> to alabels during normalization \([https\://github\.com/ansible\-collections/community\.dns/pull/13](https\://github\.com/ansible\-collections/community\.dns/pull/13)\)\.
@@ -977,17 +1023,17 @@ Fixes bugs\, adds rate limiting for Hosttech JSON API\, and adds a new bulk sync
<a id="v0-2-0"></a>
## v0\.2\.0
-<a id="release-summary-46"></a>
+<a id="release-summary-47"></a>
### Release Summary
Major refactoring release\, which adds a zone information module and supports HostTech\'s new REST API\.
-<a id="major-changes"></a>
+<a id="major-changes-1"></a>
### Major Changes
* hosttech\_\* modules \- support the new JSON API at [https\://api\.ns1\.hosttech\.eu/api/documentation/](https\://api\.ns1\.hosttech\.eu/api/documentation/) \([https\://github\.com/ansible\-collections/community\.dns/pull/4](https\://github\.com/ansible\-collections/community\.dns/pull/4)\)\.
-<a id="minor-changes-14"></a>
+<a id="minor-changes-15"></a>
### Minor Changes
* hosttech\_dns\_record\* modules \- allow to specify <code>prefix</code> instead of <code>record</code> \([https\://github\.com/ansible\-collections/community\.dns/pull/8](https\://github\.com/ansible\-collections/community\.dns/pull/8)\)\.
@@ -997,12 +1043,12 @@ Major refactoring release\, which adds a zone information module and supports Ho
* hosttech\_dns\_record\_info \- also return <code>prefix</code> for a record set \([https\://github\.com/ansible\-collections/community\.dns/pull/8](https\://github\.com/ansible\-collections/community\.dns/pull/8)\)\.
* hosttech\_record \- allow to delete records without querying their content first by specifying <code>overwrite\=true</code> \([https\://github\.com/ansible\-collections/community\.dns/pull/4](https\://github\.com/ansible\-collections/community\.dns/pull/4)\)\.
-<a id="breaking-changes--porting-guide-1"></a>
+<a id="breaking-changes--porting-guide-2"></a>
### Breaking Changes / Porting Guide
* hosttech\_\* module\_utils \- completely rewrite and refactor to support new JSON API and allow to reuse provider\-independent module logic \([https\://github\.com/ansible\-collections/community\.dns/pull/4](https\://github\.com/ansible\-collections/community\.dns/pull/4)\)\.
-<a id="bugfixes-44"></a>
+<a id="bugfixes-45"></a>
### Bugfixes
* Update Public Suffix List\.
@@ -1017,7 +1063,7 @@ Major refactoring release\, which adds a zone information module and supports Ho
<a id="v0-1-0"></a>
## v0\.1\.0
-<a id="release-summary-47"></a>
+<a id="release-summary-48"></a>
### Release Summary
Initial public release\.
diff --git a/ansible_collections/community/dns/CHANGELOG.rst b/ansible_collections/community/dns/CHANGELOG.rst
index e91d83ebf..9aef9afb1 100644
--- a/ansible_collections/community/dns/CHANGELOG.rst
+++ b/ansible_collections/community/dns/CHANGELOG.rst
@@ -4,6 +4,45 @@ Community DNS Collection Release Notes
.. contents:: Topics
+v3.0.0
+======
+
+Release Summary
+---------------
+
+...
+
+Major Changes
+-------------
+
+- The ``community.dns`` collection now depends on the ``community.library_inventory_filtering_v1`` collection. This utility collection provides host filtering functionality for inventory plugins. If you use the Ansible community package, both collections are included and you do not have to do anything special. If you install the collection with ``ansible-galaxy collection install``, it will be installed automatically. If you install the collection by copying the files of the collection to a place where ansible-core can find it, for example by cloning the git repository, you need to make sure that you also have to install the dependency if you are using the inventory plugins (https://github.com/ansible-collections/community.dns/pull/196).
+
+Minor Changes
+-------------
+
+- inventory plugins - add ``filter`` option which allows to include and exclude hosts based on Jinja2 conditions (https://github.com/ansible-collections/community.dns/pull/196).
+- lookup, lookup_as_dict - it is now possible to configure whether the input should be treated as an absolute domain name (``search=false``), or potentially as a relative domain name (``search=true``) (https://github.com/ansible-collections/community.dns/issues/200, https://github.com/ansible-collections/community.dns/pull/201).
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- The default for the ``txt_character_encoding`` options in various modules and plugins changed from ``octal`` to ``decimal`` (https://github.com/ansible-collections/community.dns/pull/196).
+- inventory plugins - ``filters`` is now no longer an alias of ``simple_filters``, but a new, different option (https://github.com/ansible-collections/community.dns/pull/196).
+- inventory plugins - the ``plugin`` option is now required (https://github.com/ansible-collections/community.dns/pull/196).
+- lookup, lookup_as_dict - the default for ``search`` changed from ``false`` (implicit default for community.dns 2.x.y) to ``true`` (https://github.com/ansible-collections/community.dns/issues/200, https://github.com/ansible-collections/community.dns/pull/201).
+
+Removed Features (previously deprecated)
+----------------------------------------
+
+- The collection no longer supports Ansible, ansible-base, and ansible-core releases that are currently End of Life at the time of the 3.0.0 release. This means that Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14 are no longer supported. The collection might still work with these versions, but it can stop working at any moment without advance notice, and this will not be considered a bug (https://github.com/ansible-collections/community.dns/pull/196).
+- hetzner_dns_record_set, hetzner_dns_record - the deprecated alias ``name`` of the prefix option was removed (https://github.com/ansible-collections/community.dns/pull/196).
+- hosttech_dns_records - the redirect to the ``hosttech_dns_record_sets`` module has been removed (https://github.com/ansible-collections/community.dns/pull/196).
+
+Bugfixes
+--------
+
+- Update Public Suffix List.
+
v2.9.0
======
diff --git a/ansible_collections/community/dns/FILES.json b/ansible_collections/community/dns/FILES.json
index 52b3239cd..32915c500 100644
--- a/ansible_collections/community/dns/FILES.json
+++ b/ansible_collections/community/dns/FILES.json
@@ -25,7 +25,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4ef2a19d9715b2b9a70a6fe716ec40726b3c425f3c2b96d9bfe5d12489f74574",
+ "chksum_sha256": "02ff9da8ae9991541407a1f05a5b2bafa3d558213b44c63287665d370c4091da",
"format": 1
},
{
@@ -53,14 +53,14 @@
"name": ".github/workflows/ee.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bcef35a96fa3202cfec5d7adcb76b93124fa08e1a8c6dd914bf8cbb8aed28f11",
+ "chksum_sha256": "dcd1d5b0f91b932e5b535b9e5c08a3b02123e089a1ac1846f8bad9ba892e9893",
"format": 1
},
{
"name": ".github/workflows/extra-tests.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c7ed351192ec963495e9a1752c3ecd914698582affd90dec5065c7f2180fe1dc",
+ "chksum_sha256": "67094594a3f5090d92cbc78fd0c1020ed3c1a30f69a850b92de3a226692a01e0",
"format": 1
},
{
@@ -151,7 +151,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d6afad220bd94bbf6ffd765666b7589d04b014238a3e02973e066958c44acf43",
+ "chksum_sha256": "1f73967d9bae45a0341f90dd810cd70afa17786df1d296e5803f18f4d5c4d33c",
"format": 1
},
{
@@ -200,7 +200,7 @@
"name": "docs/docsite/rst/hetzner_guide.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b7f406b5c5d7921909eb2196feae0ec9a28e18ee5a2ce08e0a8db50c3e2506f6",
+ "chksum_sha256": "06fa52a3c1e246e5cee3b9b556c412b842a109ab37a56121754a81819327f9d3",
"format": 1
},
{
@@ -256,7 +256,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a0f15da8558a0fcbe370883adaa3a3982a99ae3d93e785523b126d1912bcc30a",
+ "chksum_sha256": "402e41b8f52840f3e00165fbac091febdb9542600fec9626c654f16569fa4b82",
"format": 1
},
{
@@ -305,7 +305,7 @@
"name": "plugins/doc_fragments/inventory_records.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ca51ab2e9350f36f68827a2fa86145ad0865838ac43313e07e09f853fd6e1f3c",
+ "chksum_sha256": "acae110608db050d3f39ae87490c4d94c80a6fc0d7eff427eb3b39b3c1c443ae",
"format": 1
},
{
@@ -354,7 +354,7 @@
"name": "plugins/doc_fragments/options.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d6187dcb10a41b78a6bf385d22a3fafe2c1a8e69b296aeb8292d109edfab3b22",
+ "chksum_sha256": "99f9e241c2b7937cfe03684be5d83b5b5fba46f114776731da4b81de244603db",
"format": 1
},
{
@@ -431,14 +431,14 @@
"name": "plugins/inventory/hetzner_dns_records.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b6531b5ee8da29ac4909eeb4db27b9d5c232c8acfd8741dc99cc6d5877ccf213",
+ "chksum_sha256": "2321c6f2bbf813769d033a2ea087874c59b165503e6e9d63e7538485eafd7745",
"format": 1
},
{
"name": "plugins/inventory/hosttech_dns_records.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ed0fef2e327ea3103a8e3c08a0af587f1cc48c6239ad14e3164f706e86d7f160",
+ "chksum_sha256": "ceb63f67d1c2b3c60d50b6bd8838cf1125057e6e79dcfe87295bf9700d1acac0",
"format": 1
},
{
@@ -452,14 +452,14 @@
"name": "plugins/lookup/lookup.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6571e35773f4c9116eaf7c21e5c25ab95d803e54d3c929e6b94b82eaa503d8ee",
+ "chksum_sha256": "8bdcf8b3091a59c20b4aa656150055959b8c24d378a0d96b565629d99d49ce77",
"format": 1
},
{
"name": "plugins/lookup/lookup_as_dict.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2eb51bdf708dc19c84dd15e16c8804570922cdf0b5cfad337c7a85c93b326750",
+ "chksum_sha256": "707a51ebeff3a2cbf1ae4324e1dcf7fb7e589af3ef44c67cb0336c95c81c75dc",
"format": 1
},
{
@@ -487,7 +487,7 @@
"name": "plugins/module_utils/conversion/converter.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "06a3d891a5c81bc1552ba2be7d7bca8cae84c1d7a9e51fb0bd9d7e957e02b575",
+ "chksum_sha256": "db2ac83bb84e53abafccd7ec6974059c37e03b18e6265ea07490bcc23879dafe",
"format": 1
},
{
@@ -641,14 +641,14 @@
"name": "plugins/module_utils/options.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9ab338a1f293a6bb6b041a8a01d99885dc6388b672a8ca01f78ac37615089f09",
+ "chksum_sha256": "40ae1e4a499762415df77dc1778b6c8679d71a8b004945537f0c631afef926f0",
"format": 1
},
{
"name": "plugins/module_utils/provider.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "894a0fb9f647b50f80ec6cad79181804cc0a2be8aa5fb3c9875d0524647445f3",
+ "chksum_sha256": "248dbb61a2c77dd8389e7d9cb6fe53650ce9d4b7a9a6c973c6f41e5bc7ab4d00",
"format": 1
},
{
@@ -662,7 +662,7 @@
"name": "plugins/module_utils/resolver.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2d0ceedf04f529e982d7865daa9c7d56b4ba49361e665a5e246fb4f3f4de569a",
+ "chksum_sha256": "5b3faecab5ba159a7208509ed2511519343cdae5ed3def6d511e4458a4df3ccf",
"format": 1
},
{
@@ -701,17 +701,10 @@
"format": 1
},
{
- "name": "plugins/modules/hosttech_dns_records.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "fe2c760eaf5bccaed8abbefe6dd6952b428fd05c0cc48919dc579acc7ad57141",
- "format": 1
- },
- {
"name": "plugins/modules/hetzner_dns_record.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "235b7a73ce5f2a9e74098f8c4100fbe2ca828a13ec021872392e5f0442cc6e56",
+ "chksum_sha256": "eb5ecec9883413c8ba73e29877c051561eb62b0ba15cd947ee0bb679744106af",
"format": 1
},
{
@@ -725,7 +718,7 @@
"name": "plugins/modules/hetzner_dns_record_set.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "35f71b7b8f680261f51b78d7c34cf4d89f490ba5937674614055cd6593e578d3",
+ "chksum_sha256": "8b6617b6ffc67eab9ea1bdd3d7eab779588d6bea372b55cc051e3a33c2f077c1",
"format": 1
},
{
@@ -830,7 +823,7 @@
"name": "plugins/plugin_utils/inventory/records.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "768ceedc4f0b624a22f9b777452f143e0b88639c1bd7e5f861d789ec0269e6e1",
+ "chksum_sha256": "6f8073358134147fc4c46631dff39aaac94215423a68c622b29802459acb61c6",
"format": 1
},
{
@@ -872,7 +865,7 @@
"name": "plugins/public_suffix_list.dat",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "27ae0b652366e8c5675942482de87819cf7947f5f4dc7bc661dc82b9b5da2d04",
+ "chksum_sha256": "437ffb5d25e5dee3fa4fef0109aac0e37f2f67b03a6787eeb22db831e308efe9",
"format": 1
},
{
@@ -1012,7 +1005,7 @@
"name": "tests/integration/targets/filter_txt/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ec0d81efcabab342ec8b892fdf9bcd54bf488a3b92a81a0efbe09f26e2d80c27",
+ "chksum_sha256": "089c3a08e5c4c1111c6a429944ceb1ecccd22ad4f3991ddfbbd07fd9ae4b3ccd",
"format": 1
},
{
@@ -1579,14 +1572,14 @@
"name": "tests/unit/plugins/inventory/test_hetzner_dns_records.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fcb263ece98ce1696cd5bbe594b86911d3365d9e8dfd9858ffbf6735c5dd46d2",
+ "chksum_sha256": "2695e818ea088c60143c39a2fa7610b885af292ff6b182559e77d3d2189070de",
"format": 1
},
{
"name": "tests/unit/plugins/inventory/test_hosttech_dns_records.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "20aafd958aa2e24b07b610c7d4efbee67cab74ecaada25876889564de7fe01d6",
+ "chksum_sha256": "c630d5dc0c2fbf2c0eb421e906e1f443c65b4fae6321ee76e72ebec2a3be8dd4",
"format": 1
},
{
@@ -1600,14 +1593,14 @@
"name": "tests/unit/plugins/lookup/test_lookup.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a888fcf181730c2aae23357e0a073cbf1996a2172b13ea8c96e0ab17623937af",
+ "chksum_sha256": "0e84b4e2cb5b44d4bf325440a9a20e1392d1f1b70af31cc077b6375d377abdf0",
"format": 1
},
{
"name": "tests/unit/plugins/lookup/test_lookup_as_dict.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "283ff7237b352e16cc23b413fd05b39bcb474c047f1662507f7c078a56d0814e",
+ "chksum_sha256": "65ec26898c31f97e5f155b520779aace7f0a056ea9654c662aadb4931630dee8",
"format": 1
},
{
@@ -1698,7 +1691,7 @@
"name": "tests/unit/plugins/module_utils/resolver_helper.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1732b34b946b6911c9cc9690330f589691a71eccc1344d1973f31d3814327bf8",
+ "chksum_sha256": "8a4819cb5ff96f0f58fac8407282943e51afa11807bc7334f54515c6b7c71568",
"format": 1
},
{
@@ -1817,7 +1810,7 @@
"name": "tests/unit/plugins/modules/test_hetzner_dns_record_set_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f69a48413b461b5b7232b3eb6aab1ce61475922d47372bb621052366ce9e185d",
+ "chksum_sha256": "c4a5ab6f9c3bdd64c04321fe7d0bda4f0a9a5ffac691ae5d1a94979997e0ecd6",
"format": 1
},
{
@@ -1926,6 +1919,13 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/plugin_utils/test_unsafe.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a48876d3a7e7dbc9fca656b2476824138ca1cd1c630a9b116c6398cf63d9f0ca",
+ "format": 1
+ },
+ {
"name": "tests/unit/replace-requirements.sh",
"ftype": "file",
"chksum_type": "sha256",
@@ -1971,7 +1971,7 @@
"name": "CHANGELOG.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bc56ad1ca72650697ca9f41b004a70f54ef329c79938268b1430d0dac8fa51d6",
+ "chksum_sha256": "1489e680b9d05205a48e068d84dc804325584d49005222f1f506f42ad49ae63a",
"format": 1
},
{
@@ -1985,7 +1985,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6dd1dbacede2c19ab983288d1fccde3d6369642593b1da10029cdf53e6b3176c",
+ "chksum_sha256": "8d243919ca88dbc2725a0b5a94ee622f405d42abcef4d6072f76c6539d1eef5a",
"format": 1
},
{
@@ -2013,7 +2013,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "61615f641d8efd57833806770c66a86dfe2ceb595df9fe1e9ef1fc0d9e2bfab4",
+ "chksum_sha256": "216c0accaebda45205edabf0713d372f195393f49be5a94d6ba5e3fb6847502a",
"format": 1
},
{
diff --git a/ansible_collections/community/dns/MANIFEST.json b/ansible_collections/community/dns/MANIFEST.json
index 0c60fe528..08e4d9c66 100644
--- a/ansible_collections/community/dns/MANIFEST.json
+++ b/ansible_collections/community/dns/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "dns",
- "version": "2.9.0",
+ "version": "3.0.0",
"authors": [
"Felix Fontein (github.com/felixfontein)",
"Markus Bergholz (github.com/markuman)"
@@ -20,7 +20,9 @@
"MPL-2.0"
],
"license_file": null,
- "dependencies": {},
+ "dependencies": {
+ "community.library_inventory_filtering_v1": ">=1.0.0"
+ },
"repository": "https://github.com/ansible-collections/community.dns",
"documentation": "https://docs.ansible.com/ansible/devel/collections/community/dns/",
"homepage": "https://github.com/ansible-collections/community.dns",
@@ -30,7 +32,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "723a758354360ce388c0f83a88527e05dc67d3bcad6495e66deca44b8a169d12",
+ "chksum_sha256": "ba0f38847eafe7b48453fb5a53d01010332adb7982622a61061c9df456b18e68",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/dns/README.md b/ansible_collections/community/dns/README.md
index 32257a110..5a0ab4d42 100644
--- a/ansible_collections/community/dns/README.md
+++ b/ansible_collections/community/dns/README.md
@@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
[![CI](https://github.com/ansible-collections/community.dns/workflows/CI/badge.svg?event=push)](https://github.com/ansible-collections/community.dns/actions)
[![Public Suffix List up-to-date](https://github.com/ansible-collections/community.dns/workflows/Check%20for%20Public%20Suffix%20List%20updates/badge.svg?branch=main)](https://github.com/ansible-collections/community.dns/actions?query=workflow%3A%22Check+for+Public+Suffix+List+updates%22+branch%3Amain)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.dns)](https://codecov.io/gh/ansible-collections/community.dns)
+[![REUSE status](https://api.reuse.software/badge/github.com/ansible-collections/community.dns)](https://api.reuse.software/info/github.com/ansible-collections/community.dns)
This repository contains the `community.dns` Ansible Collection. The collection includes plugins and modules to work with DNS.
@@ -16,7 +17,7 @@ Please note that this collection does **not** support Windows targets.
## Tested with Ansible
-Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, and ansible-core 2.17 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
+Tested with the current ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, and ansible-core 2.17 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
## External requirements
diff --git a/ansible_collections/community/dns/changelogs/changelog.yaml b/ansible_collections/community/dns/changelogs/changelog.yaml
index 3eafad115..230527b2b 100644
--- a/ansible_collections/community/dns/changelogs/changelog.yaml
+++ b/ansible_collections/community/dns/changelogs/changelog.yaml
@@ -829,3 +829,52 @@ releases:
name: unquote_txt
namespace: null
release_date: '2024-04-21'
+ 3.0.0:
+ changes:
+ breaking_changes:
+ - The default for the ``txt_character_encoding`` options in various modules
+ and plugins changed from ``octal`` to ``decimal`` (https://github.com/ansible-collections/community.dns/pull/196).
+ - inventory plugins - ``filters`` is now no longer an alias of ``simple_filters``,
+ but a new, different option (https://github.com/ansible-collections/community.dns/pull/196).
+ - inventory plugins - the ``plugin`` option is now required (https://github.com/ansible-collections/community.dns/pull/196).
+ - lookup, lookup_as_dict - the default for ``search`` changed from ``false``
+ (implicit default for community.dns 2.x.y) to ``true`` (https://github.com/ansible-collections/community.dns/issues/200,
+ https://github.com/ansible-collections/community.dns/pull/201).
+ bugfixes:
+ - Update Public Suffix List.
+ major_changes:
+ - The ``community.dns`` collection now depends on the ``community.library_inventory_filtering_v1``
+ collection. This utility collection provides host filtering functionality
+ for inventory plugins. If you use the Ansible community package, both collections
+ are included and you do not have to do anything special. If you install the
+ collection with ``ansible-galaxy collection install``, it will be installed
+ automatically. If you install the collection by copying the files of the collection
+ to a place where ansible-core can find it, for example by cloning the git
+ repository, you need to make sure that you also have to install the dependency
+ if you are using the inventory plugins (https://github.com/ansible-collections/community.dns/pull/196).
+ minor_changes:
+ - inventory plugins - add ``filter`` option which allows to include and exclude
+ hosts based on Jinja2 conditions (https://github.com/ansible-collections/community.dns/pull/196).
+ - lookup, lookup_as_dict - it is now possible to configure whether the input
+ should be treated as an absolute domain name (``search=false``), or potentially
+ as a relative domain name (``search=true``) (https://github.com/ansible-collections/community.dns/issues/200,
+ https://github.com/ansible-collections/community.dns/pull/201).
+ release_summary: '...
+
+ '
+ removed_features:
+ - The collection no longer supports Ansible, ansible-base, and ansible-core
+ releases that are currently End of Life at the time of the 3.0.0 release.
+ This means that Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core
+ 2.12, ansible-core 2.13, and ansible-core 2.14 are no longer supported. The
+ collection might still work with these versions, but it can stop working at
+ any moment without advance notice, and this will not be considered a bug (https://github.com/ansible-collections/community.dns/pull/196).
+ - hetzner_dns_record_set, hetzner_dns_record - the deprecated alias ``name``
+ of the prefix option was removed (https://github.com/ansible-collections/community.dns/pull/196).
+ - hosttech_dns_records - the redirect to the ``hosttech_dns_record_sets`` module
+ has been removed (https://github.com/ansible-collections/community.dns/pull/196).
+ fragments:
+ - 201-lookup-search.yml
+ - 3.0.0.yml
+ - update-psl.yml
+ release_date: '2024-05-19'
diff --git a/ansible_collections/community/dns/docs/docsite/rst/hetzner_guide.rst b/ansible_collections/community/dns/docs/docsite/rst/hetzner_guide.rst
index 8c0e34e26..f22412286 100644
--- a/ansible_collections/community/dns/docs/docsite/rst/hetzner_guide.rst
+++ b/ansible_collections/community/dns/docs/docsite/rst/hetzner_guide.rst
@@ -463,7 +463,7 @@ When :ansopt:`value` is not specified, the ``markuman.hetzner_dns.record`` modul
# 'type' does not change:
type: A
-A last step is replacing the deprecated alias :ansopt:`community.dns.hetzner_dns_record_set#module:name` of :ansopt:`community.dns.hetzner_dns_record_set#module:prefix` by :ansopt:`community.dns.hetzner_dns_record_set#module:prefix`. This can be done later though, if you do not mind the deprecation warnings.
+A last step is replacing the removed alias ``name`` of :ansopt:`community.dns.hetzner_dns_record_set#module:prefix` by :ansopt:`community.dns.hetzner_dns_record_set#module:prefix`.
The markuman.hetzner_dns.record_info module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/ansible_collections/community/dns/meta/runtime.yml b/ansible_collections/community/dns/meta/runtime.yml
index 25f52c7a8..2cb1350ea 100644
--- a/ansible_collections/community/dns/meta/runtime.yml
+++ b/ansible_collections/community/dns/meta/runtime.yml
@@ -3,7 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
-requires_ansible: '>=2.9.10'
+requires_ansible: '>=2.14.0'
action_groups:
hetzner:
- hetzner_dns_record_info
@@ -18,12 +18,10 @@ action_groups:
- hosttech_dns_record_set_info
- hosttech_dns_record_set
- hosttech_dns_record_sets
- - hosttech_dns_records # deprecated redirect
- hosttech_dns_zone_info
plugin_routing:
modules:
hosttech_dns_records:
- redirect: community.dns.hosttech_dns_record_sets
- deprecation:
+ tombstone:
removal_version: 3.0.0
warning_text: The hosttech_dns_records module has been renamed to hosttech_dns_record_sets.
diff --git a/ansible_collections/community/dns/plugins/doc_fragments/inventory_records.py b/ansible_collections/community/dns/plugins/doc_fragments/inventory_records.py
index e7a90a7b7..760ba1590 100644
--- a/ansible_collections/community/dns/plugins/doc_fragments/inventory_records.py
+++ b/ansible_collections/community/dns/plugins/doc_fragments/inventory_records.py
@@ -34,11 +34,10 @@ options:
simple_filters:
description:
- A dictionary of filter value pairs.
- - This option has been renamed from O(filters) to O(simple_filters) in community.dns 2.8.0.
- The old name can still be used until community.dns 3.0.0.
+ - This option used to be called O(filters) before community.dns 3.0.0. It has been renamed from
+ O(filters) to O(simple_filters) in community.dns 2.8.0, and the old name was still available
+ as an alias until community.dns 3.0.0. O(filters) is now used for something else.
type: dict
- aliases:
- - filters
default: {}
suboptions:
# (The following must be kept in sync with the equivalent lines in <provider_name>.py!)
diff --git a/ansible_collections/community/dns/plugins/doc_fragments/options.py b/ansible_collections/community/dns/plugins/doc_fragments/options.py
index 55c83f1b2..9b892c711 100644
--- a/ansible_collections/community/dns/plugins/doc_fragments/options.py
+++ b/ansible_collections/community/dns/plugins/doc_fragments/options.py
@@ -55,11 +55,12 @@ options:
description:
- Whether to treat numeric escape sequences (V(\\xyz)) as octal or decimal numbers.
This is only used when O(txt_transformation=quoted).
- - The current default is V(octal) which is deprecated. It will change to V(decimal) in
- community.dns 3.0.0. The value V(decimal) is compatible to L(RFC 1035, https://www.ietf.org/rfc/rfc1035.txt).
+ - The default changed to V(decimal) in community.dns 3.0.0. Before, the default used to be V(octal).
+ The value V(decimal) is compatible to L(RFC 1035, https://www.ietf.org/rfc/rfc1035.txt).
type: str
choices:
- decimal
- octal
+ default: decimal
version_added: 2.5.0
'''
diff --git a/ansible_collections/community/dns/plugins/inventory/hetzner_dns_records.py b/ansible_collections/community/dns/plugins/inventory/hetzner_dns_records.py
index 7982c23f0..8fe1d9465 100644
--- a/ansible_collections/community/dns/plugins/inventory/hetzner_dns_records.py
+++ b/ansible_collections/community/dns/plugins/inventory/hetzner_dns_records.py
@@ -24,12 +24,14 @@ description:
options:
plugin:
description: The name of this plugin. Should always be set to V(community.dns.hetzner_dns_records) for this plugin to recognize it as its own.
- # TODO: add `required: true` in 3.0.0
- # required: true
+ required: true
choices:
- community.dns.hetzner_dns_records
type: str
+ filters:
+ version_added: 3.0.0
+
extends_documentation_fragment:
- community.dns.hetzner
- community.dns.hetzner.plugin
@@ -37,6 +39,7 @@ extends_documentation_fragment:
- community.dns.hetzner.zone_id_type
- community.dns.inventory_records
- community.dns.options.record_transformation
+ - community.library_inventory_filtering_v1.inventory_filter
notes:
- The provider-specific O(hetzner_token) option can be templated.
@@ -58,6 +61,10 @@ zone_name: domain.de
simple_filters:
type:
- TXT
+filters:
+ - include: >-
+ not ansible_host.startswith('v=')
+ - exclude: true
txt_transformation: unquoted
# You can also configure the token by putting secret value into this file,
@@ -67,6 +74,7 @@ hetzner_token: >-
{{ (lookup('community.sops.sops', 'keys/hetzner.sops.yml') | from_yaml).hetzner_dns_token }}
'''
+
from ansible_collections.community.dns.plugins.module_utils.http import (
OpenURLHelper,
)
diff --git a/ansible_collections/community/dns/plugins/inventory/hosttech_dns_records.py b/ansible_collections/community/dns/plugins/inventory/hosttech_dns_records.py
index d14cf73ed..e5573de5d 100644
--- a/ansible_collections/community/dns/plugins/inventory/hosttech_dns_records.py
+++ b/ansible_collections/community/dns/plugins/inventory/hosttech_dns_records.py
@@ -24,8 +24,7 @@ description:
options:
plugin:
description: The name of this plugin. Should always be set to V(community.dns.hosttech_dns_records) for this plugin to recognize it as its own.
- # TODO: add `required: true` in 3.0.0
- # required: true
+ required: true
choices:
- community.dns.hosttech_dns_records
type: str
@@ -38,6 +37,9 @@ options:
# compatibility with previous type=int...
# type: string
+ filters:
+ version_added: 3.0.0
+
extends_documentation_fragment:
- community.dns.hosttech
- community.dns.hosttech.plugin
@@ -45,6 +47,7 @@ extends_documentation_fragment:
- community.dns.hosttech.zone_id_type
- community.dns.inventory_records
- community.dns.options.record_transformation
+ - community.library_inventory_filtering_v1.inventory_filter
notes:
- The provider-specific O(hosttech_username), O(hosttech_password), and O(hosttech_token) options can be templated.
@@ -66,6 +69,10 @@ zone_name: domain.ch
simple_filters:
type:
- AAAA
+filters:
+ - include: >-
+ '*.' not in inventory_hostname
+ - exclude: true
# You can also configure the token by putting secret value into this file,
# but this is discouraged. Use a lookup like below, or leave it away and
diff --git a/ansible_collections/community/dns/plugins/lookup/lookup.py b/ansible_collections/community/dns/plugins/lookup/lookup.py
index 9f18164b1..0e968d81a 100644
--- a/ansible_collections/community/dns/plugins/lookup/lookup.py
+++ b/ansible_collections/community/dns/plugins/lookup/lookup.py
@@ -89,6 +89,17 @@ options:
- fail
- message
default: empty
+ search:
+ description:
+ - If V(false), the input is assumed to be an absolute domain name.
+ - If V(true), the input is assumed to be a relative domain name if it does not end with C(.),
+ the search list configured in the system's resolver configuration will be used for relative
+ names, and the resolver's domain may be added to relative names.
+ - Note that this behavior changed in community.dns 3.0.0. In community.dns 2.x.y, O(search=false)
+ was the only available choice.
+ type: bool
+ default: true
+ version_added: 3.0.0
notes:
- Note that when using this lookup plugin with V(lookup(\)), and the result is a one-element list,
Ansible simply returns the one element not as a list. Since this behavior is surprising and
@@ -151,7 +162,7 @@ except ImportError:
class LookupModule(LookupBase):
@staticmethod
- def _resolve(resolver, name, rdtype, server_addresses, nxdomain_handling):
+ def _resolve(resolver, name, rdtype, server_addresses, nxdomain_handling, target_can_be_relative=True, search=True):
def callback():
try:
rrset = resolver.resolve(
@@ -159,6 +170,8 @@ class LookupModule(LookupBase):
rdtype=rdtype,
server_addresses=server_addresses,
nxdomain_is_empty=nxdomain_handling == 'empty',
+ target_can_be_relative=target_can_be_relative,
+ search=search,
)
if not rrset:
return []
@@ -189,6 +202,8 @@ class LookupModule(LookupBase):
nxdomain_handling = self.get_option('nxdomain_handling')
+ search = self.get_option('search')
+
server_addresses = None
if self.get_option('server'):
server_addresses = []
@@ -206,5 +221,5 @@ class LookupModule(LookupBase):
result = []
for name in terms:
- result.extend(self._resolve(resolver, name, rdtype, server_addresses, nxdomain_handling))
+ result.extend(self._resolve(resolver, name, rdtype, server_addresses, nxdomain_handling, target_can_be_relative=search, search=search))
return result
diff --git a/ansible_collections/community/dns/plugins/lookup/lookup_as_dict.py b/ansible_collections/community/dns/plugins/lookup/lookup_as_dict.py
index 8783d86c1..3650b2094 100644
--- a/ansible_collections/community/dns/plugins/lookup/lookup_as_dict.py
+++ b/ansible_collections/community/dns/plugins/lookup/lookup_as_dict.py
@@ -87,6 +87,17 @@ options:
- empty
- fail
default: empty
+ search:
+ description:
+ - If V(false), the input is assumed to be an absolute domain name.
+ - If V(true), the input is assumed to be a relative domain name if it does not end with C(.),
+ the search list configured in the system's resolver configuration will be used for relative
+ names, and the resolver's domain may be added to relative names.
+ - Note that this behavior changed in community.dns 3.0.0. In community.dns 2.x.y, O(search=false)
+ was the only available choice.
+ type: bool
+ default: true
+ version_added: 3.0.0
notes:
- Note that when using this lookup plugin with V(lookup(\)), and the result is a one-element list,
Ansible simply returns the one element not as a list. Since this behavior is surprising and
@@ -440,7 +451,7 @@ except ImportError:
class LookupModule(LookupBase):
@staticmethod
- def _resolve(resolver, name, rdtype, server_addresses, nxdomain_handling):
+ def _resolve(resolver, name, rdtype, server_addresses, nxdomain_handling, target_can_be_relative=True, search=True):
def callback():
try:
rrset = resolver.resolve(
@@ -448,6 +459,8 @@ class LookupModule(LookupBase):
rdtype=rdtype,
server_addresses=server_addresses,
nxdomain_is_empty=nxdomain_handling == 'empty',
+ target_can_be_relative=target_can_be_relative,
+ search=search,
)
if not rrset:
return []
@@ -476,6 +489,8 @@ class LookupModule(LookupBase):
nxdomain_handling = self.get_option('nxdomain_handling')
+ search = self.get_option('search')
+
server_addresses = None
if self.get_option('server'):
server_addresses = []
@@ -493,5 +508,5 @@ class LookupModule(LookupBase):
result = []
for name in terms:
- result.extend(self._resolve(resolver, name, rdtype, server_addresses, nxdomain_handling))
+ result.extend(self._resolve(resolver, name, rdtype, server_addresses, nxdomain_handling, target_can_be_relative=search, search=search))
return result
diff --git a/ansible_collections/community/dns/plugins/module_utils/conversion/converter.py b/ansible_collections/community/dns/plugins/module_utils/conversion/converter.py
index b8a9f4a8d..c6667d50e 100644
--- a/ansible_collections/community/dns/plugins/module_utils/conversion/converter.py
+++ b/ansible_collections/community/dns/plugins/module_utils/conversion/converter.py
@@ -44,23 +44,9 @@ class RecordConverter(object):
self._txt_transformation = self._option_provider.get_option('txt_transformation')
# Valid values: 'decimal', 'octal'
self._txt_character_encoding = self._option_provider.get_option('txt_character_encoding')
- self._txt_character_encoding_deprecation = False
- if self._txt_character_encoding is None:
- # TODO: remove implicit default in community.dns 3.0.0
- self._txt_character_encoding = 'octal'
- if self._txt_transformation == 'quoted':
- self._txt_character_encoding_deprecation = True
def emit_deprecations(self, deprecator):
- if self._txt_character_encoding_deprecation:
- deprecator(
- 'The default of the txt_character_encoding option will change from "octal" to "decimal" in community.dns 3.0.0.'
- ' This potentially affects you since you use txt_transformation=quoted. You can explicitly set txt_character_encoding'
- ' to "octal" to keep the current behavior, or "decimal" to already now switch to the new behavior. We recommend'
- ' switching to the new behavior, and using check/diff mode to figure out potential changes',
- version='3.0.0',
- collection_name='community.dns',
- )
+ pass
def _handle_txt_api(self, to_api, record):
"""
diff --git a/ansible_collections/community/dns/plugins/module_utils/options.py b/ansible_collections/community/dns/plugins/module_utils/options.py
index 3906b4b6c..3b88ebae8 100644
--- a/ansible_collections/community/dns/plugins/module_utils/options.py
+++ b/ansible_collections/community/dns/plugins/module_utils/options.py
@@ -32,6 +32,6 @@ def create_record_transformation_argspec():
return ArgumentSpec(
argument_spec=dict(
txt_transformation=dict(type='str', default='unquoted', choices=['api', 'quoted', 'unquoted']),
- txt_character_encoding=dict(type='str', choices=['decimal', 'octal']),
+ txt_character_encoding=dict(type='str', default='decimal', choices=['decimal', 'octal']),
),
)
diff --git a/ansible_collections/community/dns/plugins/module_utils/provider.py b/ansible_collections/community/dns/plugins/module_utils/provider.py
index 56282d9c9..f5bf08a81 100644
--- a/ansible_collections/community/dns/plugins/module_utils/provider.py
+++ b/ansible_collections/community/dns/plugins/module_utils/provider.py
@@ -104,6 +104,6 @@ class ProviderInformation(object):
This return value is only used if txt_record_handling returns 'encoded'.
- WARNING: the default return value will change to 'decimal' for community.dns 3.0.0!
+ Note: the default return value changed from 'octal' to 'decimal' in community.dns 3.0.0.
"""
- return 'octal'
+ return 'decimal'
diff --git a/ansible_collections/community/dns/plugins/module_utils/resolver.py b/ansible_collections/community/dns/plugins/module_utils/resolver.py
index 280b697d4..3814b164b 100644
--- a/ansible_collections/community/dns/plugins/module_utils/resolver.py
+++ b/ansible_collections/community/dns/plugins/module_utils/resolver.py
@@ -73,7 +73,7 @@ class _Resolve(object):
response = self._handle_timeout(resolver.resolve, dnsname, lifetime=self.timeout, **kwargs)
except AttributeError:
# For dnspython < 2.0.0
- resolver.search = False
+ resolver.search = kwargs.pop('search', False)
try:
response = self._handle_timeout(resolver.query, dnsname, lifetime=self.timeout, **kwargs)
except TypeError:
@@ -101,8 +101,11 @@ class SimpleResolver(_Resolve):
servfail_retries=servfail_retries,
)
- def resolve(self, target, nxdomain_is_empty=True, server_addresses=None, **kwargs):
- dnsname = dns.name.from_unicode(to_text(target))
+ def resolve(self, target, nxdomain_is_empty=True, server_addresses=None, target_can_be_relative=False, **kwargs):
+ if target_can_be_relative:
+ dnsname = dns.name.from_unicode(to_text(target), origin=None)
+ else:
+ dnsname = dns.name.from_unicode(to_text(target))
resolver = self.default_resolver
if server_addresses:
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py
index 23c873322..c27c152c3 100644
--- a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record.py
@@ -43,11 +43,6 @@ attributes:
diff_mode:
support: full
-options:
- prefix:
- aliases:
- - name
-
author:
- Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
- Felix Fontein (@felixfontein)
@@ -109,8 +104,6 @@ def main():
provider_information = create_hetzner_provider_information()
argument_spec = create_hetzner_argument_spec()
argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
- argument_spec.argument_spec['prefix']['aliases'] = ['name']
- argument_spec.argument_spec['prefix']['deprecated_aliases'] = [dict(name='name', version='3.0.0', collection_name='community.dns')]
module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
diff --git a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py
index ce3ad313a..61cfca634 100644
--- a/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py
+++ b/ansible_collections/community/dns/plugins/modules/hetzner_dns_record_set.py
@@ -40,11 +40,6 @@ attributes:
diff_mode:
support: full
-options:
- prefix:
- aliases:
- - name
-
author:
- Markus Bergholz (@markuman) <markuman+spambelongstogoogle@gmail.com>
- Felix Fontein (@felixfontein)
@@ -224,8 +219,6 @@ def main():
provider_information = create_hetzner_provider_information()
argument_spec = create_hetzner_argument_spec()
argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
- argument_spec.argument_spec['prefix']['aliases'] = ['name']
- argument_spec.argument_spec['prefix']['deprecated_aliases'] = [dict(name='name', version='3.0.0', collection_name='community.dns')]
module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
run_module(module, lambda: create_hetzner_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
diff --git a/ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py b/ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py
deleted file mode 100644
index 583cfa58e..000000000
--- a/ansible_collections/community/dns/plugins/modules/hosttech_dns_records.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017-2021 Felix Fontein
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: hosttech_dns_record_sets
-
-short_description: Bulk synchronize DNS record sets in Hosttech DNS service
-
-version_added: 2.0.0
-
-description:
- - Bulk synchronize DNS record sets in Hosttech DNS service.
- - This module replaces C(hosttech_dns_records) from community.dns before 2.0.0.
-
-extends_documentation_fragment:
- - community.dns.hosttech
- - community.dns.hosttech.record_notes
- - community.dns.hosttech.record_type_choices_record_sets_module
- - community.dns.hosttech.zone_id_type
- - community.dns.module_record_sets
- - community.dns.options.record_transformation
- - community.dns.attributes
- - community.dns.attributes.actiongroup_hosttech
-
-attributes:
- action_group:
- version_added: 2.4.0
- check_mode:
- support: full
- diff_mode:
- support: full
-
-author:
- - Felix Fontein (@felixfontein)
-
-'''
-
-EXAMPLES = '''
-- name: Make sure some records exist and have the expected values
- community.dns.hosttech_dns_record_sets:
- zone_name: foo.com
- records:
- - prefix: new
- type: A
- ttl: 7200
- value:
- - 1.1.1.1
- - 2.2.2.2
- - prefix: new
- type: AAAA
- ttl: 7200
- value:
- - "::1"
- - record: foo.com
- type: TXT
- value:
- - test
- hosttech_token: access_token
-
-- name: Synchronize DNS zone with a fixed set of records
- # If a record exists that is not mentioned here, it will be deleted
- community.dns.hosttech_dns_record_sets:
- zone_id: 23
- purge: true
- records:
- - prefix: ''
- type: A
- value: 127.0.0.1
- - prefix: ''
- type: AAAA
- value: "::1"
- - prefix: ''
- type: NS
- value:
- - ns-1.hoster.com
- - ns-2.hoster.com
- - ns-3.hoster.com
- hosttech_token: access_token
-'''
-
-RETURN = '''
-zone_id:
- description: The ID of the zone.
- type: int
- returned: success
- sample: 23
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-
-from ansible_collections.community.dns.plugins.module_utils.argspec import (
- ModuleOptionProvider,
-)
-
-from ansible_collections.community.dns.plugins.module_utils.http import (
- ModuleHTTPHelper,
-)
-
-from ansible_collections.community.dns.plugins.module_utils.hosttech.api import (
- create_hosttech_argument_spec,
- create_hosttech_api,
- create_hosttech_provider_information,
-)
-
-from ansible_collections.community.dns.plugins.module_utils.module.record_sets import (
- create_module_argument_spec,
- run_module,
-)
-
-
-def main():
- provider_information = create_hosttech_provider_information()
- argument_spec = create_hosttech_argument_spec()
- argument_spec.merge(create_module_argument_spec(provider_information=provider_information))
- module = AnsibleModule(supports_check_mode=True, **argument_spec.to_kwargs())
- run_module(module, lambda: create_hosttech_api(ModuleOptionProvider(module), ModuleHTTPHelper(module)), provider_information=provider_information)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py b/ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py
index 1d6827f2f..2ecfb1949 100644
--- a/ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py
+++ b/ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py
@@ -17,6 +17,8 @@ from ansible.plugins.inventory import BaseInventoryPlugin
from ansible.utils.display import Display
from ansible.template import Templar
+from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host
+
from ansible_collections.community.dns.plugins.module_utils.provider import (
ensure_type,
)
@@ -67,15 +69,7 @@ class RecordsInventoryModule(BaseInventoryPlugin):
def parse(self, inventory, loader, path, cache=False):
super(RecordsInventoryModule, self).parse(inventory, loader, path, cache)
- orig_config = self._read_config_data(path)
-
- if 'filters' in orig_config:
- display.deprecated(
- 'The `filters` option of the %s inventory plugin has been renamed to `simple_filters`. '
- 'The old name will stop working in community.dns 3.0.0.' % self.NAME,
- collection_name='community.dns',
- version='3.0.0',
- )
+ self._read_config_data(path)
self.templar = Templar(loader=loader)
@@ -119,9 +113,10 @@ class RecordsInventoryModule(BaseInventoryPlugin):
except DNSAPIError as e:
raise AnsibleError('Error: %s' % e)
- filters = self.get_option('simple_filters')
+ simple_filters = self.get_option('simple_filters')
+ filters = parse_filters(self.get_option('filters'))
- filter_types = filters.get('type') or ['A', 'AAAA', 'CNAME']
+ filter_types = simple_filters.get('type') or ['A', 'AAAA', 'CNAME']
if not isinstance(filter_types, Sequence) or isinstance(filter_types, six.string_types):
filter_types = [filter_types]
@@ -130,5 +125,12 @@ class RecordsInventoryModule(BaseInventoryPlugin):
name = zone_with_records.zone.name
if record.prefix:
name = '%s.%s' % (record.prefix, name)
+ facts = {
+ 'ansible_host': make_unsafe(record.target),
+ }
+ if not filter_host(self, name, facts, filters):
+ continue
+
self.inventory.add_host(name)
- self.inventory.set_variable(name, 'ansible_host', make_unsafe(record.target))
+ for key, value in facts.items():
+ self.inventory.set_variable(name, key, value)
diff --git a/ansible_collections/community/dns/plugins/public_suffix_list.dat b/ansible_collections/community/dns/plugins/public_suffix_list.dat
index 125f1e3d7..05df0af89 100644
--- a/ansible_collections/community/dns/plugins/public_suffix_list.dat
+++ b/ansible_collections/community/dns/plugins/public_suffix_list.dat
@@ -6710,7 +6710,7 @@ org.zw
// newGTLDs
-// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-03-28T15:13:37Z
+// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-05-04T15:12:50Z
// This list is auto-generated, don't edit it manually.
// aaa : American Automobile Association, Inc.
// https://www.iana.org/domains/root/db/aaa.html
@@ -6896,7 +6896,7 @@ anquan
// https://www.iana.org/domains/root/db/anz.html
anz
-// aol : Oath Inc.
+// aol : Yahoo Inc.
// https://www.iana.org/domains/root/db/aol.html
aol
@@ -11120,7 +11120,7 @@ xyz
// https://www.iana.org/domains/root/db/yachts.html
yachts
-// yahoo : Oath Inc.
+// yahoo : Yahoo Inc.
// https://www.iana.org/domains/root/db/yahoo.html
yahoo
@@ -11200,6 +11200,10 @@ ltd.ua
// 611coin : https://611project.org/
611.to
+// AAA workspace : https://aaa.vodka
+// Submitted by Kirill Rezraf <admin@aaa.vodka>
+aaa.vodka
+
// A2 Hosting
// Submitted by Tyler Hall <sysadmin@a2hosting.com>
a2hosted.com
@@ -11346,23 +11350,28 @@ cloudfront.net
// Amazon Cognito
// Submitted by AWS Security <psl-maintainers@amazon.com>
-// Reference: 7bee1013-f456-47df-bfe8-03c78d946d61
+// Reference: 09588633-91fe-49d8-b4e7-ec36496d11f3
auth.af-south-1.amazoncognito.com
auth.ap-northeast-1.amazoncognito.com
auth.ap-northeast-2.amazoncognito.com
auth.ap-northeast-3.amazoncognito.com
auth.ap-south-1.amazoncognito.com
+auth.ap-south-2.amazoncognito.com
auth.ap-southeast-1.amazoncognito.com
auth.ap-southeast-2.amazoncognito.com
auth.ap-southeast-3.amazoncognito.com
+auth.ap-southeast-4.amazoncognito.com
auth.ca-central-1.amazoncognito.com
auth.eu-central-1.amazoncognito.com
+auth.eu-central-2.amazoncognito.com
auth.eu-north-1.amazoncognito.com
auth.eu-south-1.amazoncognito.com
+auth.eu-south-2.amazoncognito.com
auth.eu-west-1.amazoncognito.com
auth.eu-west-2.amazoncognito.com
auth.eu-west-3.amazoncognito.com
auth.il-central-1.amazoncognito.com
+auth.me-central-1.amazoncognito.com
auth.me-south-1.amazoncognito.com
auth.sa-east-1.amazoncognito.com
auth.us-east-1.amazoncognito.com
@@ -11385,7 +11394,7 @@ us-east-1.amazonaws.com
// Amazon EMR
// Submitted by AWS Security <psl-maintainers@amazon.com>
-// Reference: 597f3f8e-9283-4e48-8e32-7ee25a1ff6ab
+// Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d
emrappui-prod.cn-north-1.amazonaws.com.cn
emrnotebooks-prod.cn-north-1.amazonaws.com.cn
emrstudio-prod.cn-north-1.amazonaws.com.cn
@@ -11410,6 +11419,9 @@ emrstudio-prod.ap-northeast-3.amazonaws.com
emrappui-prod.ap-south-1.amazonaws.com
emrnotebooks-prod.ap-south-1.amazonaws.com
emrstudio-prod.ap-south-1.amazonaws.com
+emrappui-prod.ap-south-2.amazonaws.com
+emrnotebooks-prod.ap-south-2.amazonaws.com
+emrstudio-prod.ap-south-2.amazonaws.com
emrappui-prod.ap-southeast-1.amazonaws.com
emrnotebooks-prod.ap-southeast-1.amazonaws.com
emrstudio-prod.ap-southeast-1.amazonaws.com
@@ -11419,18 +11431,30 @@ emrstudio-prod.ap-southeast-2.amazonaws.com
emrappui-prod.ap-southeast-3.amazonaws.com
emrnotebooks-prod.ap-southeast-3.amazonaws.com
emrstudio-prod.ap-southeast-3.amazonaws.com
+emrappui-prod.ap-southeast-4.amazonaws.com
+emrnotebooks-prod.ap-southeast-4.amazonaws.com
+emrstudio-prod.ap-southeast-4.amazonaws.com
emrappui-prod.ca-central-1.amazonaws.com
emrnotebooks-prod.ca-central-1.amazonaws.com
emrstudio-prod.ca-central-1.amazonaws.com
+emrappui-prod.ca-west-1.amazonaws.com
+emrnotebooks-prod.ca-west-1.amazonaws.com
+emrstudio-prod.ca-west-1.amazonaws.com
emrappui-prod.eu-central-1.amazonaws.com
emrnotebooks-prod.eu-central-1.amazonaws.com
emrstudio-prod.eu-central-1.amazonaws.com
+emrappui-prod.eu-central-2.amazonaws.com
+emrnotebooks-prod.eu-central-2.amazonaws.com
+emrstudio-prod.eu-central-2.amazonaws.com
emrappui-prod.eu-north-1.amazonaws.com
emrnotebooks-prod.eu-north-1.amazonaws.com
emrstudio-prod.eu-north-1.amazonaws.com
emrappui-prod.eu-south-1.amazonaws.com
emrnotebooks-prod.eu-south-1.amazonaws.com
emrstudio-prod.eu-south-1.amazonaws.com
+emrappui-prod.eu-south-2.amazonaws.com
+emrnotebooks-prod.eu-south-2.amazonaws.com
+emrstudio-prod.eu-south-2.amazonaws.com
emrappui-prod.eu-west-1.amazonaws.com
emrnotebooks-prod.eu-west-1.amazonaws.com
emrstudio-prod.eu-west-1.amazonaws.com
@@ -11440,6 +11464,9 @@ emrstudio-prod.eu-west-2.amazonaws.com
emrappui-prod.eu-west-3.amazonaws.com
emrnotebooks-prod.eu-west-3.amazonaws.com
emrstudio-prod.eu-west-3.amazonaws.com
+emrappui-prod.il-central-1.amazonaws.com
+emrnotebooks-prod.il-central-1.amazonaws.com
+emrstudio-prod.il-central-1.amazonaws.com
emrappui-prod.me-central-1.amazonaws.com
emrnotebooks-prod.me-central-1.amazonaws.com
emrstudio-prod.me-central-1.amazonaws.com
@@ -11470,9 +11497,11 @@ emrstudio-prod.us-west-2.amazonaws.com
// Amazon Managed Workflows for Apache Airflow
// Submitted by AWS Security <psl-maintainers@amazon.com>
-// Reference: 4ab55e6f-90c0-4a8d-b6a0-52ca5dbb1c2e
+// Reference: 87f24ece-a77e-40e8-bb4a-f6b74fe9f975
*.cn-north-1.airflow.amazonaws.com.cn
*.cn-northwest-1.airflow.amazonaws.com.cn
+*.af-south-1.airflow.amazonaws.com
+*.ap-east-1.airflow.amazonaws.com
*.ap-northeast-1.airflow.amazonaws.com
*.ap-northeast-2.airflow.amazonaws.com
*.ap-south-1.airflow.amazonaws.com
@@ -11481,12 +11510,15 @@ emrstudio-prod.us-west-2.amazonaws.com
*.ca-central-1.airflow.amazonaws.com
*.eu-central-1.airflow.amazonaws.com
*.eu-north-1.airflow.amazonaws.com
+*.eu-south-1.airflow.amazonaws.com
*.eu-west-1.airflow.amazonaws.com
*.eu-west-2.airflow.amazonaws.com
*.eu-west-3.airflow.amazonaws.com
+*.me-south-1.airflow.amazonaws.com
*.sa-east-1.airflow.amazonaws.com
*.us-east-1.airflow.amazonaws.com
*.us-east-2.airflow.amazonaws.com
+*.us-west-1.airflow.amazonaws.com
*.us-west-2.airflow.amazonaws.com
// Amazon S3
@@ -11780,9 +11812,25 @@ s3-fips.us-west-2.amazonaws.com
s3-object-lambda.us-west-2.amazonaws.com
s3-website.us-west-2.amazonaws.com
+// Amazon SageMaker Ground Truth
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c
+labeling.ap-northeast-1.sagemaker.aws
+labeling.ap-northeast-2.sagemaker.aws
+labeling.ap-south-1.sagemaker.aws
+labeling.ap-southeast-1.sagemaker.aws
+labeling.ap-southeast-2.sagemaker.aws
+labeling.ca-central-1.sagemaker.aws
+labeling.eu-central-1.sagemaker.aws
+labeling.eu-west-1.sagemaker.aws
+labeling.eu-west-2.sagemaker.aws
+labeling.us-east-1.sagemaker.aws
+labeling.us-east-2.sagemaker.aws
+labeling.us-west-2.sagemaker.aws
+
// Amazon SageMaker Notebook Instances
// Submitted by AWS Security <psl-maintainers@amazon.com>
-// Reference: ce8ae0b1-0070-496d-be88-37c31837af9d
+// Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc
notebook.af-south-1.sagemaker.aws
notebook.ap-east-1.sagemaker.aws
notebook.ap-northeast-1.sagemaker.aws
@@ -11819,6 +11867,7 @@ notebook-fips.us-gov-east-1.sagemaker.aws
notebook.us-gov-west-1.sagemaker.aws
notebook-fips.us-gov-west-1.sagemaker.aws
notebook.us-west-1.sagemaker.aws
+notebook-fips.us-west-1.sagemaker.aws
notebook.us-west-2.sagemaker.aws
notebook-fips.us-west-2.sagemaker.aws
notebook.cn-north-1.sagemaker.com.cn
@@ -11826,7 +11875,7 @@ notebook.cn-northwest-1.sagemaker.com.cn
// Amazon SageMaker Studio
// Submitted by AWS Security <psl-maintainers@amazon.com>
-// Reference: 057ee397-6bf8-4f20-b807-d7bc145ac980
+// Reference: 69c723d9-6e1a-4bff-a203-48eecd203183
studio.af-south-1.sagemaker.aws
studio.ap-east-1.sagemaker.aws
studio.ap-northeast-1.sagemaker.aws
@@ -11840,6 +11889,7 @@ studio.ca-central-1.sagemaker.aws
studio.eu-central-1.sagemaker.aws
studio.eu-north-1.sagemaker.aws
studio.eu-south-1.sagemaker.aws
+studio.eu-south-2.sagemaker.aws
studio.eu-west-1.sagemaker.aws
studio.eu-west-2.sagemaker.aws
studio.eu-west-3.sagemaker.aws
@@ -11951,6 +12001,11 @@ webview-assets.aws-cloud9.us-west-2.amazonaws.com
vfs.cloud9.us-west-2.amazonaws.com
webview-assets.cloud9.us-west-2.amazonaws.com
+// AWS Directory Service
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068
+awsapps.com
+
// AWS Elastic Beanstalk
// Submitted by AWS Security <psl-maintainers@amazon.com>
// Reference: bb5a965c-dec3-4967-aa22-e306ad064797
@@ -12144,6 +12199,10 @@ pages.gay
// Submitted by Adrian <adrian@betainabox.com>
betainabox.com
+// University of Bielsko-Biala regional domain: http://dns.bielsko.pl/
+// Submitted by Marcin <dns@ath.bielsko.pl>
+bielsko.pl
+
// BinaryLane : http://www.binarylane.com
// Submitted by Nathan O'Sullivan <nathan@mammoth.com.au>
bnr.la
@@ -12190,7 +12249,8 @@ square7.net
*.s.brave.io
// Brendly : https://brendly.rs
-// Submitted by Dusan Radovanovic <dusan.radovanovic@brendly.rs>
+// Submitted by Dusan Radovanovic <administracija@brendly.rs>
+shop.brendly.hr
shop.brendly.rs
// BrowserSafetyMark
@@ -12307,7 +12367,10 @@ discourse.team
// Clever Cloud : https://www.clever-cloud.com/
// Submitted by Quentin Adam <noc@clever-cloud.com>
+cleverapps.cc
+*.services.clever-cloud.com
cleverapps.io
+cleverapps.tech
// Clerk : https://www.clerk.dev
// Submitted by Colin Sidoti <systems@clerk.dev>
@@ -13093,6 +13156,11 @@ us-2.evennode.com
us-3.evennode.com
us-4.evennode.com
+// Expo : https://expo.dev/
+// Submitted by James Ide <psl@expo.dev>
+expo.app
+staging.expo.app
+
// eDirect Corp. : https://hosting.url.com.tw/
// Submitted by C.S. chang <cschang@corp.url.com.tw>
twmail.cc
@@ -13391,10 +13459,6 @@ localcert.net
localhostcert.net
corpnet.work
-// Ghost Foundation : https://ghost.org
-// Submitted by Matt Hanley <security@ghost.org>
-ghost.io
-
// GignoSystemJapan: http://gsj.bz
// Submitted by GignoSystemJapan <kakutou-ec@gsj.bz>
gsj.bz
@@ -13559,7 +13623,8 @@ ro.im
goip.de
// Google, Inc.
-// Submitted by Eduardo Vela <evn@google.com>
+// Submitted by Shannon McCabe <public-suffix-editors@google.com>
+*.hosted.app
*.run.app
web.app
*.0emm.com
@@ -14063,10 +14128,6 @@ co.network
co.place
co.technology
-// Lightmaker Property Manager, Inc. : https://app.lmpm.com/
-// Submitted by Greg Holland <greg.holland@lmpm.com>
-app.lmpm.com
-
// linkyard ldt: https://www.linkyard.ch/
// Submitted by Mario Siegenthaler <mario.siegenthaler@linkyard.ch>
linkyard.cloud
@@ -14312,6 +14373,10 @@ netlify.app
// Submitted by Trung Tran <Trung.Tran@neustar.biz>
4u.com
+// NGO.US Registry : https://nic.ngo.us
+// Submitted by Alstra Solutions Ltd. Networking Team <admin@alstra.org>
+ngo.us
+
// ngrok : https://ngrok.com/
// Submitted by Alan Shreve <alan@ngrok.com>
ngrok.app
@@ -14362,6 +14427,10 @@ noop.app
// Submitted by Laurent Pellegrino <security@noticeable.io>
noticeable.news
+// Notion Labs, Inc : https://www.notion.so/
+// Submitted by Jess Yao <trust-core-team@makenotion.com>
+notion.site
+
// Now-DNS : https://now-dns.com
// Submitted by Steve Russell <steve@now-dns.com>
dnsking.ch
@@ -14495,8 +14564,13 @@ pcloud.host
// Submitted by Matthew Brown <mattbrown@nyc.mn>
nyc.mn
+// O3O.Foundation : https://o3o.foundation/
+// Submitted by the prvcy.page Registry Team <psl@registry.prvcy.page>
+prvcy.page
+
// Observable, Inc. : https://observablehq.com
// Submitted by Mike Bostock <dns@observablehq.com>
+observablehq.cloud
static.observableusercontent.com
// Octopodal Solutions, LLC. : https://ulterius.io/
@@ -14624,6 +14698,7 @@ pagexl.com
// pcarrier.ca Software Inc: https://pcarrier.ca/
// Submitted by Pierre Carrier <pc@rrier.ca>
*.xmit.co
+xmit.dev
srv.us
gh.srv.us
gl.srv.us
@@ -14714,10 +14789,6 @@ xen.prgmr.com
// Submitted by registry <lendl@nic.at>
priv.at
-// privacytools.io : https://www.privacytools.io/
-// Submitted by Jonah Aragon <jonah@privacytools.io>
-prvcy.page
-
// Protocol Labs : https://protocol.ai/
// Submitted by Michael Burns <noc@protocol.ai>
*.dweb.link
@@ -15062,6 +15133,10 @@ biz.ua
co.ua
pp.ua
+// Sheezy.Art : https://sheezy.art
+// Submitted by Nyoom <admin@sheezy.art>
+sheezy.games
+
// Shift Crypto AG : https://shiftcrypto.ch
// Submitted by alex <alex@shiftcrypto.ch>
shiftcrypto.dev
@@ -15484,6 +15559,11 @@ dnsupdate.info
// Submitted by Ed Moore <Ed.Moore@lib.de.us>
lib.de.us
+// Val Town, Inc : https://val.town/
+// Submitted by Tom MacWright <security@val.town>
+express.val.run
+web.val.run
+
// VeryPositive SIA : http://very.lv
// Submitted by Danko Aleksejevs <danko@very.lv>
2038.io
@@ -15548,6 +15628,10 @@ wedeploy.sh
// Submitted by Jung Jin <jungseok.jin@wdc.com>
remotewd.com
+// Whatbox Inc. : https://whatbox.ca/
+// Submitted by Anthony Ryan <servers@whatbox.ca>
+box.ca
+
// WIARD Enterprises : https://wiardweb.com
// Submitted by Kidd Hustle <kiddhustle@wiardweb.com>
pages.wiardweb.com
@@ -15650,6 +15734,10 @@ za.org
// Submitted by Julian Alker <security@zap-hosting.com>
zap.cloud
+// Zeabur : https://zeabur.com/
+// Submitted by Zeabur Team <contact@zeabur.com>
+zeabur.app
+
// Zine EOOD : https://zine.bg/
// Submitted by Martin Angelov <martin@zine.bg>
bss.design
diff --git a/ansible_collections/community/dns/tests/integration/targets/filter_txt/tasks/main.yml b/ansible_collections/community/dns/tests/integration/targets/filter_txt/tasks/main.yml
index c0afffcea..63c7d8424 100644
--- a/ansible_collections/community/dns/tests/integration/targets/filter_txt/tasks/main.yml
+++ b/ansible_collections/community/dns/tests/integration/targets/filter_txt/tasks/main.yml
@@ -47,3 +47,47 @@
'"foo" "bar"' | community.dns.unquote_txt == "foobar"
- >
'foo "bar baz" bam' | community.dns.unquote_txt == "foobar bazbam"
+
+- name: quote_txt failure - input not string
+ set_fact:
+ output: "{{ 1 | community.dns.quote_txt }}"
+ register: quote_failure_1
+ ignore_errors: true
+
+- name: quote_txt failure - always_quote not a boolean
+ set_fact:
+ output: "{{ '' | community.dns.quote_txt(always_quote=1) }}"
+ register: quote_failure_2
+ ignore_errors: true
+
+- name: quote_txt failure - character_encoding has invalid value
+ set_fact:
+ output: "{{ '' | community.dns.quote_txt(character_encoding='foo') }}"
+ register: quote_failure_3
+ ignore_errors: true
+
+- name: unquote_txt failure - input not string
+ set_fact:
+ output: "{{ 1 | community.dns.unquote_txt }}"
+ register: unquote_failure_1
+ ignore_errors: true
+
+- name: unquote_txt failure - character_encoding has invalid value
+ set_fact:
+ output: "{{ '' | community.dns.unquote_txt(character_encoding='foo') }}"
+ register: unquote_failure_2
+ ignore_errors: true
+
+- name: Validate errors
+ assert:
+ that:
+ - quote_failure_1 is failed
+ - quote_failure_1.msg == 'Input for community.dns.quote_txt must be a string'
+ - quote_failure_2 is failed
+ - quote_failure_2.msg == 'always_quote must be a boolean, not 1'
+ - quote_failure_3 is failed
+ - quote_failure_3.msg == "character_encoding must be \"decimal\" or \"octal\", not 'foo'"
+ - unquote_failure_1 is failed
+ - unquote_failure_1.msg == 'Input for community.dns.unquote_txt must be a string'
+ - unquote_failure_2 is failed
+ - unquote_failure_2.msg == "character_encoding must be \"decimal\" or \"octal\", not 'foo'"
diff --git a/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hetzner_dns_records.py b/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hetzner_dns_records.py
index 44f694708..2dadf2643 100644
--- a/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hetzner_dns_records.py
+++ b/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hetzner_dns_records.py
@@ -236,7 +236,7 @@ def test_inventory_file_simple(mocker):
plugin: community.dns.hetzner_dns_records
hetzner_token: foo
zone_name: example.com
- filters:
+ simple_filters:
type: A
""")}
@@ -289,7 +289,7 @@ def test_inventory_file_collision(mocker):
plugin: community.dns.hetzner_dns_records
hetzner_token: '{{ "foo" }}'
zone_name: '{{ "example." ~ "com" }}'
- filters:
+ simple_filters:
type:
- A
- AAAA
diff --git a/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hosttech_dns_records.py b/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hosttech_dns_records.py
index 11995198c..dd56623df 100644
--- a/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hosttech_dns_records.py
+++ b/ansible_collections/community/dns/tests/unit/plugins/inventory/test_hosttech_dns_records.py
@@ -220,7 +220,7 @@ def test_inventory_file_simple(mocker):
plugin: community.dns.hosttech_dns_records
hosttech_token: foo
zone_name: example.com
- filters:
+ simple_filters:
type: A
""")}
@@ -270,7 +270,7 @@ def test_inventory_file_collision(mocker):
plugin: community.dns.hosttech_dns_records
hosttech_token: "{{ 'foo' }}"
zone_name: "{{ 'example' ~ '.com' }}"
- filters:
+ simple_filters:
type:
- A
- AAAA
diff --git a/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup.py b/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup.py
index 0982d8704..010fe8ac0 100644
--- a/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup.py
+++ b/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup.py
@@ -35,7 +35,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -57,29 +58,60 @@ class TestLookup(TestCase):
assert result[0] == '127.0.0.1'
assert result[1] == '127.0.0.2'
- def test_retry_success(self):
+ def test_no_search(self):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
'target': dns.name.from_unicode(u'www.example.com'),
+ 'search': False,
+ 'rdtype': dns.rdatatype.A,
+ 'lifetime': 10,
+ 'result': create_mock_answer(dns.rrset.from_rdata(
+ 'www.example.com',
+ 300,
+ dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '127.0.0.1'),
+ dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '127.0.0.2'),
+ )),
+ },
+ ],
+ })
+ with patch('dns.resolver.get_default_resolver', resolver):
+ with patch('dns.resolver.Resolver', resolver):
+ with patch('dns.query.udp', mock_query_udp([])):
+ result = self.lookup.run(['www.example.com'], search=False)
+
+ print(result)
+ assert len(result) == 2
+ assert result[0] == '127.0.0.1'
+ assert result[1] == '127.0.0.2'
+
+ def test_retry_success(self):
+ resolver = mock_resolver(['1.1.1.1'], {
+ ('1.1.1.1', ): [
+ {
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -105,25 +137,29 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
@@ -143,7 +179,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -162,7 +199,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -181,7 +219,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -200,7 +239,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -220,7 +260,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -240,7 +281,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
@@ -260,19 +302,22 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -291,19 +336,22 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
@@ -323,7 +371,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'example.com'),
+ 'target': dns.name.from_unicode(u'example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.TXT,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -351,7 +400,8 @@ class TestLookup(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('2.2.2.2', '3.3.3.3'): [
{
- 'target': dns.name.from_unicode(u'example.org'),
+ 'target': dns.name.from_unicode(u'example.org', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.AAAA,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -397,7 +447,8 @@ class TestLookup(TestCase):
],
('1.2.3.4', '1::2', '2.2.2.2', '3.3.3.3'): [
{
- 'target': dns.name.from_unicode(u'example.org'),
+ 'target': dns.name.from_unicode(u'example.org', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.AAAA,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -477,7 +528,8 @@ class TestLookup(TestCase):
],
('3.3.3.3', ): [
{
- 'target': dns.name.from_unicode(u'example.org'),
+ 'target': dns.name.from_unicode(u'example.org', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.AAAA,
'lifetime': 5,
'raise': dns.resolver.NoAnswer(response=fake_query),
diff --git a/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup_as_dict.py b/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup_as_dict.py
index f29d73143..57c3655a9 100644
--- a/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup_as_dict.py
+++ b/ansible_collections/community/dns/tests/unit/plugins/lookup/test_lookup_as_dict.py
@@ -35,7 +35,8 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -61,29 +62,64 @@ class TestLookupAsDict(TestCase):
'address': '127.0.0.2',
}
- def test_retry_success(self):
+ def test_no_search(self):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
'target': dns.name.from_unicode(u'www.example.com'),
+ 'search': False,
+ 'rdtype': dns.rdatatype.A,
+ 'lifetime': 10,
+ 'result': create_mock_answer(dns.rrset.from_rdata(
+ 'www.example.com',
+ 300,
+ dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '127.0.0.1'),
+ dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '127.0.0.2'),
+ )),
+ },
+ ],
+ })
+ with patch('dns.resolver.get_default_resolver', resolver):
+ with patch('dns.resolver.Resolver', resolver):
+ with patch('dns.query.udp', mock_query_udp([])):
+ result = self.lookup.run(['www.example.com'], search=False)
+
+ print(result)
+ assert len(result) == 2
+ assert result[0] == {
+ 'address': '127.0.0.1',
+ }
+ assert result[1] == {
+ 'address': '127.0.0.2',
+ }
+
+ def test_retry_success(self):
+ resolver = mock_resolver(['1.1.1.1'], {
+ ('1.1.1.1', ): [
+ {
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -113,25 +149,29 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'raise': dns.exception.Timeout(timeout=10),
@@ -151,7 +191,8 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -170,7 +211,8 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -190,7 +232,8 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
@@ -210,19 +253,22 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.NXDOMAIN),
@@ -241,19 +287,22 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
},
{
- 'target': dns.name.from_unicode(u'www.example.com'),
+ 'target': dns.name.from_unicode(u'www.example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.A,
'lifetime': 10,
'result': create_mock_answer(rcode=dns.rcode.SERVFAIL),
@@ -273,7 +322,8 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('1.1.1.1', ): [
{
- 'target': dns.name.from_unicode(u'example.com'),
+ 'target': dns.name.from_unicode(u'example.com', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.TXT,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -310,7 +360,8 @@ class TestLookupAsDict(TestCase):
resolver = mock_resolver(['1.1.1.1'], {
('2.2.2.2', '3.3.3.3'): [
{
- 'target': dns.name.from_unicode(u'example.org'),
+ 'target': dns.name.from_unicode(u'example.org', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.AAAA,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -358,7 +409,8 @@ class TestLookupAsDict(TestCase):
],
('1.2.3.4', '1::2', '2.2.2.2', '3.3.3.3'): [
{
- 'target': dns.name.from_unicode(u'example.org'),
+ 'target': dns.name.from_unicode(u'example.org', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.AAAA,
'lifetime': 10,
'result': create_mock_answer(dns.rrset.from_rdata(
@@ -440,7 +492,8 @@ class TestLookupAsDict(TestCase):
],
('3.3.3.3', ): [
{
- 'target': dns.name.from_unicode(u'example.org'),
+ 'target': dns.name.from_unicode(u'example.org', origin=None),
+ 'search': True,
'rdtype': dns.rdatatype.AAAA,
'lifetime': 5,
'raise': dns.resolver.NoAnswer(response=fake_query),
diff --git a/ansible_collections/community/dns/tests/unit/plugins/module_utils/resolver_helper.py b/ansible_collections/community/dns/tests/unit/plugins/module_utils/resolver_helper.py
index 7fa213c9f..71a0af989 100644
--- a/ansible_collections/community/dns/tests/unit/plugins/module_utils/resolver_helper.py
+++ b/ansible_collections/community/dns/tests/unit/plugins/module_utils/resolver_helper.py
@@ -22,7 +22,7 @@ def mock_resolver(default_nameservers, nameserver_resolve_sequence):
resolver = MagicMock()
resolver.nameservers = default_nameservers if configure else []
- def mock_resolver_resolve(target, rdtype=None, lifetime=None):
+ def mock_resolver_resolve(target, rdtype=None, lifetime=None, search=None):
resolver_index = tuple(sorted(resolver.nameservers))
assert resolver_index in nameserver_resolve_sequence, 'No resolver sequence for {0}'.format(resolver_index)
resolve_sequence = nameserver_resolve_sequence[resolver_index]
@@ -33,6 +33,7 @@ def mock_resolver(default_nameservers, nameserver_resolve_sequence):
assert target == resolve_data['target'], 'target: {0!r} vs {1!r}'.format(target, resolve_data['target'])
assert rdtype == resolve_data.get('rdtype'), 'rdtype: {0!r} vs {1!r}'.format(rdtype, resolve_data.get('rdtype'))
assert lifetime == resolve_data['lifetime'], 'lifetime: {0!r} vs {1!r}'.format(lifetime, resolve_data['lifetime'])
+ assert search == resolve_data.get('search'), 'search: {0!r} vs {1!r}'.format(search, resolve_data.get('search'))
if 'raise' in resolve_data:
raise resolve_data['raise']
diff --git a/ansible_collections/community/dns/tests/unit/plugins/modules/test_hetzner_dns_record_set_info.py b/ansible_collections/community/dns/tests/unit/plugins/modules/test_hetzner_dns_record_set_info.py
index a42add09d..e6894f97c 100644
--- a/ansible_collections/community/dns/tests/unit/plugins/modules/test_hetzner_dns_record_set_info.py
+++ b/ansible_collections/community/dns/tests/unit/plugins/modules/test_hetzner_dns_record_set_info.py
@@ -627,7 +627,7 @@ class TestHetznerDNSRecordSetInfoJSON(BaseTestModule):
assert result['set']['value'] == [u'"b\\195\\164r \\"with quotes\\" (use \\\\ to escape)"']
assert 'sets' not in result
- def test_get_single_txt_quoted_deprecation(self, mocker):
+ def test_get_single_txt_quoted_octal(self, mocker):
with patch('time.sleep', mock_sleep):
result = self.run_module_success(mocker, hetzner_dns_record_set_info, {
'hetzner_token': 'foo',
@@ -635,6 +635,7 @@ class TestHetznerDNSRecordSetInfoJSON(BaseTestModule):
'prefix': 'foo',
'type': 'TXT',
'txt_transformation': 'quoted',
+ 'txt_character_encoding': 'octal',
'_ansible_remote_tmp': '/tmp/tmp',
'_ansible_keep_remote_files': True,
}, [
@@ -678,19 +679,3 @@ class TestHetznerDNSRecordSetInfoJSON(BaseTestModule):
assert result['set']['type'] == 'TXT'
assert result['set']['value'] == [u'"b\\303\\244r \\"with quotes\\" (use \\\\ to escape)"']
assert 'sets' not in result
- assert 'deprecations' in result
- found = False
- for deprecation in result['deprecations']:
- if 'collection_name' in deprecation and deprecation['collection_name'] != 'community.dns':
- continue
- found = True
- assert deprecation['msg'] == (
- 'The default of the txt_character_encoding option will change from "octal" to "decimal" in community.dns 3.0.0.'
- ' This potentially affects you since you use txt_transformation=quoted.'
- ' You can explicitly set txt_character_encoding to "octal" to keep the current behavior,'
- ' or "decimal" to already now switch to the new behavior.'
- ' We recommend switching to the new behavior, and using check/diff mode to figure out potential changes'
- )
- assert deprecation['version'] == '3.0.0'
- assert deprecation.get('date') is None
- assert found
diff --git a/ansible_collections/community/dns/tests/unit/plugins/plugin_utils/test_unsafe.py b/ansible_collections/community/dns/tests/unit/plugins/plugin_utils/test_unsafe.py
new file mode 100644
index 000000000..cbda5f142
--- /dev/null
+++ b/ansible_collections/community/dns/tests/unit/plugins/plugin_utils/test_unsafe.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+import pytest
+
+from ansible.utils.unsafe_proxy import AnsibleUnsafe
+
+from ansible_collections.community.dns.plugins.plugin_utils.unsafe import (
+ make_unsafe,
+)
+
+
+TEST_MAKE_UNSAFE = [
+ (
+ u'text',
+ [],
+ [
+ (),
+ ],
+ ),
+ (
+ u'{{text}}',
+ [
+ (),
+ ],
+ [],
+ ),
+ (
+ b'text',
+ [],
+ [
+ (),
+ ],
+ ),
+ (
+ b'{{text}}',
+ [
+ (),
+ ],
+ [],
+ ),
+ (
+ {
+ 'skey': 'value',
+ 'ukey': '{{value}}',
+ 1: [
+ 'value',
+ '{{value}}',
+ {
+ 1.0: '{{value}}',
+ 2.0: 'value',
+ },
+ ],
+ },
+ [
+ ('ukey', ),
+ (1, 1),
+ (1, 2, 1.0),
+ ],
+ [
+ ('skey', ),
+ (1, 0),
+ (1, 2, 2.0),
+ ],
+ ),
+ (
+ ['value', '{{value}}'],
+ [
+ (1, ),
+ ],
+ [
+ (0, ),
+ ],
+ ),
+]
+
+
+@pytest.mark.parametrize("value, check_unsafe_paths, check_safe_paths", TEST_MAKE_UNSAFE)
+def test_make_unsafe(value, check_unsafe_paths, check_safe_paths):
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for check_path in check_unsafe_paths:
+ obj = unsafe_value
+ for elt in check_path:
+ obj = obj[elt]
+ assert isinstance(obj, AnsibleUnsafe)
+ for check_path in check_safe_paths:
+ obj = unsafe_value
+ for elt in check_path:
+ obj = obj[elt]
+ assert not isinstance(obj, AnsibleUnsafe)
+
+
+def test_make_unsafe_dict_key():
+ value = {
+ b'test': 1,
+ u'test': 2,
+ }
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert not isinstance(obj, AnsibleUnsafe)
+
+ value = {
+ b'{{test}}': 1,
+ u'{{test}}': 2,
+ }
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert isinstance(obj, AnsibleUnsafe)
+
+
+def test_make_unsafe_set():
+ value = set([b'test', u'test'])
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert not isinstance(obj, AnsibleUnsafe)
+
+ value = set([b'{{test}}', u'{{test}}'])
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert isinstance(obj, AnsibleUnsafe)
diff --git a/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml
index e5d55cf6e..ae4197a4a 100644
--- a/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml
+++ b/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml
@@ -186,7 +186,7 @@ stages:
- name: Debian Bookworm
test: debian-bookworm/3.11
- name: ArchLinux
- test: archlinux/3.11
+ test: archlinux/3.12
groups:
- 4
- 5
diff --git a/ansible_collections/community/docker/.github/workflows/ansible-test.yml b/ansible_collections/community/docker/.github/workflows/ansible-test.yml
index d0f253d35..d4778e091 100644
--- a/ansible_collections/community/docker/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/docker/.github/workflows/ansible-test.yml
@@ -48,6 +48,7 @@ jobs:
with:
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pull-request-change-detection: 'true'
testing-type: sanity
@@ -81,6 +82,7 @@ jobs:
with:
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pull-request-change-detection: 'true'
testing-type: units
@@ -236,6 +238,7 @@ jobs:
with:
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
docker-image: ${{ matrix.docker }}
integration-continue-on-error: 'false'
diff --git a/ansible_collections/community/docker/CHANGELOG.md b/ansible_collections/community/docker/CHANGELOG.md
index f3a4b7af6..13d287f2e 100644
--- a/ansible_collections/community/docker/CHANGELOG.md
+++ b/ansible_collections/community/docker/CHANGELOG.md
@@ -2,241 +2,331 @@
**Topics**
-- <a href="#v3-9-0">v3\.9\.0</a>
+- <a href="#v3-10-3">v3\.10\.3</a>
- <a href="#release-summary">Release Summary</a>
- - <a href="#minor-changes">Minor Changes</a>
- <a href="#bugfixes">Bugfixes</a>
-- <a href="#v3-8-1">v3\.8\.1</a>
+- <a href="#v3-10-2">v3\.10\.2</a>
- <a href="#release-summary-1">Release Summary</a>
- - <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-1">Bugfixes</a>
-- <a href="#v3-8-0">v3\.8\.0</a>
+- <a href="#v3-10-1">v3\.10\.1</a>
- <a href="#release-summary-2">Release Summary</a>
- - <a href="#minor-changes-1">Minor Changes</a>
- <a href="#bugfixes-2">Bugfixes</a>
-- <a href="#v3-7-0">v3\.7\.0</a>
+ - <a href="#known-issues">Known Issues</a>
+- <a href="#v3-10-0">v3\.10\.0</a>
- <a href="#release-summary-3">Release Summary</a>
- - <a href="#minor-changes-2">Minor Changes</a>
+ - <a href="#minor-changes">Minor Changes</a>
+ - <a href="#deprecated-features">Deprecated Features</a>
+- <a href="#v3-9-0">v3\.9\.0</a>
+ - <a href="#release-summary-4">Release Summary</a>
+ - <a href="#minor-changes-1">Minor Changes</a>
- <a href="#bugfixes-3">Bugfixes</a>
+- <a href="#v3-8-1">v3\.8\.1</a>
+ - <a href="#release-summary-5">Release Summary</a>
+ - <a href="#security-fixes">Security Fixes</a>
+ - <a href="#bugfixes-4">Bugfixes</a>
+- <a href="#v3-8-0">v3\.8\.0</a>
+ - <a href="#release-summary-6">Release Summary</a>
+ - <a href="#minor-changes-2">Minor Changes</a>
+ - <a href="#bugfixes-5">Bugfixes</a>
+- <a href="#v3-7-0">v3\.7\.0</a>
+ - <a href="#release-summary-7">Release Summary</a>
+ - <a href="#minor-changes-3">Minor Changes</a>
+ - <a href="#bugfixes-6">Bugfixes</a>
- <a href="#new-modules">New Modules</a>
- <a href="#v3-6-0">v3\.6\.0</a>
- - <a href="#release-summary-4">Release Summary</a>
+ - <a href="#release-summary-8">Release Summary</a>
- <a href="#major-changes">Major Changes</a>
- - <a href="#minor-changes-3">Minor Changes</a>
- - <a href="#bugfixes-4">Bugfixes</a>
- - <a href="#new-modules-1">New Modules</a>
-- <a href="#v3-5-0">v3\.5\.0</a>
- - <a href="#release-summary-5">Release Summary</a>
- <a href="#minor-changes-4">Minor Changes</a>
- - <a href="#deprecated-features">Deprecated Features</a>
- - <a href="#bugfixes-5">Bugfixes</a>
-- <a href="#v3-4-11">v3\.4\.11</a>
- - <a href="#release-summary-6">Release Summary</a>
- - <a href="#bugfixes-6">Bugfixes</a>
-- <a href="#v3-4-10">v3\.4\.10</a>
- - <a href="#release-summary-7">Release Summary</a>
- <a href="#bugfixes-7">Bugfixes</a>
-- <a href="#v3-4-9">v3\.4\.9</a>
- - <a href="#release-summary-8">Release Summary</a>
- - <a href="#bugfixes-8">Bugfixes</a>
-- <a href="#v3-4-8">v3\.4\.8</a>
+ - <a href="#new-modules-1">New Modules</a>
+- <a href="#v3-5-0">v3\.5\.0</a>
- <a href="#release-summary-9">Release Summary</a>
- - <a href="#known-issues">Known Issues</a>
-- <a href="#v3-4-7">v3\.4\.7</a>
+ - <a href="#minor-changes-5">Minor Changes</a>
+ - <a href="#deprecated-features-1">Deprecated Features</a>
+ - <a href="#bugfixes-8">Bugfixes</a>
+- <a href="#v3-4-11">v3\.4\.11</a>
- <a href="#release-summary-10">Release Summary</a>
- <a href="#bugfixes-9">Bugfixes</a>
-- <a href="#v3-4-6">v3\.4\.6</a>
+- <a href="#v3-4-10">v3\.4\.10</a>
- <a href="#release-summary-11">Release Summary</a>
- <a href="#bugfixes-10">Bugfixes</a>
- - <a href="#known-issues-1">Known Issues</a>
-- <a href="#v3-4-5">v3\.4\.5</a>
+- <a href="#v3-4-9">v3\.4\.9</a>
- <a href="#release-summary-12">Release Summary</a>
- <a href="#bugfixes-11">Bugfixes</a>
-- <a href="#v3-4-4">v3\.4\.4</a>
+- <a href="#v3-4-8">v3\.4\.8</a>
- <a href="#release-summary-13">Release Summary</a>
- - <a href="#minor-changes-5">Minor Changes</a>
- - <a href="#known-issues-2">Known Issues</a>
-- <a href="#v3-4-3">v3\.4\.3</a>
+ - <a href="#known-issues-1">Known Issues</a>
+- <a href="#v3-4-7">v3\.4\.7</a>
- <a href="#release-summary-14">Release Summary</a>
-- <a href="#v3-4-2">v3\.4\.2</a>
- - <a href="#release-summary-15">Release Summary</a>
- <a href="#bugfixes-12">Bugfixes</a>
-- <a href="#v3-4-1">v3\.4\.1</a>
- - <a href="#release-summary-16">Release Summary</a>
+- <a href="#v3-4-6">v3\.4\.6</a>
+ - <a href="#release-summary-15">Release Summary</a>
- <a href="#bugfixes-13">Bugfixes</a>
-- <a href="#v3-4-0">v3\.4\.0</a>
+ - <a href="#known-issues-2">Known Issues</a>
+- <a href="#v3-4-5">v3\.4\.5</a>
+ - <a href="#release-summary-16">Release Summary</a>
+ - <a href="#bugfixes-14">Bugfixes</a>
+- <a href="#v3-4-4">v3\.4\.4</a>
- <a href="#release-summary-17">Release Summary</a>
- <a href="#minor-changes-6">Minor Changes</a>
- - <a href="#bugfixes-14">Bugfixes</a>
- - <a href="#new-modules-2">New Modules</a>
-- <a href="#v3-3-2">v3\.3\.2</a>
+ - <a href="#known-issues-3">Known Issues</a>
+- <a href="#v3-4-3">v3\.4\.3</a>
- <a href="#release-summary-18">Release Summary</a>
- - <a href="#bugfixes-15">Bugfixes</a>
-- <a href="#v3-3-1">v3\.3\.1</a>
+- <a href="#v3-4-2">v3\.4\.2</a>
- <a href="#release-summary-19">Release Summary</a>
- - <a href="#bugfixes-16">Bugfixes</a>
-- <a href="#v3-3-0">v3\.3\.0</a>
+ - <a href="#bugfixes-15">Bugfixes</a>
+- <a href="#v3-4-1">v3\.4\.1</a>
- <a href="#release-summary-20">Release Summary</a>
+ - <a href="#bugfixes-16">Bugfixes</a>
+- <a href="#v3-4-0">v3\.4\.0</a>
+ - <a href="#release-summary-21">Release Summary</a>
- <a href="#minor-changes-7">Minor Changes</a>
- <a href="#bugfixes-17">Bugfixes</a>
-- <a href="#v3-2-2">v3\.2\.2</a>
- - <a href="#release-summary-21">Release Summary</a>
- - <a href="#bugfixes-18">Bugfixes</a>
-- <a href="#v3-2-1">v3\.2\.1</a>
+ - <a href="#new-modules-2">New Modules</a>
+- <a href="#v3-3-2">v3\.3\.2</a>
- <a href="#release-summary-22">Release Summary</a>
-- <a href="#v3-2-0">v3\.2\.0</a>
+ - <a href="#bugfixes-18">Bugfixes</a>
+- <a href="#v3-3-1">v3\.3\.1</a>
- <a href="#release-summary-23">Release Summary</a>
- - <a href="#minor-changes-8">Minor Changes</a>
- - <a href="#deprecated-features-1">Deprecated Features</a>
-- <a href="#v3-1-0">v3\.1\.0</a>
+ - <a href="#bugfixes-19">Bugfixes</a>
+- <a href="#v3-3-0">v3\.3\.0</a>
- <a href="#release-summary-24">Release Summary</a>
+ - <a href="#minor-changes-8">Minor Changes</a>
+ - <a href="#bugfixes-20">Bugfixes</a>
+- <a href="#v3-2-2">v3\.2\.2</a>
+ - <a href="#release-summary-25">Release Summary</a>
+ - <a href="#bugfixes-21">Bugfixes</a>
+- <a href="#v3-2-1">v3\.2\.1</a>
+ - <a href="#release-summary-26">Release Summary</a>
+- <a href="#v3-2-0">v3\.2\.0</a>
+ - <a href="#release-summary-27">Release Summary</a>
- <a href="#minor-changes-9">Minor Changes</a>
+ - <a href="#deprecated-features-2">Deprecated Features</a>
+- <a href="#v3-1-0">v3\.1\.0</a>
+ - <a href="#release-summary-28">Release Summary</a>
+ - <a href="#minor-changes-10">Minor Changes</a>
- <a href="#v3-0-2">v3\.0\.2</a>
- - <a href="#release-summary-25">Release Summary</a>
- - <a href="#bugfixes-19">Bugfixes</a>
+ - <a href="#release-summary-29">Release Summary</a>
+ - <a href="#bugfixes-22">Bugfixes</a>
- <a href="#v3-0-1">v3\.0\.1</a>
- - <a href="#release-summary-26">Release Summary</a>
- - <a href="#bugfixes-20">Bugfixes</a>
+ - <a href="#release-summary-30">Release Summary</a>
+ - <a href="#bugfixes-23">Bugfixes</a>
- <a href="#v3-0-0">v3\.0\.0</a>
- - <a href="#release-summary-27">Release Summary</a>
+ - <a href="#release-summary-31">Release Summary</a>
- <a href="#major-changes-1">Major Changes</a>
- - <a href="#minor-changes-10">Minor Changes</a>
+ - <a href="#minor-changes-11">Minor Changes</a>
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- <a href="#security-fixes-1">Security Fixes</a>
- - <a href="#bugfixes-21">Bugfixes</a>
+ - <a href="#bugfixes-24">Bugfixes</a>
- <a href="#v2-7-0">v2\.7\.0</a>
- - <a href="#release-summary-28">Release Summary</a>
- - <a href="#minor-changes-11">Minor Changes</a>
- - <a href="#deprecated-features-2">Deprecated Features</a>
- - <a href="#bugfixes-22">Bugfixes</a>
-- <a href="#v2-6-0">v2\.6\.0</a>
- - <a href="#release-summary-29">Release Summary</a>
+ - <a href="#release-summary-32">Release Summary</a>
- <a href="#minor-changes-12">Minor Changes</a>
- <a href="#deprecated-features-3">Deprecated Features</a>
- - <a href="#bugfixes-23">Bugfixes</a>
-- <a href="#v2-5-1">v2\.5\.1</a>
- - <a href="#release-summary-30">Release Summary</a>
- - <a href="#bugfixes-24">Bugfixes</a>
-- <a href="#v2-5-0">v2\.5\.0</a>
- - <a href="#release-summary-31">Release Summary</a>
- - <a href="#minor-changes-13">Minor Changes</a>
-- <a href="#v2-4-0">v2\.4\.0</a>
- - <a href="#release-summary-32">Release Summary</a>
- - <a href="#minor-changes-14">Minor Changes</a>
- <a href="#bugfixes-25">Bugfixes</a>
-- <a href="#v2-3-0">v2\.3\.0</a>
+- <a href="#v2-6-0">v2\.6\.0</a>
- <a href="#release-summary-33">Release Summary</a>
- - <a href="#minor-changes-15">Minor Changes</a>
+ - <a href="#minor-changes-13">Minor Changes</a>
+ - <a href="#deprecated-features-4">Deprecated Features</a>
- <a href="#bugfixes-26">Bugfixes</a>
-- <a href="#v2-2-1">v2\.2\.1</a>
+- <a href="#v2-5-1">v2\.5\.1</a>
- <a href="#release-summary-34">Release Summary</a>
- <a href="#bugfixes-27">Bugfixes</a>
-- <a href="#v2-2-0">v2\.2\.0</a>
+- <a href="#v2-5-0">v2\.5\.0</a>
- <a href="#release-summary-35">Release Summary</a>
- - <a href="#minor-changes-16">Minor Changes</a>
- - <a href="#bugfixes-28">Bugfixes</a>
-- <a href="#v2-1-1">v2\.1\.1</a>
+ - <a href="#minor-changes-14">Minor Changes</a>
+- <a href="#v2-4-0">v2\.4\.0</a>
- <a href="#release-summary-36">Release Summary</a>
- - <a href="#bugfixes-29">Bugfixes</a>
-- <a href="#v2-1-0">v2\.1\.0</a>
+ - <a href="#minor-changes-15">Minor Changes</a>
+ - <a href="#bugfixes-28">Bugfixes</a>
+- <a href="#v2-3-0">v2\.3\.0</a>
- <a href="#release-summary-37">Release Summary</a>
- - <a href="#minor-changes-17">Minor Changes</a>
- - <a href="#bugfixes-30">Bugfixes</a>
-- <a href="#v2-0-2">v2\.0\.2</a>
+ - <a href="#minor-changes-16">Minor Changes</a>
+ - <a href="#bugfixes-29">Bugfixes</a>
+- <a href="#v2-2-1">v2\.2\.1</a>
- <a href="#release-summary-38">Release Summary</a>
- - <a href="#bugfixes-31">Bugfixes</a>
-- <a href="#v2-0-1">v2\.0\.1</a>
+ - <a href="#bugfixes-30">Bugfixes</a>
+- <a href="#v2-2-0">v2\.2\.0</a>
- <a href="#release-summary-39">Release Summary</a>
-- <a href="#v2-0-0">v2\.0\.0</a>
+ - <a href="#minor-changes-17">Minor Changes</a>
+ - <a href="#bugfixes-31">Bugfixes</a>
+- <a href="#v2-1-1">v2\.1\.1</a>
- <a href="#release-summary-40">Release Summary</a>
- - <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
- - <a href="#deprecated-features-4">Deprecated Features</a>
- - <a href="#removed-features-previously-deprecated-1">Removed Features \(previously deprecated\)</a>
-- <a href="#v1-10-0">v1\.10\.0</a>
+ - <a href="#bugfixes-32">Bugfixes</a>
+- <a href="#v2-1-0">v2\.1\.0</a>
- <a href="#release-summary-41">Release Summary</a>
- <a href="#minor-changes-18">Minor Changes</a>
-- <a href="#v1-9-1">v1\.9\.1</a>
+ - <a href="#bugfixes-33">Bugfixes</a>
+- <a href="#v2-0-2">v2\.0\.2</a>
- <a href="#release-summary-42">Release Summary</a>
- - <a href="#bugfixes-32">Bugfixes</a>
-- <a href="#v1-9-0">v1\.9\.0</a>
+ - <a href="#bugfixes-34">Bugfixes</a>
+- <a href="#v2-0-1">v2\.0\.1</a>
- <a href="#release-summary-43">Release Summary</a>
- - <a href="#minor-changes-19">Minor Changes</a>
- - <a href="#deprecated-features-5">Deprecated Features</a>
- - <a href="#bugfixes-33">Bugfixes</a>
- - <a href="#new-plugins">New Plugins</a>
- - <a href="#connection">Connection</a>
-- <a href="#v1-8-0">v1\.8\.0</a>
+- <a href="#v2-0-0">v2\.0\.0</a>
- <a href="#release-summary-44">Release Summary</a>
- - <a href="#minor-changes-20">Minor Changes</a>
- - <a href="#bugfixes-34">Bugfixes</a>
-- <a href="#v1-7-0">v1\.7\.0</a>
+ - <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
+ - <a href="#deprecated-features-5">Deprecated Features</a>
+ - <a href="#removed-features-previously-deprecated-1">Removed Features \(previously deprecated\)</a>
+- <a href="#v1-10-0">v1\.10\.0</a>
- <a href="#release-summary-45">Release Summary</a>
- - <a href="#minor-changes-21">Minor Changes</a>
-- <a href="#v1-6-1">v1\.6\.1</a>
+ - <a href="#minor-changes-19">Minor Changes</a>
+- <a href="#v1-9-1">v1\.9\.1</a>
- <a href="#release-summary-46">Release Summary</a>
- <a href="#bugfixes-35">Bugfixes</a>
-- <a href="#v1-6-0">v1\.6\.0</a>
+- <a href="#v1-9-0">v1\.9\.0</a>
- <a href="#release-summary-47">Release Summary</a>
- - <a href="#minor-changes-22">Minor Changes</a>
+ - <a href="#minor-changes-20">Minor Changes</a>
- <a href="#deprecated-features-6">Deprecated Features</a>
- <a href="#bugfixes-36">Bugfixes</a>
-- <a href="#v1-5-0">v1\.5\.0</a>
+ - <a href="#new-plugins">New Plugins</a>
+ - <a href="#connection">Connection</a>
+- <a href="#v1-8-0">v1\.8\.0</a>
- <a href="#release-summary-48">Release Summary</a>
- - <a href="#minor-changes-23">Minor Changes</a>
+ - <a href="#minor-changes-21">Minor Changes</a>
- <a href="#bugfixes-37">Bugfixes</a>
- - <a href="#new-modules-3">New Modules</a>
-- <a href="#v1-4-0">v1\.4\.0</a>
+- <a href="#v1-7-0">v1\.7\.0</a>
- <a href="#release-summary-49">Release Summary</a>
+ - <a href="#minor-changes-22">Minor Changes</a>
+- <a href="#v1-6-1">v1\.6\.1</a>
+ - <a href="#release-summary-50">Release Summary</a>
+ - <a href="#bugfixes-38">Bugfixes</a>
+- <a href="#v1-6-0">v1\.6\.0</a>
+ - <a href="#release-summary-51">Release Summary</a>
+ - <a href="#minor-changes-23">Minor Changes</a>
+ - <a href="#deprecated-features-7">Deprecated Features</a>
+ - <a href="#bugfixes-39">Bugfixes</a>
+- <a href="#v1-5-0">v1\.5\.0</a>
+ - <a href="#release-summary-52">Release Summary</a>
- <a href="#minor-changes-24">Minor Changes</a>
+ - <a href="#bugfixes-40">Bugfixes</a>
+ - <a href="#new-modules-3">New Modules</a>
+- <a href="#v1-4-0">v1\.4\.0</a>
+ - <a href="#release-summary-53">Release Summary</a>
+ - <a href="#minor-changes-25">Minor Changes</a>
- <a href="#breaking-changes--porting-guide-2">Breaking Changes / Porting Guide</a>
- <a href="#security-fixes-2">Security Fixes</a>
- - <a href="#bugfixes-38">Bugfixes</a>
+ - <a href="#bugfixes-41">Bugfixes</a>
- <a href="#v1-3-0">v1\.3\.0</a>
- - <a href="#release-summary-50">Release Summary</a>
- - <a href="#minor-changes-25">Minor Changes</a>
- - <a href="#bugfixes-39">Bugfixes</a>
+ - <a href="#release-summary-54">Release Summary</a>
+ - <a href="#minor-changes-26">Minor Changes</a>
+ - <a href="#bugfixes-42">Bugfixes</a>
- <a href="#new-modules-4">New Modules</a>
- <a href="#v1-2-2">v1\.2\.2</a>
- - <a href="#release-summary-51">Release Summary</a>
+ - <a href="#release-summary-55">Release Summary</a>
- <a href="#security-fixes-3">Security Fixes</a>
- <a href="#v1-2-1">v1\.2\.1</a>
- - <a href="#release-summary-52">Release Summary</a>
- - <a href="#bugfixes-40">Bugfixes</a>
+ - <a href="#release-summary-56">Release Summary</a>
+ - <a href="#bugfixes-43">Bugfixes</a>
- <a href="#v1-2-0">v1\.2\.0</a>
- - <a href="#release-summary-53">Release Summary</a>
- - <a href="#minor-changes-26">Minor Changes</a>
- - <a href="#bugfixes-41">Bugfixes</a>
-- <a href="#v1-1-0">v1\.1\.0</a>
- - <a href="#release-summary-54">Release Summary</a>
+ - <a href="#release-summary-57">Release Summary</a>
- <a href="#minor-changes-27">Minor Changes</a>
- - <a href="#deprecated-features-7">Deprecated Features</a>
- - <a href="#bugfixes-42">Bugfixes</a>
+ - <a href="#bugfixes-44">Bugfixes</a>
+- <a href="#v1-1-0">v1\.1\.0</a>
+ - <a href="#release-summary-58">Release Summary</a>
+ - <a href="#minor-changes-28">Minor Changes</a>
+ - <a href="#deprecated-features-8">Deprecated Features</a>
+ - <a href="#bugfixes-45">Bugfixes</a>
- <a href="#new-plugins-1">New Plugins</a>
- <a href="#connection-1">Connection</a>
- <a href="#inventory">Inventory</a>
- <a href="#new-modules-5">New Modules</a>
- <a href="#v1-0-1">v1\.0\.1</a>
- - <a href="#release-summary-55">Release Summary</a>
- - <a href="#bugfixes-43">Bugfixes</a>
+ - <a href="#release-summary-59">Release Summary</a>
+ - <a href="#bugfixes-46">Bugfixes</a>
- <a href="#v1-0-0">v1\.0\.0</a>
- - <a href="#release-summary-56">Release Summary</a>
- - <a href="#minor-changes-28">Minor Changes</a>
-- <a href="#v0-1-0">v0\.1\.0</a>
- - <a href="#release-summary-57">Release Summary</a>
+ - <a href="#release-summary-60">Release Summary</a>
- <a href="#minor-changes-29">Minor Changes</a>
+- <a href="#v0-1-0">v0\.1\.0</a>
+ - <a href="#release-summary-61">Release Summary</a>
+ - <a href="#minor-changes-30">Minor Changes</a>
- <a href="#removed-features-previously-deprecated-2">Removed Features \(previously deprecated\)</a>
- - <a href="#bugfixes-44">Bugfixes</a>
+ - <a href="#bugfixes-47">Bugfixes</a>
+
+<a id="v3-10-3"></a>
+## v3\.10\.3
+
+<a id="release-summary"></a>
+### Release Summary
+
+Bugfix release\.
+
+<a id="bugfixes"></a>
+### Bugfixes
+
+* docker and nsenter connection plugins\, docker\_container\_exec module \- avoid using the deprecated <code>ansible\.module\_utils\.compat\.selectors</code> module util with Python 3 \([https\://github\.com/ansible\-collections/community\.docker/issues/870](https\://github\.com/ansible\-collections/community\.docker/issues/870)\, [https\://github\.com/ansible\-collections/community\.docker/pull/871](https\://github\.com/ansible\-collections/community\.docker/pull/871)\)\.
+
+<a id="v3-10-2"></a>
+## v3\.10\.2
+
+<a id="release-summary-1"></a>
+### Release Summary
+
+Bugfix release\.
+
+<a id="bugfixes-1"></a>
+### Bugfixes
+
+* vendored Docker SDK for Python \- include a fix requests 2\.32\.2\+ compatibility \([https\://github\.com/ansible\-collections/community\.docker/issues/860](https\://github\.com/ansible\-collections/community\.docker/issues/860)\, [https\://github\.com/psf/requests/issues/6707](https\://github\.com/psf/requests/issues/6707)\, [https\://github\.com/ansible\-collections/community\.docker/pull/864](https\://github\.com/ansible\-collections/community\.docker/pull/864)\)\.
+
+<a id="v3-10-1"></a>
+## v3\.10\.1
+
+<a id="release-summary-2"></a>
+### Release Summary
+
+Hotfix release for requests 2\.32\.0 compatibility\.
+
+<a id="bugfixes-2"></a>
+### Bugfixes
+
+* vendored Docker SDK for Python \- include a hotfix for requests 2\.32\.0 compatibility \([https\://github\.com/ansible\-collections/community\.docker/issues/860](https\://github\.com/ansible\-collections/community\.docker/issues/860)\, [https\://github\.com/docker/docker\-py/issues/3256](https\://github\.com/docker/docker\-py/issues/3256)\, [https\://github\.com/ansible\-collections/community\.docker/pull/861](https\://github\.com/ansible\-collections/community\.docker/pull/861)\)\.
+
+<a id="known-issues"></a>
+### Known Issues
+
+* Please note that the fix for requests 2\.32\.0 included in community\.docker 3\.10\.1 only
+ fixes problems with the <em>vendored</em> Docker SDK for Python code\. Modules and plugins that
+ use Docker SDK for Python can still fail due to the SDK currently being incompatible
+ with requests 2\.32\.0\.
+
+ If you still experience problems with requests 2\.32\.0\, such as error messages like
+ <code>Not supported URL scheme http\+docker</code>\, please restrict requests to <code>\<2\.32\.0</code>\.
+
+<a id="v3-10-0"></a>
+## v3\.10\.0
+
+<a id="release-summary-3"></a>
+### Release Summary
+
+Feature release\.
+
+<a id="minor-changes"></a>
+### Minor Changes
+
+* docker\_container \- adds <code>healthcheck\.start\_interval</code> to support healthcheck start interval setting on containers \([https\://github\.com/ansible\-collections/community\.docker/pull/848](https\://github\.com/ansible\-collections/community\.docker/pull/848)\)\.
+* docker\_container \- adds <code>healthcheck\.test\_cli\_compatible</code> to allow omit test option on containers without remove existing image test \([https\://github\.com/ansible\-collections/community\.docker/pull/847](https\://github\.com/ansible\-collections/community\.docker/pull/847)\)\.
+* docker\_image\_build \- add <code>outputs</code> option to allow configuring outputs for the build \([https\://github\.com/ansible\-collections/community\.docker/pull/852](https\://github\.com/ansible\-collections/community\.docker/pull/852)\)\.
+* docker\_image\_build \- add <code>secrets</code> option to allow passing secrets to the build \([https\://github\.com/ansible\-collections/community\.docker/pull/852](https\://github\.com/ansible\-collections/community\.docker/pull/852)\)\.
+* docker\_image\_build \- allow <code>platform</code> to be a list of platforms instead of only a single platform for multi\-platform builds \([https\://github\.com/ansible\-collections/community\.docker/pull/852](https\://github\.com/ansible\-collections/community\.docker/pull/852)\)\.
+* docker\_network \- adds <code>config\_only</code> and <code>config\_from</code> to support creating and using config only networks \([https\://github\.com/ansible\-collections/community\.docker/issues/395](https\://github\.com/ansible\-collections/community\.docker/issues/395)\)\.
+* docker\_prune \- add new options <code>builder\_cache\_all</code>\, <code>builder\_cache\_filters</code>\, and <code>builder\_cache\_keep\_storage</code>\, and a new return value <code>builder\_cache\_caches\_deleted</code> for pruning build caches \([https\://github\.com/ansible\-collections/community\.docker/issues/844](https\://github\.com/ansible\-collections/community\.docker/issues/844)\, [https\://github\.com/ansible\-collections/community\.docker/issues/845](https\://github\.com/ansible\-collections/community\.docker/issues/845)\)\.
+* docker\_swarm\_service \- adds <code>sysctls</code> to support sysctl settings on swarm services \([https\://github\.com/ansible\-collections/community\.docker/issues/190](https\://github\.com/ansible\-collections/community\.docker/issues/190)\)\.
+
+<a id="deprecated-features"></a>
+### Deprecated Features
+
+* docker\_compose \- the Docker Compose v1 module is deprecated and will be removed from community\.docker 4\.0\.0\. Please migrate to the <code>community\.docker\.docker\_compose\_v2</code> module\, which works with Docker Compose v2 \([https\://github\.com/ansible\-collections/community\.docker/issues/823](https\://github\.com/ansible\-collections/community\.docker/issues/823)\, [https\://github\.com/ansible\-collections/community\.docker/pull/833](https\://github\.com/ansible\-collections/community\.docker/pull/833)\)\.
+* various modules and plugins \- the <code>ssl\_version</code> option has been deprecated and will be removed from community\.docker 4\.0\.0\. It has already been removed from Docker SDK for Python 7\.0\.0\, and was only necessary in the past to work around SSL/TLS issues \([https\://github\.com/ansible\-collections/community\.docker/pull/853](https\://github\.com/ansible\-collections/community\.docker/pull/853)\)\.
<a id="v3-9-0"></a>
## v3\.9\.0
-<a id="release-summary"></a>
+<a id="release-summary-4"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes"></a>
+<a id="minor-changes-1"></a>
### Minor Changes
* The EE requirements now include PyYAML\, since the <code>docker\_compose\_v2\*</code> modules depend on it when the <code>definition</code> option is used\. This should not have a noticable effect on generated EEs since ansible\-core itself depends on PyYAML as well\, and ansible\-builder explicitly ignores this dependency \([https\://github\.com/ansible\-collections/community\.docker/pull/832](https\://github\.com/ansible\-collections/community\.docker/pull/832)\)\.
@@ -244,7 +334,7 @@ Bugfix and feature release\.
* docker\_compose\_v2\* modules \- allow to provide an inline definition of the compose content instead of having to provide a <code>project\_src</code> directory with the compose file written into it \([https\://github\.com/ansible\-collections/community\.docker/issues/829](https\://github\.com/ansible\-collections/community\.docker/issues/829)\, [https\://github\.com/ansible\-collections/community\.docker/pull/832](https\://github\.com/ansible\-collections/community\.docker/pull/832)\)\.
* vendored Docker SDK for Python \- remove unused code that relies on functionality deprecated in Python 3\.12 \([https\://github\.com/ansible\-collections/community\.docker/pull/834](https\://github\.com/ansible\-collections/community\.docker/pull/834)\)\.
-<a id="bugfixes"></a>
+<a id="bugfixes-3"></a>
### Bugfixes
* docker\_compose\_v2\* \- allow <code>project\_src</code> to be a relative path\, by converting it to an absolute path before using it \([https\://github\.com/ansible\-collections/community\.docker/issues/827](https\://github\.com/ansible\-collections/community\.docker/issues/827)\, [https\://github\.com/ansible\-collections/community\.docker/pull/828](https\://github\.com/ansible\-collections/community\.docker/pull/828)\)\.
@@ -254,7 +344,7 @@ Bugfix and feature release\.
<a id="v3-8-1"></a>
## v3\.8\.1
-<a id="release-summary-1"></a>
+<a id="release-summary-5"></a>
### Release Summary
Bugfix release
@@ -264,7 +354,7 @@ Bugfix release
* docker\_containers\, docker\_machine\, and docker\_swarm inventory plugins \- make sure all data received from the Docker daemon / Docker machine is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.docker/pull/815](https\://github\.com/ansible\-collections/community\.docker/pull/815)\)\.
-<a id="bugfixes-1"></a>
+<a id="bugfixes-4"></a>
### Bugfixes
* docker\_compose\_v2 \- do not fail when non\-fatal errors occur\. This can happen when pulling an image fails\, but then the image can be built for another service\. Docker Compose emits an error in that case\, but <code>docker compose up</code> still completes successfully \([https\://github\.com/ansible\-collections/community\.docker/issues/807](https\://github\.com/ansible\-collections/community\.docker/issues/807)\, [https\://github\.com/ansible\-collections/community\.docker/pull/810](https\://github\.com/ansible\-collections/community\.docker/pull/810)\, [https\://github\.com/ansible\-collections/community\.docker/pull/811](https\://github\.com/ansible\-collections/community\.docker/pull/811)\)\.
@@ -275,19 +365,19 @@ Bugfix release
<a id="v3-8-0"></a>
## v3\.8\.0
-<a id="release-summary-2"></a>
+<a id="release-summary-6"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes-1"></a>
+<a id="minor-changes-2"></a>
### Minor Changes
* docker\_compose\_v2 \- allow to wait until containers are running/health when running <code>docker compose up</code> with the new <code>wait</code> option \([https\://github\.com/ansible\-collections/community\.docker/issues/794](https\://github\.com/ansible\-collections/community\.docker/issues/794)\, [https\://github\.com/ansible\-collections/community\.docker/pull/796](https\://github\.com/ansible\-collections/community\.docker/pull/796)\)\.
* docker\_container \- the <code>pull\_check\_mode\_behavior</code> option now allows to control the module\'s behavior in check mode when <code>pull\=always</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/792](https\://github\.com/ansible\-collections/community\.docker/issues/792)\, [https\://github\.com/ansible\-collections/community\.docker/pull/797](https\://github\.com/ansible\-collections/community\.docker/pull/797)\)\.
* docker\_container \- the <code>pull</code> option now accepts the three values <code>never</code>\, <code>missing\_image</code> \(default\)\, and <code>never</code>\, next to the previously valid values <code>true</code> \(equivalent to <code>always</code>\) and <code>false</code> \(equivalent to <code>missing\_image</code>\)\. This allows the equivalent to <code>\-\-pull\=never</code> from the Docker command line \([https\://github\.com/ansible\-collections/community\.docker/issues/783](https\://github\.com/ansible\-collections/community\.docker/issues/783)\, [https\://github\.com/ansible\-collections/community\.docker/pull/797](https\://github\.com/ansible\-collections/community\.docker/pull/797)\)\.
-<a id="bugfixes-2"></a>
+<a id="bugfixes-5"></a>
### Bugfixes
* docker\_compose\_v2 \- do not consider a <code>Waiting</code> event as an action/change \([https\://github\.com/ansible\-collections/community\.docker/pull/804](https\://github\.com/ansible\-collections/community\.docker/pull/804)\)\.
@@ -297,18 +387,18 @@ Bugfix and feature release\.
<a id="v3-7-0"></a>
## v3\.7\.0
-<a id="release-summary-3"></a>
+<a id="release-summary-7"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes-2"></a>
+<a id="minor-changes-3"></a>
### Minor Changes
* docker\_compose\_v2 \- add <code>scale</code> option to allow to explicitly scale services \([https\://github\.com/ansible\-collections/community\.docker/pull/776](https\://github\.com/ansible\-collections/community\.docker/pull/776)\)\.
* docker\_compose\_v2\, docker\_compose\_v2\_pull \- support <code>files</code> parameter to specify multiple Compose files \([https\://github\.com/ansible\-collections/community\.docker/issues/772](https\://github\.com/ansible\-collections/community\.docker/issues/772)\, [https\://github\.com/ansible\-collections/community\.docker/pull/775](https\://github\.com/ansible\-collections/community\.docker/pull/775)\)\.
-<a id="bugfixes-3"></a>
+<a id="bugfixes-6"></a>
### Bugfixes
* docker\_compose\_v2 \- properly parse dry\-run build events from <code>stderr</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/778](https\://github\.com/ansible\-collections/community\.docker/issues/778)\, [https\://github\.com/ansible\-collections/community\.docker/pull/779](https\://github\.com/ansible\-collections/community\.docker/pull/779)\)\.
@@ -317,12 +407,12 @@ Bugfix and feature release\.
<a id="new-modules"></a>
### New Modules
-* docker\_image\_export \- Export \(archive\) Docker images
+* community\.docker\.docker\_image\_export \- Export \(archive\) Docker images
<a id="v3-6-0"></a>
## v3\.6\.0
-<a id="release-summary-4"></a>
+<a id="release-summary-8"></a>
### Release Summary
Bugfix and feature release\.
@@ -342,7 +432,7 @@ so the main difference is that instead of some Python requirements\, they depend
* The <code>community\.docker</code> collection now depends on the <code>community\.library\_inventory\_filtering\_v1</code> collection\. This utility collection provides host filtering functionality for inventory plugins\. If you use the Ansible community package\, both collections are included and you do not have to do anything special\. If you install the collection with <code>ansible\-galaxy collection install</code>\, it will be installed automatically\. If you install the collection by copying the files of the collection to a place where ansible\-core can find it\, for example by cloning the git repository\, you need to make sure that you also have to install the dependency if you are using the inventory plugins \([https\://github\.com/ansible\-collections/community\.docker/pull/698](https\://github\.com/ansible\-collections/community\.docker/pull/698)\)\.
-<a id="minor-changes-3"></a>
+<a id="minor-changes-4"></a>
### Minor Changes
* The <code>ca\_cert</code> option available to almost all modules and plugins has been renamed to <code>ca\_path</code>\. The name <code>ca\_path</code> is also used for similar options in ansible\-core and other collections\. The old name has been added as an alias and can still be used \([https\://github\.com/ansible\-collections/community\.docker/pull/744](https\://github\.com/ansible\-collections/community\.docker/pull/744)\)\.
@@ -352,7 +442,7 @@ so the main difference is that instead of some Python requirements\, they depend
* docker\_image \- allow to specify memory size and swap memory size in other units than bytes \([https\://github\.com/ansible\-collections/community\.docker/pull/727](https\://github\.com/ansible\-collections/community\.docker/pull/727)\)\.
* inventory plugins \- add <code>filter</code> option which allows to include and exclude hosts based on Jinja2 conditions \([https\://github\.com/ansible\-collections/community\.docker/pull/698](https\://github\.com/ansible\-collections/community\.docker/pull/698)\, [https\://github\.com/ansible\-collections/community\.docker/issues/610](https\://github\.com/ansible\-collections/community\.docker/issues/610)\)\.
-<a id="bugfixes-4"></a>
+<a id="bugfixes-7"></a>
### Bugfixes
* Use <code>unix\:///var/run/docker\.sock</code> instead of the legacy <code>unix\://var/run/docker\.sock</code> as default for <code>docker\_host</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/736](https\://github\.com/ansible\-collections/community\.docker/pull/736)\)\.
@@ -361,34 +451,34 @@ so the main difference is that instead of some Python requirements\, they depend
<a id="new-modules-1"></a>
### New Modules
-* docker\_compose\_v2 \- Manage multi\-container Docker applications with Docker Compose CLI plugin
-* docker\_compose\_v2\_pull \- Pull a Docker compose project
-* docker\_image\_build \- Build Docker images using Docker buildx
-* docker\_image\_pull \- Pull Docker images from registries
-* docker\_image\_push \- Push Docker images to registries
-* docker\_image\_remove \- Remove Docker images
-* docker\_image\_tag \- Tag Docker images with new names and/or tags
+* community\.docker\.docker\_compose\_v2 \- Manage multi\-container Docker applications with Docker Compose CLI plugin
+* community\.docker\.docker\_compose\_v2\_pull \- Pull a Docker compose project
+* community\.docker\.docker\_image\_build \- Build Docker images using Docker buildx
+* community\.docker\.docker\_image\_pull \- Pull Docker images from registries
+* community\.docker\.docker\_image\_push \- Push Docker images to registries
+* community\.docker\.docker\_image\_remove \- Remove Docker images
+* community\.docker\.docker\_image\_tag \- Tag Docker images with new names and/or tags
<a id="v3-5-0"></a>
## v3\.5\.0
-<a id="release-summary-5"></a>
+<a id="release-summary-9"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes-4"></a>
+<a id="minor-changes-5"></a>
### Minor Changes
* docker\_container \- implement better <code>platform</code> string comparisons to improve idempotency \([https\://github\.com/ansible\-collections/community\.docker/issues/654](https\://github\.com/ansible\-collections/community\.docker/issues/654)\, [https\://github\.com/ansible\-collections/community\.docker/pull/705](https\://github\.com/ansible\-collections/community\.docker/pull/705)\)\.
* docker\_container \- internal refactorings which allow comparisons to use more information like details of the current image or the Docker host config \([https\://github\.com/ansible\-collections/community\.docker/pull/713](https\://github\.com/ansible\-collections/community\.docker/pull/713)\)\.
-<a id="deprecated-features"></a>
+<a id="deprecated-features-1"></a>
### Deprecated Features
* docker\_container \- the default <code>ignore</code> for the <code>image\_name\_mismatch</code> parameter has been deprecated and will switch to <code>recreate</code> in community\.docker 4\.0\.0\. A deprecation warning will be printed in situations where the default value is used and where a behavior would change once the default changes \([https\://github\.com/ansible\-collections/community\.docker/pull/703](https\://github\.com/ansible\-collections/community\.docker/pull/703)\)\.
-<a id="bugfixes-5"></a>
+<a id="bugfixes-8"></a>
### Bugfixes
* modules and plugins using the Docker SDK for Python \- remove <code>ssl\_version</code> from the parameters passed to Docker SDK for Python 7\.0\.0\+\. Explicitly fail with a nicer error message if it was explicitly set in this case \([https\://github\.com/ansible\-collections/community\.docker/pull/715](https\://github\.com/ansible\-collections/community\.docker/pull/715)\)\.
@@ -398,12 +488,12 @@ Bugfix and feature release\.
<a id="v3-4-11"></a>
## v3\.4\.11
-<a id="release-summary-6"></a>
+<a id="release-summary-10"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-6"></a>
+<a id="bugfixes-9"></a>
### Bugfixes
* docker\_volume \- fix crash caused by accessing an empty dictionary\. The <code>has\_different\_config\(\)</code> was raising an <code>AttributeError</code> because the <code>self\.existing\_volume\[\"Labels\"\]</code> dictionary was <code>None</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/702](https\://github\.com/ansible\-collections/community\.docker/pull/702)\)\.
@@ -411,12 +501,12 @@ Bugfix release\.
<a id="v3-4-10"></a>
## v3\.4\.10
-<a id="release-summary-7"></a>
+<a id="release-summary-11"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-7"></a>
+<a id="bugfixes-10"></a>
### Bugfixes
* docker\_swarm \- make init and join operations work again with Docker SDK for Python before 4\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/issues/695](https\://github\.com/ansible\-collections/community\.docker/issues/695)\, [https\://github\.com/ansible\-collections/community\.docker/pull/696](https\://github\.com/ansible\-collections/community\.docker/pull/696)\)\.
@@ -424,12 +514,12 @@ Bugfix release\.
<a id="v3-4-9"></a>
## v3\.4\.9
-<a id="release-summary-8"></a>
+<a id="release-summary-12"></a>
### Release Summary
Maintenance release with updated documentation and vendored Docker SDK for Python code\.
-<a id="bugfixes-8"></a>
+<a id="bugfixes-11"></a>
### Bugfixes
* vendored Docker SDK for Python code \- cherry\-pick changes from the Docker SDK for Python code to align code\. These changes should not affect the parts used by the collection\'s code \([https\://github\.com/ansible\-collections/community\.docker/pull/694](https\://github\.com/ansible\-collections/community\.docker/pull/694)\)\.
@@ -437,7 +527,7 @@ Maintenance release with updated documentation and vendored Docker SDK for Pytho
<a id="v3-4-8"></a>
## v3\.4\.8
-<a id="release-summary-9"></a>
+<a id="release-summary-13"></a>
### Release Summary
Maintenance release with updated documentation\.
@@ -450,7 +540,7 @@ ansible\-core 2\.15 or later to see it as it is intended\. Alternatively you can
look at [the devel docsite](https\://docs\.ansible\.com/ansible/devel/collections/community/docker/)
for the rendered HTML version of the documentation of the latest release\.
-<a id="known-issues"></a>
+<a id="known-issues-1"></a>
### Known Issues
* Ansible markup will show up in raw form on ansible\-doc text output for ansible\-core before 2\.15\. If you have trouble deciphering the documentation markup\, please upgrade to ansible\-core 2\.15 \(or newer\)\, or read the HTML documentation on [https\://docs\.ansible\.com/ansible/devel/collections/community/docker/](https\://docs\.ansible\.com/ansible/devel/collections/community/docker/)\.
@@ -458,12 +548,12 @@ for the rendered HTML version of the documentation of the latest release\.
<a id="v3-4-7"></a>
## v3\.4\.7
-<a id="release-summary-10"></a>
+<a id="release-summary-14"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-9"></a>
+<a id="bugfixes-12"></a>
### Bugfixes
* docker\_swarm\_info \- if <code>service\=true</code> is used\, do not crash when a service without an endpoint spec is encountered \([https\://github\.com/ansible\-collections/community\.docker/issues/636](https\://github\.com/ansible\-collections/community\.docker/issues/636)\, [https\://github\.com/ansible\-collections/community\.docker/pull/637](https\://github\.com/ansible\-collections/community\.docker/pull/637)\)\.
@@ -471,12 +561,12 @@ Bugfix release\.
<a id="v3-4-6"></a>
## v3\.4\.6
-<a id="release-summary-11"></a>
+<a id="release-summary-15"></a>
### Release Summary
Bugfix release with documentation warnings about using certain functionality when connecting to the Docker daemon with TCP TLS\.
-<a id="bugfixes-10"></a>
+<a id="bugfixes-13"></a>
### Bugfixes
* socket\_handler module utils \- make sure this fully works when Docker SDK for Python is not available \([https\://github\.com/ansible\-collections/community\.docker/pull/620](https\://github\.com/ansible\-collections/community\.docker/pull/620)\)\.
@@ -484,7 +574,7 @@ Bugfix release with documentation warnings about using certain functionality whe
* vendored Docker SDK for Python code \- respect timeouts on Windows named pipes \([https\://github\.com/ansible\-collections/community\.docker/pull/619](https\://github\.com/ansible\-collections/community\.docker/pull/619)\)\.
* vendored Docker SDK for Python code \- use <code>poll\(\)</code> instead of <code>select\(\)</code> except on Windows \([https\://github\.com/ansible\-collections/community\.docker/pull/619](https\://github\.com/ansible\-collections/community\.docker/pull/619)\)\.
-<a id="known-issues-1"></a>
+<a id="known-issues-2"></a>
### Known Issues
* docker\_api connection plugin \- does <strong>not work with TCP TLS sockets</strong>\! This is caused by the inability to send an <code>close\_notify</code> TLS alert without closing the connection with Python\'s <code>SSLSocket</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/605](https\://github\.com/ansible\-collections/community\.docker/issues/605)\, [https\://github\.com/ansible\-collections/community\.docker/pull/621](https\://github\.com/ansible\-collections/community\.docker/pull/621)\)\.
@@ -493,12 +583,12 @@ Bugfix release with documentation warnings about using certain functionality whe
<a id="v3-4-5"></a>
## v3\.4\.5
-<a id="release-summary-12"></a>
+<a id="release-summary-16"></a>
### Release Summary
Maintenance release which adds compatibility with requests 2\.29\.0 and 2\.30\.0 and urllib3 2\.0\.
-<a id="bugfixes-11"></a>
+<a id="bugfixes-14"></a>
### Bugfixes
* Make vendored Docker SDK for Python code compatible with requests 2\.29\.0 and urllib3 2\.0 \([https\://github\.com/ansible\-collections/community\.docker/pull/613](https\://github\.com/ansible\-collections/community\.docker/pull/613)\)\.
@@ -506,17 +596,17 @@ Maintenance release which adds compatibility with requests 2\.29\.0 and 2\.30\.0
<a id="v3-4-4"></a>
## v3\.4\.4
-<a id="release-summary-13"></a>
+<a id="release-summary-17"></a>
### Release Summary
Maintenance release with updated EE requirements and updated documentation\.
-<a id="minor-changes-5"></a>
+<a id="minor-changes-6"></a>
### Minor Changes
* Restrict requests to versions before 2\.29\.0\, and urllib3 to versions before 2\.0\.0\. This is necessary until the vendored code from Docker SDK for Python has been fully adjusted to work with a feature of urllib3 that is used since requests 2\.29\.0 \([https\://github\.com/ansible\-collections/community\.docker/issues/611](https\://github\.com/ansible\-collections/community\.docker/issues/611)\, [https\://github\.com/ansible\-collections/community\.docker/pull/612](https\://github\.com/ansible\-collections/community\.docker/pull/612)\)\.
-<a id="known-issues-2"></a>
+<a id="known-issues-3"></a>
### Known Issues
* The modules and plugins using the vendored code from Docker SDK for Python currently do not work with requests 2\.29\.0 and/or urllib3 2\.0\.0\. The same is currently true for the latest version of Docker SDK for Python itself \([https\://github\.com/ansible\-collections/community\.docker/issues/611](https\://github\.com/ansible\-collections/community\.docker/issues/611)\, [https\://github\.com/ansible\-collections/community\.docker/pull/612](https\://github\.com/ansible\-collections/community\.docker/pull/612)\)\.
@@ -524,7 +614,7 @@ Maintenance release with updated EE requirements and updated documentation\.
<a id="v3-4-3"></a>
## v3\.4\.3
-<a id="release-summary-14"></a>
+<a id="release-summary-18"></a>
### Release Summary
Maintenance release with improved documentation\.
@@ -532,12 +622,12 @@ Maintenance release with improved documentation\.
<a id="v3-4-2"></a>
## v3\.4\.2
-<a id="release-summary-15"></a>
+<a id="release-summary-19"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-12"></a>
+<a id="bugfixes-15"></a>
### Bugfixes
* docker\_prune \- return correct value for <code>changed</code>\. So far the module always claimed that nothing changed \([https\://github\.com/ansible\-collections/community\.docker/pull/593](https\://github\.com/ansible\-collections/community\.docker/pull/593)\)\.
@@ -545,12 +635,12 @@ Bugfix release\.
<a id="v3-4-1"></a>
## v3\.4\.1
-<a id="release-summary-16"></a>
+<a id="release-summary-20"></a>
### Release Summary
Regular bugfix release\.
-<a id="bugfixes-13"></a>
+<a id="bugfixes-16"></a>
### Bugfixes
* docker\_api connection plugin\, docker\_container\_exec\, docker\_container\_copy\_into \- properly close socket to Daemon after executing commands in containers \([https\://github\.com/ansible\-collections/community\.docker/pull/582](https\://github\.com/ansible\-collections/community\.docker/pull/582)\)\.
@@ -560,18 +650,18 @@ Regular bugfix release\.
<a id="v3-4-0"></a>
## v3\.4\.0
-<a id="release-summary-17"></a>
+<a id="release-summary-21"></a>
### Release Summary
Regular bugfix and feature release\.
-<a id="minor-changes-6"></a>
+<a id="minor-changes-7"></a>
### Minor Changes
* docker\_api connection plugin \- when copying files to/from a container\, stream the file contents instead of first reading them to memory \([https\://github\.com/ansible\-collections/community\.docker/pull/545](https\://github\.com/ansible\-collections/community\.docker/pull/545)\)\.
* docker\_host\_info \- allow to list all containers with new option <code>containers\_all</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/535](https\://github\.com/ansible\-collections/community\.docker/issues/535)\, [https\://github\.com/ansible\-collections/community\.docker/pull/538](https\://github\.com/ansible\-collections/community\.docker/pull/538)\)\.
-<a id="bugfixes-14"></a>
+<a id="bugfixes-17"></a>
### Bugfixes
* docker\_api connection plugin \- fix error handling when 409 Conflict is returned by the Docker daemon in case of a stopped container \([https\://github\.com/ansible\-collections/community\.docker/pull/546](https\://github\.com/ansible\-collections/community\.docker/pull/546)\)\.
@@ -582,17 +672,17 @@ Regular bugfix and feature release\.
<a id="new-modules-2"></a>
### New Modules
-* docker\_container\_copy\_into \- Copy a file into a Docker container
+* community\.docker\.docker\_container\_copy\_into \- Copy a file into a Docker container
<a id="v3-3-2"></a>
## v3\.3\.2
-<a id="release-summary-18"></a>
+<a id="release-summary-22"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-15"></a>
+<a id="bugfixes-18"></a>
### Bugfixes
* docker\_container \- when <code>detach\=false</code>\, wait indefinitely and not at most one minute\. This was the behavior with Docker SDK for Python\, and was accidentally changed in 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/issues/526](https\://github\.com/ansible\-collections/community\.docker/issues/526)\, [https\://github\.com/ansible\-collections/community\.docker/pull/527](https\://github\.com/ansible\-collections/community\.docker/pull/527)\)\.
@@ -600,12 +690,12 @@ Bugfix release\.
<a id="v3-3-1"></a>
## v3\.3\.1
-<a id="release-summary-19"></a>
+<a id="release-summary-23"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-16"></a>
+<a id="bugfixes-19"></a>
### Bugfixes
* current\_container\_facts \- make container detection work better in more cases \([https\://github\.com/ansible\-collections/community\.docker/pull/522](https\://github\.com/ansible\-collections/community\.docker/pull/522)\)\.
@@ -613,18 +703,18 @@ Bugfix release\.
<a id="v3-3-0"></a>
## v3\.3\.0
-<a id="release-summary-20"></a>
+<a id="release-summary-24"></a>
### Release Summary
Feature and bugfix release\.
-<a id="minor-changes-7"></a>
+<a id="minor-changes-8"></a>
### Minor Changes
* current\_container\_facts \- make work with current Docker version\, also support Podman \([https\://github\.com/ansible\-collections/community\.docker/pull/510](https\://github\.com/ansible\-collections/community\.docker/pull/510)\)\.
* docker\_image \- when using <code>archive\_path</code>\, detect whether changes are necessary based on the image ID \(hash\)\. If the existing tar archive matches the source\, do nothing\. Previously\, each task execution re\-created the archive \([https\://github\.com/ansible\-collections/community\.docker/pull/500](https\://github\.com/ansible\-collections/community\.docker/pull/500)\)\.
-<a id="bugfixes-17"></a>
+<a id="bugfixes-20"></a>
### Bugfixes
* docker\_container\_exec \- fix <code>chdir</code> option which was ignored since community\.docker 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/issues/517](https\://github\.com/ansible\-collections/community\.docker/issues/517)\, [https\://github\.com/ansible\-collections/community\.docker/pull/518](https\://github\.com/ansible\-collections/community\.docker/pull/518)\)\.
@@ -633,12 +723,12 @@ Feature and bugfix release\.
<a id="v3-2-2"></a>
## v3\.2\.2
-<a id="release-summary-21"></a>
+<a id="release-summary-25"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-18"></a>
+<a id="bugfixes-21"></a>
### Bugfixes
* docker\_container \- the <code>kill\_signal</code> option erroneously did not accept strings anymore since 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/issues/505](https\://github\.com/ansible\-collections/community\.docker/issues/505)\, [https\://github\.com/ansible\-collections/community\.docker/pull/506](https\://github\.com/ansible\-collections/community\.docker/pull/506)\)\.
@@ -646,7 +736,7 @@ Bugfix release\.
<a id="v3-2-1"></a>
## v3\.2\.1
-<a id="release-summary-22"></a>
+<a id="release-summary-26"></a>
### Release Summary
Maintenance release with improved documentation\.
@@ -654,17 +744,17 @@ Maintenance release with improved documentation\.
<a id="v3-2-0"></a>
## v3\.2\.0
-<a id="release-summary-23"></a>
+<a id="release-summary-27"></a>
### Release Summary
Feature and deprecation release\.
-<a id="minor-changes-8"></a>
+<a id="minor-changes-9"></a>
### Minor Changes
* docker\_container \- added <code>image\_name\_mismatch</code> option which allows to control the behavior if the container uses the image specified\, but the container\'s configuration uses a different name for the image than the one provided to the module \([https\://github\.com/ansible\-collections/community\.docker/issues/485](https\://github\.com/ansible\-collections/community\.docker/issues/485)\, [https\://github\.com/ansible\-collections/community\.docker/pull/488](https\://github\.com/ansible\-collections/community\.docker/pull/488)\)\.
-<a id="deprecated-features-1"></a>
+<a id="deprecated-features-2"></a>
### Deprecated Features
* docker\_container \- the <code>ignore\_image</code> option is deprecated and will be removed in community\.docker 4\.0\.0\. Use <code>image\: ignore</code> in <code>comparisons</code> instead \([https\://github\.com/ansible\-collections/community\.docker/pull/487](https\://github\.com/ansible\-collections/community\.docker/pull/487)\)\.
@@ -673,12 +763,12 @@ Feature and deprecation release\.
<a id="v3-1-0"></a>
## v3\.1\.0
-<a id="release-summary-24"></a>
+<a id="release-summary-28"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-9"></a>
+<a id="minor-changes-10"></a>
### Minor Changes
* The collection repository conforms to the [REUSE specification](https\://reuse\.software/spec/) except for the changelog fragments \([https\://github\.com/ansible\-collections/community\.docker/pull/462](https\://github\.com/ansible\-collections/community\.docker/pull/462)\)\.
@@ -687,12 +777,12 @@ Feature release\.
<a id="v3-0-2"></a>
## v3\.0\.2
-<a id="release-summary-25"></a>
+<a id="release-summary-29"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-19"></a>
+<a id="bugfixes-22"></a>
### Bugfixes
* docker\_image \- fix build argument handling \([https\://github\.com/ansible\-collections/community\.docker/issues/455](https\://github\.com/ansible\-collections/community\.docker/issues/455)\, [https\://github\.com/ansible\-collections/community\.docker/pull/456](https\://github\.com/ansible\-collections/community\.docker/pull/456)\)\.
@@ -700,12 +790,12 @@ Bugfix release\.
<a id="v3-0-1"></a>
## v3\.0\.1
-<a id="release-summary-26"></a>
+<a id="release-summary-30"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-20"></a>
+<a id="bugfixes-23"></a>
### Bugfixes
* docker\_container \- fix handling of <code>env\_file</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/451](https\://github\.com/ansible\-collections/community\.docker/issues/451)\, [https\://github\.com/ansible\-collections/community\.docker/pull/452](https\://github\.com/ansible\-collections/community\.docker/pull/452)\)\.
@@ -713,7 +803,7 @@ Bugfix release\.
<a id="v3-0-0"></a>
## v3\.0\.0
-<a id="release-summary-27"></a>
+<a id="release-summary-31"></a>
### Release Summary
The 3\.0\.0 release features a rewrite of the <code>docker\_container</code> module\, and many modules and plugins no longer depend on the Docker SDK for Python\.
@@ -740,7 +830,7 @@ The 3\.0\.0 release features a rewrite of the <code>docker\_container</code> mod
* docker\_volume \- no longer uses the Docker SDK for Python\. It requires <code>requests</code> to be installed\, and depending on the features used has some more requirements\. If the Docker SDK for Python is installed\, these requirements are likely met \([https\://github\.com/ansible\-collections/community\.docker/pull/411](https\://github\.com/ansible\-collections/community\.docker/pull/411)\)\.
* docker\_volume\_info \- no longer uses the Docker SDK for Python\. It requires <code>requests</code> to be installed\, and depending on the features used has some more requirements\. If the Docker SDK for Python is installed\, these requirements are likely met \([https\://github\.com/ansible\-collections/community\.docker/pull/412](https\://github\.com/ansible\-collections/community\.docker/pull/412)\)\.
-<a id="minor-changes-10"></a>
+<a id="minor-changes-11"></a>
### Minor Changes
* All software licenses are now in the <code>LICENSES/</code> directory of the collection root\. Moreover\, <code>SPDX\-License\-Identifier\:</code> is used to declare the applicable license for every file that is not automatically generated \([https\://github\.com/ansible\-collections/community\.docker/pull/430](https\://github\.com/ansible\-collections/community\.docker/pull/430)\)\.
@@ -780,7 +870,7 @@ The 3\.0\.0 release features a rewrite of the <code>docker\_container</code> mod
* modules and plugins communicating directly with the Docker daemon \- when connecting by SSH and not using <code>use\_ssh\_client\=true</code>\, reject unknown host keys instead of accepting them\. This is only a change relative to older community\.docker 3\.0\.0 pre\-releases or with respect to Docker SDK for Python \< 6\.0\.0\. Docker SDK for Python 6\.0\.0 will also include this change \([https\://github\.com/ansible\-collections/community\.docker/pull/434](https\://github\.com/ansible\-collections/community\.docker/pull/434)\)\.
-<a id="bugfixes-21"></a>
+<a id="bugfixes-24"></a>
### Bugfixes
* docker\_image \- when composing the build context\, trim trailing whitespace from <code>\.dockerignore</code> entries\. This is only a change relative to older community\.docker 3\.0\.0 pre\-releases or with respect to Docker SDK for Python \< 6\.0\.0\. Docker SDK for Python 6\.0\.0 will also include this change \([https\://github\.com/ansible\-collections/community\.docker/pull/434](https\://github\.com/ansible\-collections/community\.docker/pull/434)\)\.
@@ -794,23 +884,23 @@ The 3\.0\.0 release features a rewrite of the <code>docker\_container</code> mod
<a id="v2-7-0"></a>
## v2\.7\.0
-<a id="release-summary-28"></a>
+<a id="release-summary-32"></a>
### Release Summary
Bugfix and deprecation release\. The next 2\.x\.y releases will only be bugfix releases\, the next expect minor/major release will be 3\.0\.0 with some major changes\.
-<a id="minor-changes-11"></a>
+<a id="minor-changes-12"></a>
### Minor Changes
* Move common utility functions from the <code>common</code> module\_util to a new module\_util called <code>util</code>\. This should not have any user\-visible effect \([https\://github\.com/ansible\-collections/community\.docker/pull/390](https\://github\.com/ansible\-collections/community\.docker/pull/390)\)\.
-<a id="deprecated-features-2"></a>
+<a id="deprecated-features-3"></a>
### Deprecated Features
* Support for Docker API version 1\.20 to 1\.24 has been deprecated and will be removed in community\.docker 3\.0\.0\. The first Docker version supporting API version 1\.25 was Docker 1\.13\, released in January 2017\. This affects the modules <code>docker\_container</code>\, <code>docker\_container\_exec</code>\, <code>docker\_container\_info</code>\, <code>docker\_compose</code>\, <code>docker\_login</code>\, <code>docker\_image</code>\, <code>docker\_image\_info</code>\, <code>docker\_image\_load</code>\, <code>docker\_host\_info</code>\, <code>docker\_network</code>\, <code>docker\_network\_info</code>\, <code>docker\_node\_info</code>\, <code>docker\_swarm\_info</code>\, <code>docker\_swarm\_service</code>\, <code>docker\_swarm\_service\_info</code>\, <code>docker\_volume\_info</code>\, and <code>docker\_volume</code>\, whose minimally supported API version is between 1\.20 and 1\.24 \([https\://github\.com/ansible\-collections/community\.docker/pull/396](https\://github\.com/ansible\-collections/community\.docker/pull/396)\)\.
* Support for Python 2\.6 is deprecated and will be removed in the next major release \(community\.docker 3\.0\.0\)\. Some modules might still work with Python 2\.6\, but we will no longer try to ensure compatibility \([https\://github\.com/ansible\-collections/community\.docker/pull/388](https\://github\.com/ansible\-collections/community\.docker/pull/388)\)\.
-<a id="bugfixes-22"></a>
+<a id="bugfixes-25"></a>
### Bugfixes
* Docker SDK for Python based modules and plugins \- if the API version is specified as an option\, use that one to validate API version requirements of module/plugin options instead of the latest API version supported by the Docker daemon\. This also avoids one unnecessary API call per module/plugin \([https\://github\.com/ansible\-collections/community\.docker/pull/389](https\://github\.com/ansible\-collections/community\.docker/pull/389)\)\.
@@ -818,17 +908,17 @@ Bugfix and deprecation release\. The next 2\.x\.y releases will only be bugfix r
<a id="v2-6-0"></a>
## v2\.6\.0
-<a id="release-summary-29"></a>
+<a id="release-summary-33"></a>
### Release Summary
Bugfix and feature release\.
-<a id="minor-changes-12"></a>
+<a id="minor-changes-13"></a>
### Minor Changes
* docker\_container \- added <code>image\_label\_mismatch</code> parameter \([https\://github\.com/ansible\-collections/community\.docker/issues/314](https\://github\.com/ansible\-collections/community\.docker/issues/314)\, [https\://github\.com/ansible\-collections/community\.docker/pull/370](https\://github\.com/ansible\-collections/community\.docker/pull/370)\)\.
-<a id="deprecated-features-3"></a>
+<a id="deprecated-features-4"></a>
### Deprecated Features
* Support for Ansible 2\.9 and ansible\-base 2\.10 is deprecated\, and will be removed in the next major release \(community\.docker 3\.0\.0\)\. Some modules might still work with these versions afterwards\, but we will no longer keep compatibility code that was needed to support them \([https\://github\.com/ansible\-collections/community\.docker/pull/361](https\://github\.com/ansible\-collections/community\.docker/pull/361)\)\.
@@ -836,7 +926,7 @@ Bugfix and feature release\.
* Various modules \- the default of <code>tls\_hostname</code> that was supposed to be removed in community\.docker 2\.0\.0 will now be removed in version 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/pull/362](https\://github\.com/ansible\-collections/community\.docker/pull/362)\)\.
* docker\_stack \- the return values <code>out</code> and <code>err</code> that were supposed to be removed in community\.docker 2\.0\.0 will now be removed in version 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/pull/362](https\://github\.com/ansible\-collections/community\.docker/pull/362)\)\.
-<a id="bugfixes-23"></a>
+<a id="bugfixes-26"></a>
### Bugfixes
* docker\_container \- fail with a meaningful message instead of crashing if a port is specified with more than three colon\-separated parts \([https\://github\.com/ansible\-collections/community\.docker/pull/367](https\://github\.com/ansible\-collections/community\.docker/pull/367)\, [https\://github\.com/ansible\-collections/community\.docker/issues/365](https\://github\.com/ansible\-collections/community\.docker/issues/365)\)\.
@@ -845,12 +935,12 @@ Bugfix and feature release\.
<a id="v2-5-1"></a>
## v2\.5\.1
-<a id="release-summary-30"></a>
+<a id="release-summary-34"></a>
### Release Summary
Maintenance release\.
-<a id="bugfixes-24"></a>
+<a id="bugfixes-27"></a>
### Bugfixes
* Include <code>PSF\-license\.txt</code> file for <code>plugins/module\_utils/\_version\.py</code>\.
@@ -858,12 +948,12 @@ Maintenance release\.
<a id="v2-5-0"></a>
## v2\.5\.0
-<a id="release-summary-31"></a>
+<a id="release-summary-35"></a>
### Release Summary
Regular feature release\.
-<a id="minor-changes-13"></a>
+<a id="minor-changes-14"></a>
### Minor Changes
* docker\_config \- add support for <code>template\_driver</code> with one option <code>golang</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/332](https\://github\.com/ansible\-collections/community\.docker/issues/332)\, [https\://github\.com/ansible\-collections/community\.docker/pull/345](https\://github\.com/ansible\-collections/community\.docker/pull/345)\)\.
@@ -872,19 +962,19 @@ Regular feature release\.
<a id="v2-4-0"></a>
## v2\.4\.0
-<a id="release-summary-32"></a>
+<a id="release-summary-36"></a>
### Release Summary
Regular feature and bugfix release\.
-<a id="minor-changes-14"></a>
+<a id="minor-changes-15"></a>
### Minor Changes
* Prepare collection for inclusion in an Execution Environment by declaring its dependencies\. The <code>docker\_stack\*</code> modules are not supported \([https\://github\.com/ansible\-collections/community\.docker/pull/336](https\://github\.com/ansible\-collections/community\.docker/pull/336)\)\.
* current\_container\_facts \- add detection for GitHub Actions \([https\://github\.com/ansible\-collections/community\.docker/pull/336](https\://github\.com/ansible\-collections/community\.docker/pull/336)\)\.
* docker\_container \- support returning Docker container log output when using Docker\'s <code>local</code> logging driver\, an optimized local logging driver introduced in Docker 18\.09 \([https\://github\.com/ansible\-collections/community\.docker/pull/337](https\://github\.com/ansible\-collections/community\.docker/pull/337)\)\.
-<a id="bugfixes-25"></a>
+<a id="bugfixes-28"></a>
### Bugfixes
* docker connection plugin \- make sure that <code>docker\_extra\_args</code> is used for querying the Docker version\. Also ensures that the Docker version is only queried when needed\. This is currently the case if a remote user is specified \([https\://github\.com/ansible\-collections/community\.docker/issues/325](https\://github\.com/ansible\-collections/community\.docker/issues/325)\, [https\://github\.com/ansible\-collections/community\.docker/pull/327](https\://github\.com/ansible\-collections/community\.docker/pull/327)\)\.
@@ -892,12 +982,12 @@ Regular feature and bugfix release\.
<a id="v2-3-0"></a>
## v2\.3\.0
-<a id="release-summary-33"></a>
+<a id="release-summary-37"></a>
### Release Summary
Regular feature and bugfix release\.
-<a id="minor-changes-15"></a>
+<a id="minor-changes-16"></a>
### Minor Changes
* docker connection plugin \- implement connection reset by clearing internal container user cache \([https\://github\.com/ansible\-collections/community\.docker/pull/312](https\://github\.com/ansible\-collections/community\.docker/pull/312)\)\.
@@ -906,7 +996,7 @@ Regular feature and bugfix release\.
* docker\_api connection plugin \- implement connection reset by clearing internal container user/group ID cache \([https\://github\.com/ansible\-collections/community\.docker/pull/312](https\://github\.com/ansible\-collections/community\.docker/pull/312)\)\.
* docker\_api connection plugin \- the plugin supports new ways to define the timeout\. These are the <code>ANSIBLE\_DOCKER\_TIMEOUT</code> environment variable\, the <code>timeout</code> setting in the <code>docker\_connection</code> section of <code>ansible\.cfg</code>\, and the <code>ansible\_docker\_timeout</code> variable \([https\://github\.com/ansible\-collections/community\.docker/pull/308](https\://github\.com/ansible\-collections/community\.docker/pull/308)\)\.
-<a id="bugfixes-26"></a>
+<a id="bugfixes-29"></a>
### Bugfixes
* docker connection plugin \- fix option handling to be compatible with ansible\-core 2\.13 \([https\://github\.com/ansible\-collections/community\.docker/pull/297](https\://github\.com/ansible\-collections/community\.docker/pull/297)\, [https\://github\.com/ansible\-collections/community\.docker/issues/307](https\://github\.com/ansible\-collections/community\.docker/issues/307)\)\.
@@ -915,12 +1005,12 @@ Regular feature and bugfix release\.
<a id="v2-2-1"></a>
## v2\.2\.1
-<a id="release-summary-34"></a>
+<a id="release-summary-38"></a>
### Release Summary
Regular bugfix release\.
-<a id="bugfixes-27"></a>
+<a id="bugfixes-30"></a>
### Bugfixes
* docker\_compose \- fix Python 3 type error when extracting warnings or errors from docker\-compose\'s output \([https\://github\.com/ansible\-collections/community\.docker/pull/305](https\://github\.com/ansible\-collections/community\.docker/pull/305)\)\.
@@ -928,19 +1018,19 @@ Regular bugfix release\.
<a id="v2-2-0"></a>
## v2\.2\.0
-<a id="release-summary-35"></a>
+<a id="release-summary-39"></a>
### Release Summary
Regular feature and bugfix release\.
-<a id="minor-changes-16"></a>
+<a id="minor-changes-17"></a>
### Minor Changes
* docker\_config \- add support for rolling update\, set <code>rolling\_versions</code> to <code>true</code> to enable \([https\://github\.com/ansible\-collections/community\.docker/pull/295](https\://github\.com/ansible\-collections/community\.docker/pull/295)\, [https\://github\.com/ansible\-collections/community\.docker/issues/109](https\://github\.com/ansible\-collections/community\.docker/issues/109)\)\.
* docker\_secret \- add support for rolling update\, set <code>rolling\_versions</code> to <code>true</code> to enable \([https\://github\.com/ansible\-collections/community\.docker/pull/293](https\://github\.com/ansible\-collections/community\.docker/pull/293)\, [https\://github\.com/ansible\-collections/community\.docker/issues/21](https\://github\.com/ansible\-collections/community\.docker/issues/21)\)\.
* docker\_swarm\_service \- add support for setting capabilities with the <code>cap\_add</code> and <code>cap\_drop</code> parameters\. Usage is the same as with the <code>capabilities</code> and <code>cap\_drop</code> parameters for <code>docker\_container</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/294](https\://github\.com/ansible\-collections/community\.docker/pull/294)\)\.
-<a id="bugfixes-28"></a>
+<a id="bugfixes-31"></a>
### Bugfixes
* docker\_container\, docker\_image \- adjust image finding code to peculiarities of <code>podman\-docker</code>\'s API emulation when Docker short names like <code>redis</code> are used \([https\://github\.com/ansible\-collections/community\.docker/issues/292](https\://github\.com/ansible\-collections/community\.docker/issues/292)\)\.
@@ -948,12 +1038,12 @@ Regular feature and bugfix release\.
<a id="v2-1-1"></a>
## v2\.1\.1
-<a id="release-summary-36"></a>
+<a id="release-summary-40"></a>
### Release Summary
Emergency release to amend breaking change in previous release\.
-<a id="bugfixes-29"></a>
+<a id="bugfixes-32"></a>
### Bugfixes
* Fix unintended breaking change caused by [an earlier fix](https\://github\.com/ansible\-collections/community\.docker/pull/258) by vendoring the deprecated Python standard library <code>distutils\.version</code> until this collection stops supporting Ansible 2\.9 and ansible\-base 2\.10 \([https\://github\.com/ansible\-collections/community\.docker/issues/267](https\://github\.com/ansible\-collections/community\.docker/issues/267)\, [https\://github\.com/ansible\-collections/community\.docker/pull/269](https\://github\.com/ansible\-collections/community\.docker/pull/269)\)\.
@@ -961,18 +1051,18 @@ Emergency release to amend breaking change in previous release\.
<a id="v2-1-0"></a>
## v2\.1\.0
-<a id="release-summary-37"></a>
+<a id="release-summary-41"></a>
### Release Summary
Feature and bugfix release\.
-<a id="minor-changes-17"></a>
+<a id="minor-changes-18"></a>
### Minor Changes
* docker\_container\_exec \- add <code>detach</code> parameter \([https\://github\.com/ansible\-collections/community\.docker/issues/250](https\://github\.com/ansible\-collections/community\.docker/issues/250)\, [https\://github\.com/ansible\-collections/community\.docker/pull/255](https\://github\.com/ansible\-collections/community\.docker/pull/255)\)\.
* docker\_container\_exec \- add <code>env</code> option \([https\://github\.com/ansible\-collections/community\.docker/issues/248](https\://github\.com/ansible\-collections/community\.docker/issues/248)\, [https\://github\.com/ansible\-collections/community\.docker/pull/254](https\://github\.com/ansible\-collections/community\.docker/pull/254)\)\.
-<a id="bugfixes-30"></a>
+<a id="bugfixes-33"></a>
### Bugfixes
* Various modules and plugins \- use vendored version of <code>distutils\.version</code> included in ansible\-core 2\.12 if available\. This avoids breakage when <code>distutils</code> is removed from the standard library of Python 3\.12\. Note that ansible\-core 2\.11\, ansible\-base 2\.10 and Ansible 2\.9 are right now not compatible with Python 3\.12\, hence this fix does not target these ansible\-core/\-base/2\.9 versions \([https\://github\.com/ansible\-collections/community\.docker/pull/258](https\://github\.com/ansible\-collections/community\.docker/pull/258)\)\.
@@ -982,12 +1072,12 @@ Feature and bugfix release\.
<a id="v2-0-2"></a>
## v2\.0\.2
-<a id="release-summary-38"></a>
+<a id="release-summary-42"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-31"></a>
+<a id="bugfixes-34"></a>
### Bugfixes
* docker\_api connection plugin \- avoid passing an unnecessary argument to a Docker SDK for Python call that is only supported by version 3\.0\.0 or later \([https\://github\.com/ansible\-collections/community\.docker/pull/243](https\://github\.com/ansible\-collections/community\.docker/pull/243)\)\.
@@ -998,7 +1088,7 @@ Bugfix release\.
<a id="v2-0-1"></a>
## v2\.0\.1
-<a id="release-summary-39"></a>
+<a id="release-summary-43"></a>
### Release Summary
Maintenance release with some documentation fixes\.
@@ -1006,7 +1096,7 @@ Maintenance release with some documentation fixes\.
<a id="v2-0-0"></a>
## v2\.0\.0
-<a id="release-summary-40"></a>
+<a id="release-summary-44"></a>
### Release Summary
New major release with some deprecations removed and a breaking change in the <code>docker\_compose</code> module regarding the <code>timeout</code> parameter\.
@@ -1016,7 +1106,7 @@ New major release with some deprecations removed and a breaking change in the <c
* docker\_compose \- fixed <code>timeout</code> defaulting behavior so that <code>stop\_grace\_period</code>\, if defined in the compose file\, will be used if <code>timeout</code> is not specified \([https\://github\.com/ansible\-collections/community\.docker/pull/163](https\://github\.com/ansible\-collections/community\.docker/pull/163)\)\.
-<a id="deprecated-features-4"></a>
+<a id="deprecated-features-5"></a>
### Deprecated Features
* docker\_container \- using the special value <code>all</code> in <code>published\_ports</code> has been deprecated\. Use <code>publish\_all\_ports\=true</code> instead \([https\://github\.com/ansible\-collections/community\.docker/pull/210](https\://github\.com/ansible\-collections/community\.docker/pull/210)\)\.
@@ -1032,12 +1122,12 @@ New major release with some deprecations removed and a breaking change in the <c
<a id="v1-10-0"></a>
## v1\.10\.0
-<a id="release-summary-41"></a>
+<a id="release-summary-45"></a>
### Release Summary
Regular feature and bugfix release\.
-<a id="minor-changes-18"></a>
+<a id="minor-changes-19"></a>
### Minor Changes
* Add the modules docker\_container\_exec\, docker\_image\_load and docker\_plugin to the <code>docker</code> module defaults group \([https\://github\.com/ansible\-collections/community\.docker/pull/209](https\://github\.com/ansible\-collections/community\.docker/pull/209)\)\.
@@ -1047,12 +1137,12 @@ Regular feature and bugfix release\.
<a id="v1-9-1"></a>
## v1\.9\.1
-<a id="release-summary-42"></a>
+<a id="release-summary-46"></a>
### Release Summary
Regular bugfix release\.
-<a id="bugfixes-32"></a>
+<a id="bugfixes-35"></a>
### Bugfixes
* docker\_compose \- fixed incorrect <code>changed</code> status for services with <code>profiles</code> defined\, but none enabled \([https\://github\.com/ansible\-collections/community\.docker/pull/192](https\://github\.com/ansible\-collections/community\.docker/pull/192)\)\.
@@ -1060,12 +1150,12 @@ Regular bugfix release\.
<a id="v1-9-0"></a>
## v1\.9\.0
-<a id="release-summary-43"></a>
+<a id="release-summary-47"></a>
### Release Summary
New bugfixes and features release\.
-<a id="minor-changes-19"></a>
+<a id="minor-changes-20"></a>
### Minor Changes
* docker\_\* modules \- include <code>ImportError</code> traceback when reporting that Docker SDK for Python could not be found \([https\://github\.com/ansible\-collections/community\.docker/pull/188](https\://github\.com/ansible\-collections/community\.docker/pull/188)\)\.
@@ -1074,12 +1164,12 @@ New bugfixes and features release\.
* docker\_container \- added new <code>command\_handling</code> option with current deprecated default value <code>compatibility</code> which allows to control how the module handles shell quoting when interpreting lists\, and how the module handles empty lists/strings\. The default will switch to <code>correct</code> in community\.docker 3\.0\.0 \([https\://github\.com/ansible\-collections/community\.docker/pull/186](https\://github\.com/ansible\-collections/community\.docker/pull/186)\)\.
* docker\_container \- lifted restriction preventing the creation of anonymous volumes with the <code>mounts</code> option \([https\://github\.com/ansible\-collections/community\.docker/pull/181](https\://github\.com/ansible\-collections/community\.docker/pull/181)\)\.
-<a id="deprecated-features-5"></a>
+<a id="deprecated-features-6"></a>
### Deprecated Features
* docker\_container \- the new <code>command\_handling</code>\'s default value\, <code>compatibility</code>\, is deprecated and will change to <code>correct</code> in community\.docker 3\.0\.0\. A deprecation warning is emitted by the module in cases where the behavior will change\. Please note that ansible\-core will output a deprecation warning only once\, so if it is shown for an earlier task\, there could be more tasks with this warning where it is not shown \([https\://github\.com/ansible\-collections/community\.docker/pull/186](https\://github\.com/ansible\-collections/community\.docker/pull/186)\)\.
-<a id="bugfixes-33"></a>
+<a id="bugfixes-36"></a>
### Bugfixes
* docker\_compose \- fixes task failures when bringing up services while using <code>docker\-compose \<1\.17\.0</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/180](https\://github\.com/ansible\-collections/community\.docker/issues/180)\)\.
@@ -1093,17 +1183,17 @@ New bugfixes and features release\.
<a id="connection"></a>
#### Connection
-* nsenter \- execute on host running controller container
+* community\.docker\.nsenter \- execute on host running controller container
<a id="v1-8-0"></a>
## v1\.8\.0
-<a id="release-summary-44"></a>
+<a id="release-summary-48"></a>
### Release Summary
Regular bugfix and feature release\.
-<a id="minor-changes-20"></a>
+<a id="minor-changes-21"></a>
### Minor Changes
* Avoid internal ansible\-core module\_utils in favor of equivalent public API available since at least Ansible 2\.9 \([https\://github\.com/ansible\-collections/community\.docker/pull/164](https\://github\.com/ansible\-collections/community\.docker/pull/164)\)\.
@@ -1112,7 +1202,7 @@ Regular bugfix and feature release\.
* docker\_host\_info \- allow values for keys in <code>containers\_filters</code>\, <code>images\_filters</code>\, <code>networks\_filters</code>\, and <code>volumes\_filters</code> to be passed as YAML lists \([https\://github\.com/ansible\-collections/community\.docker/pull/160](https\://github\.com/ansible\-collections/community\.docker/pull/160)\)\.
* docker\_plugin \- added <code>alias</code> option to specify local names for docker plugins \([https\://github\.com/ansible\-collections/community\.docker/pull/161](https\://github\.com/ansible\-collections/community\.docker/pull/161)\)\.
-<a id="bugfixes-34"></a>
+<a id="bugfixes-37"></a>
### Bugfixes
* docker\_compose \- fix idempotence bug when using <code>stopped\: true</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/142](https\://github\.com/ansible\-collections/community\.docker/issues/142)\, [https\://github\.com/ansible\-collections/community\.docker/pull/159](https\://github\.com/ansible\-collections/community\.docker/pull/159)\)\.
@@ -1120,12 +1210,12 @@ Regular bugfix and feature release\.
<a id="v1-7-0"></a>
## v1\.7\.0
-<a id="release-summary-45"></a>
+<a id="release-summary-49"></a>
### Release Summary
Small feature and bugfix release\.
-<a id="minor-changes-21"></a>
+<a id="minor-changes-22"></a>
### Minor Changes
* docker\_image \- allow to tag images by ID \([https\://github\.com/ansible\-collections/community\.docker/pull/149](https\://github\.com/ansible\-collections/community\.docker/pull/149)\)\.
@@ -1133,12 +1223,12 @@ Small feature and bugfix release\.
<a id="v1-6-1"></a>
## v1\.6\.1
-<a id="release-summary-46"></a>
+<a id="release-summary-50"></a>
### Release Summary
Bugfix release to reduce deprecation warning spam\.
-<a id="bugfixes-35"></a>
+<a id="bugfixes-38"></a>
### Bugfixes
* docker\_\* modules and plugins\, except <code>docker\_swarm</code> connection plugin and <code>docker\_compose</code> and <code>docker\_stack\*\` modules \- only emit \`\`tls\_hostname</code> deprecation message if TLS is actually used \([https\://github\.com/ansible\-collections/community\.docker/pull/143](https\://github\.com/ansible\-collections/community\.docker/pull/143)\)\.
@@ -1146,23 +1236,23 @@ Bugfix release to reduce deprecation warning spam\.
<a id="v1-6-0"></a>
## v1\.6\.0
-<a id="release-summary-47"></a>
+<a id="release-summary-51"></a>
### Release Summary
Regular bugfix and feature release\.
-<a id="minor-changes-22"></a>
+<a id="minor-changes-23"></a>
### Minor Changes
* common module utils \- correct error messages for guiding to install proper Docker SDK for Python module \([https\://github\.com/ansible\-collections/community\.docker/pull/125](https\://github\.com/ansible\-collections/community\.docker/pull/125)\)\.
* docker\_container \- allow <code>memory\_swap\: \-1</code> to set memory swap limit to unlimited\. This is useful when the user cannot set memory swap limits due to cgroup limitations or other reasons\, as by default Docker will try to set swap usage to two times the value of <code>memory</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/138](https\://github\.com/ansible\-collections/community\.docker/pull/138)\)\.
-<a id="deprecated-features-6"></a>
+<a id="deprecated-features-7"></a>
### Deprecated Features
* docker\_\* modules and plugins\, except <code>docker\_swarm</code> connection plugin and <code>docker\_compose</code> and <code>docker\_stack\*\` modules \- the current default \`\`localhost</code> for <code>tls\_hostname</code> is deprecated\. In community\.docker 2\.0\.0 it will be computed from <code>docker\_host</code> instead \([https\://github\.com/ansible\-collections/community\.docker/pull/134](https\://github\.com/ansible\-collections/community\.docker/pull/134)\)\.
-<a id="bugfixes-36"></a>
+<a id="bugfixes-39"></a>
### Bugfixes
* docker\-compose \- fix not pulling when <code>state\: present</code> and <code>stopped\: true</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/12](https\://github\.com/ansible\-collections/community\.docker/issues/12)\, [https\://github\.com/ansible\-collections/community\.docker/pull/119](https\://github\.com/ansible\-collections/community\.docker/pull/119)\)\.
@@ -1172,17 +1262,17 @@ Regular bugfix and feature release\.
<a id="v1-5-0"></a>
## v1\.5\.0
-<a id="release-summary-48"></a>
+<a id="release-summary-52"></a>
### Release Summary
Regular feature release\.
-<a id="minor-changes-23"></a>
+<a id="minor-changes-24"></a>
### Minor Changes
* Add the <code>use\_ssh\_client</code> option to most docker modules and plugins \([https\://github\.com/ansible\-collections/community\.docker/issues/108](https\://github\.com/ansible\-collections/community\.docker/issues/108)\, [https\://github\.com/ansible\-collections/community\.docker/pull/114](https\://github\.com/ansible\-collections/community\.docker/pull/114)\)\.
-<a id="bugfixes-37"></a>
+<a id="bugfixes-40"></a>
### Bugfixes
* all modules \- use <code>to\_native</code> to convert exceptions to strings \([https\://github\.com/ansible\-collections/community\.docker/pull/121](https\://github\.com/ansible\-collections/community\.docker/pull/121)\)\.
@@ -1190,17 +1280,17 @@ Regular feature release\.
<a id="new-modules-3"></a>
### New Modules
-* docker\_container\_exec \- Execute command in a docker container
+* community\.docker\.docker\_container\_exec \- Execute command in a docker container
<a id="v1-4-0"></a>
## v1\.4\.0
-<a id="release-summary-49"></a>
+<a id="release-summary-53"></a>
### Release Summary
Security release to address another potential secret leak\. Also includes regular bugfixes and features\.
-<a id="minor-changes-24"></a>
+<a id="minor-changes-25"></a>
### Minor Changes
* docker\_swarm\_service \- change <code>publish\.published\_port</code> option from mandatory to optional\. Docker will assign random high port if not specified \([https\://github\.com/ansible\-collections/community\.docker/issues/99](https\://github\.com/ansible\-collections/community\.docker/issues/99)\)\.
@@ -1215,7 +1305,7 @@ Security release to address another potential secret leak\. Also includes regula
* docker\_swarm \- the <code>join\_token</code> option is now marked as <code>no\_log</code> so it is no longer written into logs \([https\://github\.com/ansible\-collections/community\.docker/pull/103](https\://github\.com/ansible\-collections/community\.docker/pull/103)\)\.
-<a id="bugfixes-38"></a>
+<a id="bugfixes-41"></a>
### Bugfixes
* <code>docker\_swarm\_service</code> \- fix KeyError on caused by reference to deprecated option <code>update\_failure\_action</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/100](https\://github\.com/ansible\-collections/community\.docker/pull/100)\)\.
@@ -1224,12 +1314,12 @@ Security release to address another potential secret leak\. Also includes regula
<a id="v1-3-0"></a>
## v1\.3\.0
-<a id="release-summary-50"></a>
+<a id="release-summary-54"></a>
### Release Summary
Regular feature and bugfix release\.
-<a id="minor-changes-25"></a>
+<a id="minor-changes-26"></a>
### Minor Changes
* docker\_container \- add <code>storage\_opts</code> option to specify storage options \([https\://github\.com/ansible\-collections/community\.docker/issues/91](https\://github\.com/ansible\-collections/community\.docker/issues/91)\, [https\://github\.com/ansible\-collections/community\.docker/pull/93](https\://github\.com/ansible\-collections/community\.docker/pull/93)\)\.
@@ -1237,7 +1327,7 @@ Regular feature and bugfix release\.
* docker\_image \- properly support image IDs \(hashes\) for loading and tagging images \([https\://github\.com/ansible\-collections/community\.docker/issues/86](https\://github\.com/ansible\-collections/community\.docker/issues/86)\, [https\://github\.com/ansible\-collections/community\.docker/pull/87](https\://github\.com/ansible\-collections/community\.docker/pull/87)\)\.
* docker\_swarm\_service \- adding support for maximum number of tasks per node \(<code>replicas\_max\_per\_node</code>\) when running swarm service in replicated mode\. Introduced in API 1\.40 \([https\://github\.com/ansible\-collections/community\.docker/issues/7](https\://github\.com/ansible\-collections/community\.docker/issues/7)\, [https\://github\.com/ansible\-collections/community\.docker/pull/92](https\://github\.com/ansible\-collections/community\.docker/pull/92)\)\.
-<a id="bugfixes-39"></a>
+<a id="bugfixes-42"></a>
### Bugfixes
* docker\_container \- fix healthcheck disabling idempotency issue with strict comparison \([https\://github\.com/ansible\-collections/community\.docker/issues/85](https\://github\.com/ansible\-collections/community\.docker/issues/85)\)\.
@@ -1249,13 +1339,13 @@ Regular feature and bugfix release\.
<a id="new-modules-4"></a>
### New Modules
-* docker\_image\_load \- Load docker image\(s\) from archives
-* docker\_plugin \- Manage Docker plugins
+* community\.docker\.docker\_image\_load \- Load docker image\(s\) from archives
+* community\.docker\.docker\_plugin \- Manage Docker plugins
<a id="v1-2-2"></a>
## v1\.2\.2
-<a id="release-summary-51"></a>
+<a id="release-summary-55"></a>
### Release Summary
Security bugfix release to address CVE\-2021\-20191\.
@@ -1268,12 +1358,12 @@ Security bugfix release to address CVE\-2021\-20191\.
<a id="v1-2-1"></a>
## v1\.2\.1
-<a id="release-summary-52"></a>
+<a id="release-summary-56"></a>
### Release Summary
Bugfix release\.
-<a id="bugfixes-40"></a>
+<a id="bugfixes-43"></a>
### Bugfixes
* docker connection plugin \- fix Docker version parsing\, as some docker versions have a leading <code>v</code> in the output of the command <code>docker version \-\-format \"\{\{\.Server\.Version\}\}\"</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/76](https\://github\.com/ansible\-collections/community\.docker/pull/76)\)\.
@@ -1281,17 +1371,17 @@ Bugfix release\.
<a id="v1-2-0"></a>
## v1\.2\.0
-<a id="release-summary-53"></a>
+<a id="release-summary-57"></a>
### Release Summary
Feature release with one new feature and two bugfixes\.
-<a id="minor-changes-26"></a>
+<a id="minor-changes-27"></a>
### Minor Changes
* docker\_container \- added <code>default\_host\_ip</code> option which allows to explicitly set the default IP string for published ports without explicitly specified IPs\. When using IPv6 binds with Docker 20\.10\.2 or newer\, this needs to be set to an empty string \(<code>\"\"</code>\) \([https\://github\.com/ansible\-collections/community\.docker/issues/70](https\://github\.com/ansible\-collections/community\.docker/issues/70)\, [https\://github\.com/ansible\-collections/community\.docker/pull/71](https\://github\.com/ansible\-collections/community\.docker/pull/71)\)\.
-<a id="bugfixes-41"></a>
+<a id="bugfixes-44"></a>
### Bugfixes
* docker\_container \- allow IPv6 zones \(RFC 4007\) in bind IPs \([https\://github\.com/ansible\-collections/community\.docker/pull/66](https\://github\.com/ansible\-collections/community\.docker/pull/66)\)\.
@@ -1300,24 +1390,24 @@ Feature release with one new feature and two bugfixes\.
<a id="v1-1-0"></a>
## v1\.1\.0
-<a id="release-summary-54"></a>
+<a id="release-summary-58"></a>
### Release Summary
Feature release with three new plugins and modules\.
-<a id="minor-changes-27"></a>
+<a id="minor-changes-28"></a>
### Minor Changes
* docker\_container \- support specifying <code>cgroup\_parent</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/6](https\://github\.com/ansible\-collections/community\.docker/issues/6)\, [https\://github\.com/ansible\-collections/community\.docker/pull/59](https\://github\.com/ansible\-collections/community\.docker/pull/59)\)\.
* docker\_container \- when a container is started with <code>detached\=false</code>\, <code>status</code> is now also returned when it is 0 \([https\://github\.com/ansible\-collections/community\.docker/issues/26](https\://github\.com/ansible\-collections/community\.docker/issues/26)\, [https\://github\.com/ansible\-collections/community\.docker/pull/58](https\://github\.com/ansible\-collections/community\.docker/pull/58)\)\.
* docker\_image \- support <code>platform</code> when building images \([https\://github\.com/ansible\-collections/community\.docker/issues/22](https\://github\.com/ansible\-collections/community\.docker/issues/22)\, [https\://github\.com/ansible\-collections/community\.docker/pull/54](https\://github\.com/ansible\-collections/community\.docker/pull/54)\)\.
-<a id="deprecated-features-7"></a>
+<a id="deprecated-features-8"></a>
### Deprecated Features
* docker\_container \- currently <code>published\_ports</code> can contain port mappings next to the special value <code>all</code>\, in which case the port mappings are ignored\. This behavior is deprecated for community\.docker 2\.0\.0\, at which point it will either be forbidden\, or this behavior will be properly implemented similar to how the Docker CLI tool handles this \([https\://github\.com/ansible\-collections/community\.docker/issues/8](https\://github\.com/ansible\-collections/community\.docker/issues/8)\, [https\://github\.com/ansible\-collections/community\.docker/pull/60](https\://github\.com/ansible\-collections/community\.docker/pull/60)\)\.
-<a id="bugfixes-42"></a>
+<a id="bugfixes-45"></a>
### Bugfixes
* docker\_image \- if <code>push\=true</code> is used with <code>repository</code>\, and the image does not need to be tagged\, still push\. This can happen if <code>repository</code> and <code>name</code> are equal \([https\://github\.com/ansible\-collections/community\.docker/issues/52](https\://github\.com/ansible\-collections/community\.docker/issues/52)\, [https\://github\.com/ansible\-collections/community\.docker/pull/53](https\://github\.com/ansible\-collections/community\.docker/pull/53)\)\.
@@ -1330,27 +1420,27 @@ Feature release with three new plugins and modules\.
<a id="connection-1"></a>
#### Connection
-* docker\_api \- Run tasks in docker containers
+* community\.docker\.docker\_api \- Run tasks in docker containers
<a id="inventory"></a>
#### Inventory
-* docker\_containers \- Ansible dynamic inventory plugin for Docker containers\.
+* community\.docker\.docker\_containers \- Ansible dynamic inventory plugin for Docker containers\.
<a id="new-modules-5"></a>
### New Modules
-* current\_container\_facts \- Return facts about whether the module runs in a Docker container
+* community\.docker\.current\_container\_facts \- Return facts about whether the module runs in a Docker container
<a id="v1-0-1"></a>
## v1\.0\.1
-<a id="release-summary-55"></a>
+<a id="release-summary-59"></a>
### Release Summary
Maintenance release with a bugfix for <code>docker\_container</code>\.
-<a id="bugfixes-43"></a>
+<a id="bugfixes-46"></a>
### Bugfixes
* docker\_container \- the validation for <code>capabilities</code> in <code>device\_requests</code> was incorrect \([https\://github\.com/ansible\-collections/community\.docker/issues/42](https\://github\.com/ansible\-collections/community\.docker/issues/42)\, [https\://github\.com/ansible\-collections/community\.docker/pull/43](https\://github\.com/ansible\-collections/community\.docker/pull/43)\)\.
@@ -1358,12 +1448,12 @@ Maintenance release with a bugfix for <code>docker\_container</code>\.
<a id="v1-0-0"></a>
## v1\.0\.0
-<a id="release-summary-56"></a>
+<a id="release-summary-60"></a>
### Release Summary
This is the first production \(non\-prerelease\) release of <code>community\.docker</code>\.
-<a id="minor-changes-28"></a>
+<a id="minor-changes-29"></a>
### Minor Changes
* Add collection\-side support of the <code>docker</code> action group / module defaults group \([https\://github\.com/ansible\-collections/community\.docker/pull/17](https\://github\.com/ansible\-collections/community\.docker/pull/17)\)\.
@@ -1373,14 +1463,14 @@ This is the first production \(non\-prerelease\) release of <code>community\.doc
<a id="v0-1-0"></a>
## v0\.1\.0
-<a id="release-summary-57"></a>
+<a id="release-summary-61"></a>
### Release Summary
The <code>community\.docker</code> continues the work on the Ansible docker modules and plugins from their state in <code>community\.general</code> 1\.2\.0\. The changes listed here are thus relative to the modules and plugins <code>community\.general\.docker\*</code>\.
All deprecation removals planned for <code>community\.general</code> 2\.0\.0 have been applied\. All deprecation removals scheduled for <code>community\.general</code> 3\.0\.0 have been re\-scheduled for <code>community\.docker</code> 2\.0\.0\.
-<a id="minor-changes-29"></a>
+<a id="minor-changes-30"></a>
### Minor Changes
* docker\_container \- now supports the <code>device\_requests</code> option\, which allows to request additional resources such as GPUs \([https\://github\.com/ansible/ansible/issues/65748](https\://github\.com/ansible/ansible/issues/65748)\, [https\://github\.com/ansible\-collections/community\.general/pull/1119](https\://github\.com/ansible\-collections/community\.general/pull/1119)\)\.
@@ -1411,7 +1501,7 @@ All deprecation removals planned for <code>community\.general</code> 2\.0\.0 hav
* docker\_volume \- no longer returns <code>ansible\_facts</code> \([https\://github\.com/ansible\-collections/community\.docker/pull/1](https\://github\.com/ansible\-collections/community\.docker/pull/1)\)\.
* docker\_volume \- the <code>force</code> option has been removed\. Use <code>recreate</code> instead \([https\://github\.com/ansible\-collections/community\.docker/pull/1](https\://github\.com/ansible\-collections/community\.docker/pull/1)\)\.
-<a id="bugfixes-44"></a>
+<a id="bugfixes-47"></a>
### Bugfixes
* docker\_login \- fix internal config file storage to handle credentials for more than one registry \([https\://github\.com/ansible\-collections/community\.general/issues/1117](https\://github\.com/ansible\-collections/community\.general/issues/1117)\)\.
diff --git a/ansible_collections/community/docker/CHANGELOG.rst b/ansible_collections/community/docker/CHANGELOG.rst
index 1e2ef58a6..dff8b150b 100644
--- a/ansible_collections/community/docker/CHANGELOG.rst
+++ b/ansible_collections/community/docker/CHANGELOG.rst
@@ -4,6 +4,82 @@ Docker Community Collection Release Notes
.. contents:: Topics
+v3.10.3
+=======
+
+Release Summary
+---------------
+
+Bugfix release.
+
+Bugfixes
+--------
+
+- docker and nsenter connection plugins, docker_container_exec module - avoid using the deprecated ``ansible.module_utils.compat.selectors`` module util with Python 3 (https://github.com/ansible-collections/community.docker/issues/870, https://github.com/ansible-collections/community.docker/pull/871).
+
+v3.10.2
+=======
+
+Release Summary
+---------------
+
+Bugfix release.
+
+Bugfixes
+--------
+
+- vendored Docker SDK for Python - include a fix requests 2.32.2+ compatibility (https://github.com/ansible-collections/community.docker/issues/860, https://github.com/psf/requests/issues/6707, https://github.com/ansible-collections/community.docker/pull/864).
+
+v3.10.1
+=======
+
+Release Summary
+---------------
+
+Hotfix release for requests 2.32.0 compatibility.
+
+Bugfixes
+--------
+
+- vendored Docker SDK for Python - include a hotfix for requests 2.32.0 compatibility (https://github.com/ansible-collections/community.docker/issues/860, https://github.com/docker/docker-py/issues/3256, https://github.com/ansible-collections/community.docker/pull/861).
+
+Known Issues
+------------
+
+- Please note that the fix for requests 2.32.0 included in community.docker 3.10.1 only
+ fixes problems with the *vendored* Docker SDK for Python code. Modules and plugins that
+ use Docker SDK for Python can still fail due to the SDK currently being incompatible
+ with requests 2.32.0.
+
+ If you still experience problems with requests 2.32.0, such as error messages like
+ ``Not supported URL scheme http+docker``, please restrict requests to ``<2.32.0``.
+
+v3.10.0
+=======
+
+Release Summary
+---------------
+
+Feature release.
+
+Minor Changes
+-------------
+
+- docker_container - adds ``healthcheck.start_interval`` to support healthcheck start interval setting on containers (https://github.com/ansible-collections/community.docker/pull/848).
+- docker_container - adds ``healthcheck.test_cli_compatible`` to allow omit test option on containers without remove existing image test (https://github.com/ansible-collections/community.docker/pull/847).
+- docker_image_build - add ``outputs`` option to allow configuring outputs for the build (https://github.com/ansible-collections/community.docker/pull/852).
+- docker_image_build - add ``secrets`` option to allow passing secrets to the build (https://github.com/ansible-collections/community.docker/pull/852).
+- docker_image_build - allow ``platform`` to be a list of platforms instead of only a single platform for multi-platform builds (https://github.com/ansible-collections/community.docker/pull/852).
+- docker_network - adds ``config_only`` and ``config_from`` to support creating and using config only networks (https://github.com/ansible-collections/community.docker/issues/395).
+- docker_prune - add new options ``builder_cache_all``, ``builder_cache_filters``, and ``builder_cache_keep_storage``, and a new return value ``builder_cache_caches_deleted`` for pruning build caches (https://github.com/ansible-collections/community.docker/issues/844, https://github.com/ansible-collections/community.docker/issues/845).
+- docker_swarm_service - adds ``sysctls`` to support sysctl settings on swarm services (https://github.com/ansible-collections/community.docker/issues/190).
+
+Deprecated Features
+-------------------
+
+- docker_compose - the Docker Compose v1 module is deprecated and will be removed from community.docker 4.0.0. Please migrate to the ``community.docker.docker_compose_v2`` module, which works with Docker Compose v2 (https://github.com/ansible-collections/community.docker/issues/823, https://github.com/ansible-collections/community.docker/pull/833).
+- various modules and plugins - the ``ssl_version`` option has been deprecated and will be removed from community.docker 4.0.0. It has already been removed from Docker SDK for Python 7.0.0, and was only necessary in the past to work around SSL/TLS issues (https://github.com/ansible-collections/community.docker/pull/853).
+
v3.9.0
======
@@ -93,7 +169,7 @@ Bugfixes
New Modules
-----------
-- docker_image_export - Export (archive) Docker images
+- community.docker.docker_image_export - Export (archive) Docker images
v3.6.0
======
@@ -137,13 +213,13 @@ Bugfixes
New Modules
-----------
-- docker_compose_v2 - Manage multi-container Docker applications with Docker Compose CLI plugin
-- docker_compose_v2_pull - Pull a Docker compose project
-- docker_image_build - Build Docker images using Docker buildx
-- docker_image_pull - Pull Docker images from registries
-- docker_image_push - Push Docker images to registries
-- docker_image_remove - Remove Docker images
-- docker_image_tag - Tag Docker images with new names and/or tags
+- community.docker.docker_compose_v2 - Manage multi-container Docker applications with Docker Compose CLI plugin
+- community.docker.docker_compose_v2_pull - Pull a Docker compose project
+- community.docker.docker_image_build - Build Docker images using Docker buildx
+- community.docker.docker_image_pull - Pull Docker images from registries
+- community.docker.docker_image_push - Push Docker images to registries
+- community.docker.docker_image_remove - Remove Docker images
+- community.docker.docker_image_tag - Tag Docker images with new names and/or tags
v3.5.0
======
@@ -359,7 +435,7 @@ Bugfixes
New Modules
-----------
-- docker_container_copy_into - Copy a file into a Docker container
+- community.docker.docker_container_copy_into - Copy a file into a Docker container
v3.3.2
======
@@ -870,7 +946,7 @@ New Plugins
Connection
~~~~~~~~~~
-- nsenter - execute on host running controller container
+- community.docker.nsenter - execute on host running controller container
v1.8.0
======
@@ -967,7 +1043,7 @@ Bugfixes
New Modules
-----------
-- docker_container_exec - Execute command in a docker container
+- community.docker.docker_container_exec - Execute command in a docker container
v1.4.0
======
@@ -1026,8 +1102,8 @@ Bugfixes
New Modules
-----------
-- docker_image_load - Load docker image(s) from archives
-- docker_plugin - Manage Docker plugins
+- community.docker.docker_image_load - Load docker image(s) from archives
+- community.docker.docker_plugin - Manage Docker plugins
v1.2.2
======
@@ -1107,17 +1183,17 @@ New Plugins
Connection
~~~~~~~~~~
-- docker_api - Run tasks in docker containers
+- community.docker.docker_api - Run tasks in docker containers
Inventory
~~~~~~~~~
-- docker_containers - Ansible dynamic inventory plugin for Docker containers.
+- community.docker.docker_containers - Ansible dynamic inventory plugin for Docker containers.
New Modules
-----------
-- current_container_facts - Return facts about whether the module runs in a Docker container
+- community.docker.current_container_facts - Return facts about whether the module runs in a Docker container
v1.0.1
======
diff --git a/ansible_collections/community/docker/FILES.json b/ansible_collections/community/docker/FILES.json
index da52548f1..c2f6a28c3 100644
--- a/ansible_collections/community/docker/FILES.json
+++ b/ansible_collections/community/docker/FILES.json
@@ -109,7 +109,7 @@
"name": ".azure-pipelines/azure-pipelines.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "84dc585b738c2bfea68ee8e9cd6d4417f36627bd96a67f92b6f8073449b2d7af",
+ "chksum_sha256": "eed726931f1b030bc5f6c4165c0251704a098760de49fe58cad4c56aa91522e0",
"format": 1
},
{
@@ -130,7 +130,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4082845558609060198c2628d77b14eb18b28f48faf0fc08116fee817b4e056c",
+ "chksum_sha256": "b36f9ccf4acf3c6d9358268de4c973d43406516c7f2b09f4303fa7c9672ae69a",
"format": 1
},
{
@@ -242,7 +242,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d3068c91410e1c891056bfdefa3812fb91ed3ccd41fe97b6aaa428debcd5b663",
+ "chksum_sha256": "e678850bfb28299b51297b445b2319e25d84b492364f236ee0154baefcb7d8ce",
"format": 1
},
{
@@ -256,7 +256,7 @@
"name": "changelogs/config.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "89ca51ecae2759b4987976d346e16fa930be4a4e05062a1385764626e3aca951",
+ "chksum_sha256": "21105a71a6783da90a5b108563acfeadf066ef571db64d0d36d55c5886ba1dcd",
"format": 1
},
{
@@ -284,7 +284,7 @@
"name": "docs/docsite/rst/scenario_guide.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b7460de972dad8dba6ffbaacd46a84f2b673a74e78f5eb3db617fd3eb574ba6d",
+ "chksum_sha256": "dcbef6d865e38902c5a8b88e7bddf940f62cf31067f29cd041a215cd6a0a6f19",
"format": 1
},
{
@@ -340,7 +340,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "edcb1bfa37eaf30f16b8a081dcd80ac6406972a894d4f3f5f7fd320e4f309c38",
+ "chksum_sha256": "9c6256715af06a03c0a93beac94757d47be3b0125ccce5d874ffd9227890d09f",
"format": 1
},
{
@@ -375,21 +375,21 @@
"name": "plugins/connection/docker.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "499dc980904433196409bc04a10faf38801123c8a22871026037f4bad6d13bab",
+ "chksum_sha256": "4d013442683d88f48c73695a8cf5d6acb11b4528db1d195c41209a641dd9ebda",
"format": 1
},
{
"name": "plugins/connection/docker_api.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "eb3275f36134a45b5acc0620f5b0b849c9cde8cf1975c7cd45b683d56e2e4258",
+ "chksum_sha256": "f04f25bf107d119641444104cf76284c7bb42d6407de0b881eb5b554ae147edd",
"format": 1
},
{
"name": "plugins/connection/nsenter.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2f246a2f8dcb35feb42d2a1d7f28ead845ae4854da097781489233f5a5920e94",
+ "chksum_sha256": "0b3e97b145df0862f75ea03ead386929d6e4faae67123e0421b19a2fa3575347",
"format": 1
},
{
@@ -417,7 +417,7 @@
"name": "plugins/doc_fragments/docker.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "89dae4973d0a843ba52d8ac81197045dcdc136df4ca685210efe815366dbb70f",
+ "chksum_sha256": "15bc8148d241ed95343e15632933a9d6d15b53d690c2f1b7b8a0d7cf56c2adc2",
"format": 1
},
{
@@ -431,7 +431,7 @@
"name": "plugins/inventory/docker_containers.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a4feea030c92ca0b3541d679ad49ae060430c0f5a3994fb589485a330613941a",
+ "chksum_sha256": "a4571bbd61633d474b092157351d19ce4ca99893402cb9bfeb316e03427eb357",
"format": 1
},
{
@@ -445,7 +445,7 @@
"name": "plugins/inventory/docker_swarm.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "04e5cf494bac339905130787fbdfe0ca23ab7caad8fec2f784d014937f86eeb1",
+ "chksum_sha256": "73d1a797b773c037c755480b245ad7cfc11b6eb7310c1f015c52729c4e842dab",
"format": 1
},
{
@@ -529,7 +529,7 @@
"name": "plugins/module_utils/_api/transport/basehttpadapter.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "73da87364c86548cdf16f52608349443f02f9926b52e736649a417f1238376ea",
+ "chksum_sha256": "2e88df15eeb6be839c78e777bc093d3f2c727b185395d2616d0cd6d92a4675f5",
"format": 1
},
{
@@ -697,14 +697,14 @@
"name": "plugins/module_utils/module_container/base.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3ef56885b8746ef1ae068412cd9a608dcb83f5b7aa06670d5ae6216aa845a940",
+ "chksum_sha256": "3a1b4d8958005daf4724c037e7419ddbba384eda142a55c6088f5045617f2672",
"format": 1
},
{
"name": "plugins/module_utils/module_container/docker_api.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2d0e757e6b3439e7445531b1be278c283e2a442747f86f51ef831739ddf158c5",
+ "chksum_sha256": "c21b7f1c3d8e1d188ffec2b460589da857ec44d550874f0fb7016e083e7071c2",
"format": 1
},
{
@@ -778,6 +778,13 @@
"format": 1
},
{
+ "name": "plugins/module_utils/selectors.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a48ff68d6dd79eb5d9509e3acae79a6179c9646c51654108ca6873d1eafdb817",
+ "format": 1
+ },
+ {
"name": "plugins/module_utils/socket_handler.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -802,7 +809,7 @@
"name": "plugins/module_utils/util.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cd9d4863ea58408543821688b7093aed25a1323109de82c13c8489f6cd45651a",
+ "chksum_sha256": "b300136bb10e2a9a51862b6b10eb5ce9032c551a13cebba97200ccb501e1a450",
"format": 1
},
{
@@ -830,7 +837,7 @@
"name": "plugins/modules/docker_compose.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ae76fdb37a3517ffcdc50047d900d33a94a9c5e85dcc76ebdd1bbc6dfa9c3b8b",
+ "chksum_sha256": "973b8aee68fcb76dd620c243904c64dee7f234ca1f69019b87c83ca72a8efc48",
"format": 1
},
{
@@ -858,7 +865,7 @@
"name": "plugins/modules/docker_container.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "20ff6513c8c1d81c477c58c1cbe943e383005bcf8c110cfb3b58f96240339da7",
+ "chksum_sha256": "24722b19a3ea8c32bdade25e9f5e061ede3fed5bb01c3db238a5cb45e28b2a1b",
"format": 1
},
{
@@ -872,7 +879,7 @@
"name": "plugins/modules/docker_container_exec.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "088ebb7b7c11d7d7ee8a9e30a9813dc7acfd0bac32782a8a128ac3fe613ab797",
+ "chksum_sha256": "9828790f19f268519de01fa41df37adf89f5a6af88438b4dab5fd225b7a68a88",
"format": 1
},
{
@@ -900,7 +907,7 @@
"name": "plugins/modules/docker_image_build.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0c56e7842f5681b3ca5081ee263fc33ee2a677ce07d19407c04be97f66352720",
+ "chksum_sha256": "ced5bedc7d1ad287717dc2ea39357db5ca584973d04b4f2225180c8fd20ece22",
"format": 1
},
{
@@ -963,7 +970,7 @@
"name": "plugins/modules/docker_network.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d8f6a678e09487346b7ab007dcef3d8c5cb494ede7ccadc43be42c205902de40",
+ "chksum_sha256": "f0b7ab1dd6aac89762fd6ab9b30267eb48bb0906ade41805ff5df79d5e3685c0",
"format": 1
},
{
@@ -998,7 +1005,7 @@
"name": "plugins/modules/docker_prune.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "83107f0243ee1c6706686da15f65e8aa2e5fc96e0d346934210557a97ca38292",
+ "chksum_sha256": "57a0ca1bfd08ac4f16afcaf8a925697bd8cd53a4aa33d1c07b53992174e3eeab",
"format": 1
},
{
@@ -1047,7 +1054,7 @@
"name": "plugins/modules/docker_swarm_service.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a123422ef5020a31efc1f19872e62bd1374af3352640a62df3f01dc8a4c0a3df",
+ "chksum_sha256": "355ed4ec943f881394333a58cc442803c36c85c0e2232374bc9970be977444bd",
"format": 1
},
{
@@ -1096,7 +1103,7 @@
"name": "plugins/plugin_utils/socket_handler.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "35cd4e8636a9d7bc209996b7a384c183f14f205485939744d2164d86a70c8e9b",
+ "chksum_sha256": "56157c15e13defbde6a392ba2804bdb2734316d559c2e61c08361d65deae3ae0",
"format": 1
},
{
@@ -1586,7 +1593,7 @@
"name": "tests/integration/targets/docker_compose_v2/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "375f957e7348b7c72fac3e7ce7634b9424daf98122537ff7b803b56aa4b3079d",
+ "chksum_sha256": "c2a2b069e45658c6089293227752efeb565e01191414706424ce74de797120f2",
"format": 1
},
{
@@ -1649,7 +1656,7 @@
"name": "tests/integration/targets/docker_compose_v2_pull/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "375f957e7348b7c72fac3e7ce7634b9424daf98122537ff7b803b56aa4b3079d",
+ "chksum_sha256": "8e6319cebc310a53e60a30c57416f87baf55918cb8264ae0cf1a070821cb63ba",
"format": 1
},
{
@@ -2237,7 +2244,7 @@
"name": "tests/integration/targets/docker_image_build/tasks/tests/options.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "175cbbaf36639ee9c054d814400835d571416b48df606c9ed7ccaf009f98032c",
+ "chksum_sha256": "8fe987d38f4065b152a05d845709946504903321342d99184c10aa7cf86ae74b",
"format": 1
},
{
@@ -2258,7 +2265,7 @@
"name": "tests/integration/targets/docker_image_build/tasks/test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d96b8ee07ced0cad104066cce1c1ccbd8569008924dc2669c43f363dcfec9c6f",
+ "chksum_sha256": "4ee523d71f919551cb6c11ae760fe05d24990867ab5a08be86e554a3a8fed861",
"format": 1
},
{
@@ -2297,6 +2304,13 @@
"format": 1
},
{
+ "name": "tests/integration/targets/docker_image_build/templates/SecretsDockerfile",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d65014cfb0da5082a68731d539360be8b0e522df6da3d8054dfa216910ba63a6",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/docker_image_build/templates/StagedDockerfile",
"ftype": "file",
"chksum_type": "sha256",
@@ -3147,7 +3161,7 @@
"name": "tests/integration/targets/docker_prune/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "277ac80b8d8597c2654bac67cd19434f0c478efe5f97cd341a5c90e1214c0463",
+ "chksum_sha256": "e1128cf980ee7ef055acc2d4e41f36e4b7d798f6e73a22ba34f3be0b261b2ca1",
"format": 1
},
{
@@ -3763,7 +3777,7 @@
"name": "tests/integration/targets/docker_swarm_service/vars/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fe5d12fec25ef974db885fd92993fc20baf102c5db843c58dd4263fc80c46ccf",
+ "chksum_sha256": "380d6716f8abcfa414e9174dffc3bb2b86aafc97ec7594f473b2ac1a3ffa9974",
"format": 1
},
{
@@ -3987,7 +4001,7 @@
"name": "tests/integration/targets/generic_connection_tests/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "880a774a7c576b4d4f18dc7308387997278fadb052687da474dfe4c060922cff",
+ "chksum_sha256": "da42f5ed16ff85517f2feb4316aa384d68c3a69f1ba3b3402b472ebc5b771f43",
"format": 1
},
{
@@ -4442,7 +4456,7 @@
"name": "tests/integration/targets/setup_docker/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3e5d213ee69aa2b33302bc83ce9d56fde52956a4070fde9c3e2de3c7564ad88c",
+ "chksum_sha256": "55ce15cf1ed1c55a7819cccd60385f8368b79ee831c8c458fab6eaef4d4f7f28",
"format": 1
},
{
@@ -4736,7 +4750,7 @@
"name": "tests/integration/targets/setup_docker_cli_compose/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4c8d8ec38064dacd5357eee4cab893855454ebe75e9f30c638071735a596776e",
+ "chksum_sha256": "574619bac82e7a65751db428c58b2c44a12e827c723289dc0dcaaef2a97867cf",
"format": 1
},
{
@@ -4883,7 +4897,7 @@
"name": "tests/integration/targets/setup_docker_compose_v1/vars/Alpine.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0554ad7767703892ec32552f8d6119dcc9015f694aa90e4aa4dc4d65a069840e",
+ "chksum_sha256": "95ea3c984062c116932d4d4608d7f25d9e0f9a328c98b5be8ff135ccf3c9ffc7",
"format": 1
},
{
@@ -5814,7 +5828,7 @@
"name": "tests/sanity/ignore-2.11.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9a24bca3a941c3895d8443f5467ad500972776bf79973430315dc60666ca395d",
+ "chksum_sha256": "9e75ee9b11ed3f5847b55c01cf200d637634bb9a81a8dcfa491bf100ac21d1e2",
"format": 1
},
{
@@ -5828,7 +5842,7 @@
"name": "tests/sanity/ignore-2.12.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "253e2f40d466107ec1ec5ec4a936056f7a25a47c9eff9c1541faed239e954847",
+ "chksum_sha256": "8c94911e1d8e017201a95be684853df3667c9c2dcbd5a8b975925abbccb411f2",
"format": 1
},
{
@@ -5842,7 +5856,7 @@
"name": "tests/sanity/ignore-2.13.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7633370c8868422bb5746752325d5799c4054b89347bfe284a5d562f1aa1ca75",
+ "chksum_sha256": "6d447377ca8ae39bbcce6dd990637444a59444529537371720003f13da4f5fd4",
"format": 1
},
{
@@ -5856,7 +5870,7 @@
"name": "tests/sanity/ignore-2.14.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ccc7d836b365401a29253c3db1fef85f976a8977eb57332de1136187ac45f39a",
+ "chksum_sha256": "66b5d2222c0ea982efa4ccbc5fffad980cfbc17001a6cf39b072297715cc22b8",
"format": 1
},
{
@@ -5870,7 +5884,7 @@
"name": "tests/sanity/ignore-2.15.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ccc7d836b365401a29253c3db1fef85f976a8977eb57332de1136187ac45f39a",
+ "chksum_sha256": "66b5d2222c0ea982efa4ccbc5fffad980cfbc17001a6cf39b072297715cc22b8",
"format": 1
},
{
@@ -5884,7 +5898,7 @@
"name": "tests/sanity/ignore-2.16.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "77e2580c039e9062bb354b79bad043392a7e343f11e1797b35b3d28b6955de79",
+ "chksum_sha256": "6a8d217bd175553fa6b355e3a2ce4d891d6593ffcacc639d44f6c84a45feaaa1",
"format": 1
},
{
@@ -6252,6 +6266,20 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/plugin_utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/plugin_utils/test_unsafe.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1568c3ce2e4607a182d8fcafd8d70a78000eec9bd4577ac943af0ab09ef30243",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/test_support",
"ftype": "dir",
"chksum_type": null,
@@ -6388,7 +6416,7 @@
"name": "CHANGELOG.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b7838b371ac49712b398b2cc47e2959e020fbe727275fc1052c8e49489bc3596",
+ "chksum_sha256": "42e61d2b2354fbf9c5f2da9873c0477a1c16afede7b23e7fa222f25a158f7590",
"format": 1
},
{
@@ -6402,7 +6430,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8593cb523e7f0bfece19e9dd82a25d06277269451d1334d15c15a868272bcb63",
+ "chksum_sha256": "5f823c49d14587f6dfa983c8f2359a9a5ff36e0e34c73615f01eb6504d9d0f9b",
"format": 1
},
{
@@ -6423,7 +6451,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "18391f2b88eae674b860ad2cd1ac1426dc64299c91965aa4d30b69ff269aac5f",
+ "chksum_sha256": "12a411f378daee55c2ac25a7a41f2ee0884183830ff2df254a54ebe58f188c62",
"format": 1
}
],
diff --git a/ansible_collections/community/docker/MANIFEST.json b/ansible_collections/community/docker/MANIFEST.json
index 447bfc1ce..69ffc1b62 100644
--- a/ansible_collections/community/docker/MANIFEST.json
+++ b/ansible_collections/community/docker/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "docker",
- "version": "3.9.0",
+ "version": "3.10.3",
"authors": [
"Ansible Docker Working Group"
],
@@ -28,7 +28,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f1b0cee31d5d2e869134e845593489c03632024171cd300f35688fb089e7bf2d",
+ "chksum_sha256": "c5b11456e6a1ea1ee5144451aa5a1c46f7f835b3102db5ad06d16a005b4af551",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/docker/README.md b/ansible_collections/community/docker/README.md
index 0d169c54a..2a2a9cc3f 100644
--- a/ansible_collections/community/docker/README.md
+++ b/ansible_collections/community/docker/README.md
@@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
[![Doc](https://img.shields.io/badge/docs-brightgreen.svg)](https://docs.ansible.com/ansible/latest/collections/community/docker/)
[![Build Status](https://dev.azure.com/ansible/community.docker/_apis/build/status/CI?branchName=main)](https://dev.azure.com/ansible/community.docker/_build?definitionId=25)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.docker)](https://codecov.io/gh/ansible-collections/community.docker)
+[![REUSE status](https://api.reuse.software/badge/github.com/ansible-collections/community.docker)](https://api.reuse.software/info/github.com/ansible-collections/community.docker)
This repo contains the `community.docker` Ansible Collection. The collection includes many modules and plugins to work with Docker.
@@ -78,7 +79,7 @@ If you use the Ansible package and do not update collections independently, use
- community.docker.docker_volume: manage Docker volumes
- community.docker.docker_volume_info: retrieve information on Docker volumes
* Docker Compose:
- - community.docker.docker_compose: manage Docker Compose files (legacy Docker Compose v1)
+ - community.docker.docker_compose: manage Docker Compose files (legacy Docker Compose v1; the module is deprecated and will be removed from community.docker 4.0.0)
- community.docker.docker_compose_v2: manage Docker Compose files (Docker compose CLI plugin)
- community.docker.docker_compose_v2_pull: pull a Docker compose project
* Docker Swarm:
diff --git a/ansible_collections/community/docker/changelogs/changelog.yaml b/ansible_collections/community/docker/changelogs/changelog.yaml
index fc22ba446..ba40629e7 100644
--- a/ansible_collections/community/docker/changelogs/changelog.yaml
+++ b/ansible_collections/community/docker/changelogs/changelog.yaml
@@ -1002,6 +1002,102 @@ releases:
- 466-add-data-path-port.yml
- licenses.yml
release_date: '2022-09-08'
+ 3.10.0:
+ changes:
+ deprecated_features:
+ - docker_compose - the Docker Compose v1 module is deprecated and will be removed
+ from community.docker 4.0.0. Please migrate to the ``community.docker.docker_compose_v2``
+ module, which works with Docker Compose v2 (https://github.com/ansible-collections/community.docker/issues/823,
+ https://github.com/ansible-collections/community.docker/pull/833).
+ - various modules and plugins - the ``ssl_version`` option has been deprecated
+ and will be removed from community.docker 4.0.0. It has already been removed
+ from Docker SDK for Python 7.0.0, and was only necessary in the past to work
+ around SSL/TLS issues (https://github.com/ansible-collections/community.docker/pull/853).
+ minor_changes:
+ - docker_container - adds ``healthcheck.start_interval`` to support healthcheck
+ start interval setting on containers (https://github.com/ansible-collections/community.docker/pull/848).
+ - docker_container - adds ``healthcheck.test_cli_compatible`` to allow omit
+ test option on containers without remove existing image test (https://github.com/ansible-collections/community.docker/pull/847).
+ - docker_image_build - add ``outputs`` option to allow configuring outputs for
+ the build (https://github.com/ansible-collections/community.docker/pull/852).
+ - docker_image_build - add ``secrets`` option to allow passing secrets to the
+ build (https://github.com/ansible-collections/community.docker/pull/852).
+ - docker_image_build - allow ``platform`` to be a list of platforms instead
+ of only a single platform for multi-platform builds (https://github.com/ansible-collections/community.docker/pull/852).
+ - docker_network - adds ``config_only`` and ``config_from`` to support creating
+ and using config only networks (https://github.com/ansible-collections/community.docker/issues/395).
+ - docker_prune - add new options ``builder_cache_all``, ``builder_cache_filters``,
+ and ``builder_cache_keep_storage``, and a new return value ``builder_cache_caches_deleted``
+ for pruning build caches (https://github.com/ansible-collections/community.docker/issues/844,
+ https://github.com/ansible-collections/community.docker/issues/845).
+ - docker_swarm_service - adds ``sysctls`` to support sysctl settings on swarm
+ services (https://github.com/ansible-collections/community.docker/issues/190).
+ release_summary: Feature release.
+ fragments:
+ - 3.10.0.yml
+ - 836-docker_swarm_service-sysctls.yml
+ - 843-docker_network-config-from-config-only.yml
+ - 845-docker_prune.yml
+ - 847-docker_container-heackcheck-test_cli_compatible.yml
+ - 848-docker_api-healthcheck-start-interval.yml
+ - 852-docker_image_build.yml
+ - 853-ssl_version.yml
+ - deprecate-compose-v1.yml
+ release_date: '2024-05-19'
+ 3.10.1:
+ changes:
+ bugfixes:
+ - vendored Docker SDK for Python - include a hotfix for requests 2.32.0 compatibility
+ (https://github.com/ansible-collections/community.docker/issues/860, https://github.com/docker/docker-py/issues/3256,
+ https://github.com/ansible-collections/community.docker/pull/861).
+ known_issues:
+ - 'Please note that the fix for requests 2.32.0 included in community.docker
+ 3.10.1 only
+
+ fixes problems with the *vendored* Docker SDK for Python code. Modules and
+ plugins that
+
+ use Docker SDK for Python can still fail due to the SDK currently being incompatible
+
+ with requests 2.32.0.
+
+
+ If you still experience problems with requests 2.32.0, such as error messages
+ like
+
+ ``Not supported URL scheme http+docker``, please restrict requests to ``<2.32.0``.
+
+ '
+ release_summary: 'Hotfix release for requests 2.32.0 compatibility.
+
+ '
+ fragments:
+ - 3.10.1.yml
+ - 862-requests.yml
+ release_date: '2024-05-20'
+ 3.10.2:
+ changes:
+ bugfixes:
+ - vendored Docker SDK for Python - include a fix requests 2.32.2+ compatibility
+ (https://github.com/ansible-collections/community.docker/issues/860, https://github.com/psf/requests/issues/6707,
+ https://github.com/ansible-collections/community.docker/pull/864).
+ release_summary: Bugfix release.
+ fragments:
+ - 3.10.2.yml
+ - 864-requests.yml
+ release_date: '2024-05-21'
+ 3.10.3:
+ changes:
+ bugfixes:
+ - docker and nsenter connection plugins, docker_container_exec module - avoid
+ using the deprecated ``ansible.module_utils.compat.selectors`` module util
+ with Python 3 (https://github.com/ansible-collections/community.docker/issues/870,
+ https://github.com/ansible-collections/community.docker/pull/871).
+ release_summary: Bugfix release.
+ fragments:
+ - 3.10.3.yml
+ - 871-selectors.yml
+ release_date: '2024-05-26'
3.2.0:
changes:
deprecated_features:
diff --git a/ansible_collections/community/docker/changelogs/config.yaml b/ansible_collections/community/docker/changelogs/config.yaml
index 1fd1d794d..2959c161e 100644
--- a/ansible_collections/community/docker/changelogs/config.yaml
+++ b/ansible_collections/community/docker/changelogs/config.yaml
@@ -35,3 +35,5 @@ sections:
- Known Issues
title: Docker Community Collection
trivial_section_name: trivial
+use_fqcn: true
+add_plugin_period: true
diff --git a/ansible_collections/community/docker/docs/docsite/rst/scenario_guide.rst b/ansible_collections/community/docker/docs/docsite/rst/scenario_guide.rst
index 203aa57d2..395b71003 100644
--- a/ansible_collections/community/docker/docs/docsite/rst/scenario_guide.rst
+++ b/ansible_collections/community/docker/docs/docsite/rst/scenario_guide.rst
@@ -272,12 +272,13 @@ No further requirements next to to the CLI tool and its Docker Compose plugin ar
Docker Compose v1
.................
-The :ansplugin:`community.docker.docker_compose module <community.docker.docker_compose#module>`
+The deprecated :ansplugin:`community.docker.docker_compose module <community.docker.docker_compose#module>`
allows you to use your existing Docker compose files to orchestrate containers on a single Docker daemon or on Swarm.
This module uses the out-dated and End of Life version 1.x of Docker Compose. It should mainly be used for legacy systems
-which still have to use that version of Docker Compose.
+which still have to use that version of Docker Compose. **The module is deprecated and will be removed from community.docker 4.0.0.**
+Please use the Docker Compose v2 modules instead.
-You need to install the `old Python docker-compose <https://pypi.org/project/docker-compose/>`_ on the remote machines to use the module.
+You need to install the `old Python docker-compose <https://pypi.org/project/docker-compose/>`_ on the remote machines to use the Docker Compose v1 module.
Docker Machine
diff --git a/ansible_collections/community/docker/meta/runtime.yml b/ansible_collections/community/docker/meta/runtime.yml
index 0ddd09fa3..e29f84be1 100644
--- a/ansible_collections/community/docker/meta/runtime.yml
+++ b/ansible_collections/community/docker/meta/runtime.yml
@@ -41,3 +41,10 @@ action_groups:
- docker_swarm_service_info
- docker_volume
- docker_volume_info
+
+plugin_routing:
+ modules:
+ docker_compose:
+ deprecation:
+ removal_version: 4.0.0
+ warning_text: This module uses docker-compose v1, which is End of Life since July 2022. Please migrate to community.docker.docker_compose_v2.
diff --git a/ansible_collections/community/docker/plugins/connection/docker.py b/ansible_collections/community/docker/plugins/connection/docker.py
index 68247dae2..133fe6a75 100644
--- a/ansible_collections/community/docker/plugins/connection/docker.py
+++ b/ansible_collections/community/docker/plugins/connection/docker.py
@@ -83,7 +83,6 @@ import os.path
import subprocess
import re
-from ansible.compat import selectors
from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils.common.process import get_bin_path
@@ -91,6 +90,7 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_
from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.utils.display import Display
+from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
display = Display()
diff --git a/ansible_collections/community/docker/plugins/connection/docker_api.py b/ansible_collections/community/docker/plugins/connection/docker_api.py
index 3b99281c3..a6dec85aa 100644
--- a/ansible_collections/community/docker/plugins/connection/docker_api.py
+++ b/ansible_collections/community/docker/plugins/connection/docker_api.py
@@ -21,6 +21,7 @@ notes:
with Python's C(SSLSocket)s. See U(https://github.com/ansible-collections/community.docker/issues/605) for more information.
extends_documentation_fragment:
- community.docker.docker.api_documentation
+ - community.docker.docker.ssl_version_deprecation
- community.docker.docker.var_names
options:
remote_user:
diff --git a/ansible_collections/community/docker/plugins/connection/nsenter.py b/ansible_collections/community/docker/plugins/connection/nsenter.py
index f429f8cef..ccc660b99 100644
--- a/ansible_collections/community/docker/plugins/connection/nsenter.py
+++ b/ansible_collections/community/docker/plugins/connection/nsenter.py
@@ -50,13 +50,15 @@ import fcntl
import ansible.constants as C
from ansible.errors import AnsibleError
-from ansible.module_utils.compat import selectors
from ansible.module_utils.six import binary_type, text_type
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible.plugins.connection import ConnectionBase
from ansible.utils.display import Display
from ansible.utils.path import unfrackpath
+from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
+
+
display = Display()
diff --git a/ansible_collections/community/docker/plugins/doc_fragments/docker.py b/ansible_collections/community/docker/plugins/doc_fragments/docker.py
index 92989a97b..2c78c5fae 100644
--- a/ansible_collections/community/docker/plugins/doc_fragments/docker.py
+++ b/ansible_collections/community/docker/plugins/doc_fragments/docker.py
@@ -392,3 +392,12 @@ notes:
- This module does B(not) use the L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) to
communicate with the Docker daemon. It directly calls the Docker CLI program.
'''
+
+ # DEPRECATED: this will be removed from community.docker 4.0.0! Use with care!
+ SSL_VERSION_DEPRECATION = '''
+options:
+ ssl_version:
+ deprecated:
+ why: This was necessary a long time ago to handle problems with older TLS/SSL versions. It is no longer necessary nowadays.
+ version: 4.0.0
+'''
diff --git a/ansible_collections/community/docker/plugins/inventory/docker_containers.py b/ansible_collections/community/docker/plugins/inventory/docker_containers.py
index 0cae05472..f353b03bd 100644
--- a/ansible_collections/community/docker/plugins/inventory/docker_containers.py
+++ b/ansible_collections/community/docker/plugins/inventory/docker_containers.py
@@ -21,6 +21,7 @@ author:
extends_documentation_fragment:
- ansible.builtin.constructed
- community.docker.docker.api_documentation
+ - community.docker.docker.ssl_version_deprecation
- community.library_inventory_filtering_v1.inventory_filter
description:
- Reads inventories from the Docker API.
diff --git a/ansible_collections/community/docker/plugins/inventory/docker_swarm.py b/ansible_collections/community/docker/plugins/inventory/docker_swarm.py
index acceac86c..6d1556ff5 100644
--- a/ansible_collections/community/docker/plugins/inventory/docker_swarm.py
+++ b/ansible_collections/community/docker/plugins/inventory/docker_swarm.py
@@ -78,6 +78,9 @@ DOCUMENTATION = '''
- Provide a valid SSL version number. Default value determined
by L(SSL Python module, https://docs.python.org/3/library/ssl.html).
type: str
+ deprecated:
+ why: This was necessary a long time ago to handle problems with SSL versions. It is no longer necessary nowadays.
+ version: 4.0.0
api_version:
description:
- The version of the Docker API running on the Docker Host.
diff --git a/ansible_collections/community/docker/plugins/module_utils/_api/transport/basehttpadapter.py b/ansible_collections/community/docker/plugins/module_utils/_api/transport/basehttpadapter.py
index 2afa60aea..14062a0ba 100644
--- a/ansible_collections/community/docker/plugins/module_utils/_api/transport/basehttpadapter.py
+++ b/ansible_collections/community/docker/plugins/module_utils/_api/transport/basehttpadapter.py
@@ -18,3 +18,15 @@ class BaseHTTPAdapter(_HTTPAdapter):
super(BaseHTTPAdapter, self).close()
if hasattr(self, 'pools'):
self.pools.clear()
+
+ # Hotfix for requests 2.32.0 and 2.32.1: its commit
+ # https://github.com/psf/requests/commit/c0813a2d910ea6b4f8438b91d315b8d181302356
+ # changes requests.adapters.HTTPAdapter to no longer call get_connection() from
+ # send(), but instead call _get_connection().
+ def _get_connection(self, request, *args, **kwargs):
+ return self.get_connection(request.url, kwargs.get('proxies'))
+
+ # Fix for requests 2.32.2+:
+ # https://github.com/psf/requests/commit/c98e4d133ef29c46a9b68cd783087218a8075e05
+ def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
+ return self.get_connection(request.url, proxies)
diff --git a/ansible_collections/community/docker/plugins/module_utils/module_container/base.py b/ansible_collections/community/docker/plugins/module_utils/module_container/base.py
index 0f776aa5c..410ffb153 100644
--- a/ansible_collections/community/docker/plugins/module_utils/module_container/base.py
+++ b/ansible_collections/community/docker/plugins/module_utils/module_container/base.py
@@ -935,9 +935,11 @@ OPTION_HEALTHCHECK = (
OptionGroup(preprocess=_preprocess_healthcheck)
.add_option('healthcheck', type='dict', ansible_suboptions=dict(
test=dict(type='raw'),
+ test_cli_compatible=dict(type='bool', default=False),
interval=dict(type='str'),
timeout=dict(type='str'),
start_period=dict(type='str'),
+ start_interval=dict(type='str'),
retries=dict(type='int'),
))
)
diff --git a/ansible_collections/community/docker/plugins/module_utils/module_container/docker_api.py b/ansible_collections/community/docker/plugins/module_utils/module_container/docker_api.py
index 61a5500c9..d3da84fe5 100644
--- a/ansible_collections/community/docker/plugins/module_utils/module_container/docker_api.py
+++ b/ansible_collections/community/docker/plugins/module_utils/module_container/docker_api.py
@@ -436,6 +436,7 @@ class DockerAPIEngine(Engine):
min_api_version=None,
preprocess_value=None,
update_parameter=None,
+ extra_option_minimal_versions=None,
):
def preprocess_value_(module, client, api_version, options, values):
if len(options) != 1:
@@ -499,6 +500,7 @@ class DockerAPIEngine(Engine):
set_value=set_value,
min_api_version=min_api_version,
update_value=update_value,
+ extra_option_minimal_versions=extra_option_minimal_versions,
)
@classmethod
@@ -512,6 +514,7 @@ class DockerAPIEngine(Engine):
min_api_version=None,
preprocess_value=None,
update_parameter=None,
+ extra_option_minimal_versions=None,
):
def preprocess_value_(module, client, api_version, options, values):
if len(options) != 1:
@@ -577,6 +580,7 @@ class DockerAPIEngine(Engine):
set_value=set_value,
min_api_version=min_api_version,
update_value=update_value,
+ extra_option_minimal_versions=extra_option_minimal_versions,
)
@@ -742,7 +746,7 @@ def _preprocess_etc_hosts(module, client, api_version, value):
def _preprocess_healthcheck(module, client, api_version, value):
if value is None:
return value
- if not value or not value.get('test'):
+ if not value or not (value.get('test') or (value.get('test_cli_compatible') and value.get('test') is None)):
value = {'test': ['NONE']}
elif 'test' in value:
value['test'] = normalize_healthcheck_test(value['test'])
@@ -751,6 +755,7 @@ def _preprocess_healthcheck(module, client, api_version, value):
'Interval': value.get('interval'),
'Timeout': value.get('timeout'),
'StartPeriod': value.get('start_period'),
+ 'StartInterval': value.get('start_interval'),
'Retries': value.get('retries'),
})
@@ -1300,7 +1305,16 @@ OPTION_ETC_HOSTS.add_engine('docker_api', DockerAPIEngine.host_config_value('Ext
OPTION_GROUPS.add_engine('docker_api', DockerAPIEngine.host_config_value('GroupAdd'))
OPTION_HEALTHCHECK.add_engine('docker_api', DockerAPIEngine.config_value(
- 'Healthcheck', preprocess_value=_preprocess_healthcheck, postprocess_for_get=_postprocess_healthcheck_get_value))
+ 'Healthcheck',
+ preprocess_value=_preprocess_healthcheck,
+ postprocess_for_get=_postprocess_healthcheck_get_value,
+ extra_option_minimal_versions={
+ 'healthcheck.start_interval': {
+ 'docker_api_version': '1.44',
+ 'detect_usage': lambda c: c.module.params['healthcheck'] and c.module.params['healthcheck']['start_interval'] is not None,
+ },
+ },
+))
OPTION_HOSTNAME.add_engine('docker_api', DockerAPIEngine.config_value('Hostname'))
diff --git a/ansible_collections/community/docker/plugins/module_utils/selectors.py b/ansible_collections/community/docker/plugins/module_utils/selectors.py
new file mode 100644
index 000000000..ca52cc877
--- /dev/null
+++ b/ansible_collections/community/docker/plugins/module_utils/selectors.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Provide selectors import."""
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+# Once we drop support for ansible-core 2.16, we can remove the try/except.
+
+from sys import version_info as _python_version_info
+
+
+if _python_version_info < (3, 4):
+ from ansible.module_utils.compat import selectors # noqa: F401, pylint: disable=unused-import
+else:
+ import selectors # noqa: F401, pylint: disable=unused-import
diff --git a/ansible_collections/community/docker/plugins/module_utils/util.py b/ansible_collections/community/docker/plugins/module_utils/util.py
index efd3301f1..9235e34d7 100644
--- a/ansible_collections/community/docker/plugins/module_utils/util.py
+++ b/ansible_collections/community/docker/plugins/module_utils/util.py
@@ -29,7 +29,12 @@ DOCKER_COMMON_ARGS = dict(
ca_path=dict(type='path', aliases=['ca_cert', 'tls_ca_cert', 'cacert_path']),
client_cert=dict(type='path', aliases=['tls_client_cert', 'cert_path']),
client_key=dict(type='path', aliases=['tls_client_key', 'key_path']),
- ssl_version=dict(type='str', fallback=(env_fallback, ['DOCKER_SSL_VERSION'])),
+ ssl_version=dict(
+ type='str',
+ fallback=(env_fallback, ['DOCKER_SSL_VERSION']),
+ removed_in_version='4.0.0',
+ removed_from_collection='community.docker',
+ ),
tls=dict(type='bool', default=DEFAULT_TLS, fallback=(env_fallback, ['DOCKER_TLS'])),
use_ssh_client=dict(type='bool', default=False),
validate_certs=dict(type='bool', default=DEFAULT_TLS_VERIFY, fallback=(env_fallback, ['DOCKER_TLS_VERIFY']), aliases=['tls_verify']),
@@ -348,9 +353,9 @@ def normalize_healthcheck(healthcheck, normalize_test=False):
result = dict()
# All supported healthcheck parameters
- options = ('test', 'interval', 'timeout', 'start_period', 'retries')
+ options = ('test', 'test_cli_compatible', 'interval', 'timeout', 'start_period', 'start_interval', 'retries')
- duration_options = ('interval', 'timeout', 'start_period')
+ duration_options = ('interval', 'timeout', 'start_period', 'start_interval')
for key in options:
if key in healthcheck:
@@ -361,7 +366,7 @@ def normalize_healthcheck(healthcheck, normalize_test=False):
continue
if key in duration_options:
value = convert_duration_to_nanosecond(value)
- if not value:
+ if not value and not (healthcheck.get('test_cli_compatible') and key == 'test'):
continue
if key == 'retries':
try:
@@ -371,7 +376,7 @@ def normalize_healthcheck(healthcheck, normalize_test=False):
'Cannot parse number of retries for healthcheck. '
'Expected an integer, got "{0}".'.format(value)
)
- if key == 'test' and normalize_test:
+ if key == 'test' and value and normalize_test:
value = normalize_healthcheck_test(value)
result[key] = value
diff --git a/ansible_collections/community/docker/plugins/modules/docker_compose.py b/ansible_collections/community/docker/plugins/modules/docker_compose.py
index f8edbee4b..3af3bebb1 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_compose.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_compose.py
@@ -14,6 +14,11 @@ module: docker_compose
short_description: Manage multi-container Docker applications with Docker Compose V1
+deprecated:
+ removed_in: 4.0.0
+ why: This module uses docker-compose v1, which is End of Life since July 2022.
+ alternative: Migrate to M(community.docker.docker_compose_v2)
+
author: "Chris Houseknecht (@chouseknecht)"
description:
diff --git a/ansible_collections/community/docker/plugins/modules/docker_container.py b/ansible_collections/community/docker/plugins/modules/docker_container.py
index d7dbc3780..60768637f 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_container.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_container.py
@@ -369,7 +369,7 @@ options:
- Configure a check that is run to determine whether or not containers for this service are "healthy".
- "See the docs for the L(HEALTHCHECK Dockerfile instruction,https://docs.docker.com/engine/reference/builder/#healthcheck)
for details on how healthchecks work."
- - "O(healthcheck.interval), O(healthcheck.timeout) and O(healthcheck.start_period) are specified as durations.
+ - "O(healthcheck.interval), O(healthcheck.timeout), O(healthcheck.start_period), and O(healthcheck.start_interval) are specified as durations.
They accept duration as a string in a format that look like: V(5h34m56s), V(1m30s), and so on.
The supported units are V(us), V(ms), V(s), V(m) and V(h)."
type: dict
@@ -379,6 +379,16 @@ options:
- Command to run to check health.
- Must be either a string or a list. If it is a list, the first item must be one of V(NONE), V(CMD) or V(CMD-SHELL).
type: raw
+ test_cli_compatible:
+ description:
+ - If set to V(true), omitting O(healthcheck.test) while providing O(healthcheck) does not disable healthchecks,
+ but simply overwrites the image's values by the ones specified in O(healthcheck). This is
+ the behavior used by the Docker CLI.
+ - If set to V(false), omitting O(healthcheck.test) will disable the container's health check.
+ This is the classical behavior of the module and currently the default behavior.
+ default: false
+ type: bool
+ version_added: 3.10.0
interval:
description:
- Time between running the check.
@@ -399,6 +409,12 @@ options:
- Start period for the container to initialize before starting health-retries countdown.
- The default used by the Docker daemon is V(0s).
type: str
+ start_interval:
+ description:
+ - Time between health checks during the start period. This option requires Docker Engine version 25.0 or later.
+ - The default used by the Docker daemon is V(5s).
+ type: str
+ version_added: 3.10.0
hostname:
description:
- The container's hostname.
@@ -1196,6 +1212,7 @@ EXAMPLES = '''
timeout: 10s
retries: 3
start_period: 30s
+ start_interval: 10s
- name: Remove healthcheck from container
community.docker.docker_container:
diff --git a/ansible_collections/community/docker/plugins/modules/docker_container_exec.py b/ansible_collections/community/docker/plugins/modules/docker_container_exec.py
index 0d92dad96..251af5bcd 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_container_exec.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_container_exec.py
@@ -162,7 +162,6 @@ import shlex
import traceback
from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
-from ansible.module_utils.compat import selectors
from ansible.module_utils.six import string_types
from ansible_collections.community.docker.plugins.module_utils.common_api import (
@@ -170,6 +169,8 @@ from ansible_collections.community.docker.plugins.module_utils.common_api import
RequestException,
)
+from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
+
from ansible_collections.community.docker.plugins.module_utils.socket_handler import (
DockerSocketHandlerModule,
)
diff --git a/ansible_collections/community/docker/plugins/modules/docker_image_build.py b/ansible_collections/community/docker/plugins/modules/docker_image_build.py
index 7f9502098..48478b550 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_image_build.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_image_build.py
@@ -18,6 +18,9 @@ version_added: 3.6.0
description:
- This module allows you to build Docker images using Docker's buildx plugin (BuildKit).
+ - Note that the module is B(not idempotent) in the sense of classical Ansible modules.
+ The only idempotence check is whether the built image already exists. This check can
+ be disabled with the O(rebuild) option.
extends_documentation_fragment:
- community.docker.docker.cli_documentation
@@ -89,8 +92,10 @@ options:
type: str
platform:
description:
- - Platform in the format C(os[/arch[/variant]]).
- type: str
+ - Platforms in the format C(os[/arch[/variant]]).
+ - Since community.docker 3.10.0 this can be a list of platforms, instead of just a single platform.
+ type: list
+ elements: str
shm_size:
description:
- "Size of C(/dev/shm) in format C(<number>[<unit>]). Number is positive integer.
@@ -110,7 +115,121 @@ options:
- never
- always
default: never
-
+ secrets:
+ description:
+ - Secrets to expose to the build.
+ type: list
+ elements: dict
+ version_added: 3.10.0
+ suboptions:
+ id:
+ description:
+ - The secret identifier.
+ - The secret will be made available as a file in the container under C(/run/secrets/<id>).
+ type: str
+ required: true
+ type:
+ description:
+ - Type of the secret.
+ type: str
+ choices:
+ file:
+ - Reads the secret from a file on the target.
+ - The file must be specified in O(secrets[].src).
+ env:
+ - Reads the secret from an environment variable on the target.
+ - The environment variable must be named in O(secrets[].env).
+ - Note that this requires the Buildkit plugin to have version 0.6.0 or newer.
+ value:
+ - Provides the secret from a given value O(secrets[].value).
+ - B(Note) that the secret will be passed as an environment variable to C(docker compose).
+ Use another mean of transport if you consider this not safe enough.
+ - Note that this requires the Buildkit plugin to have version 0.6.0 or newer.
+ required: true
+ src:
+ description:
+ - Source path of the secret.
+ - Only supported and required for O(secrets[].type=file).
+ type: path
+ env:
+ description:
+ - Environment value of the secret.
+ - Only supported and required for O(secrets[].type=env).
+ type: str
+ value:
+ description:
+ - Value of the secret.
+ - B(Note) that the secret will be passed as an environment variable to C(docker compose).
+ Use another mean of transport if you consider this not safe enough.
+ - Only supported and required for O(secrets[].type=value).
+ type: str
+ outputs:
+ description:
+ - Output destinations.
+ - You can provide a list of exporters to export the built image in various places.
+ Note that not all exporters might be supported by the build driver used.
+ - Note that depending on how this option is used, no image with name O(name) and tag O(tag) might
+ be created, which can cause the basic idempotency this module offers to not work.
+ - Providing an empty list to this option is equivalent to not specifying it at all.
+ The default behavior is a single entry with O(outputs[].type=image).
+ type: list
+ elements: dict
+ version_added: 3.10.0
+ suboptions:
+ type:
+ description:
+ - The type of exporter to use.
+ type: str
+ choices:
+ local:
+ - This export type writes all result files to a directory on the client.
+ The new files will be owned by the current user.
+ On multi-platform builds, all results will be put in subdirectories by their platform.
+ - The destination has to be provided in O(outputs[].dest).
+ tar:
+ - This export type export type writes all result files as a single tarball on the client.
+ On multi-platform builds, all results will be put in subdirectories by their platform.
+ - The destination has to be provided in O(outputs[].dest).
+ oci:
+ - This export type writes the result image or manifest list as an
+ L(OCI image layout, https://github.com/opencontainers/image-spec/blob/v1.0.1/image-layout.md)
+ tarball on the client.
+ - The destination has to be provided in O(outputs[].dest).
+ docker:
+ - This export type writes the single-platform result image as a Docker image specification tarball on the client.
+ Tarballs created by this exporter are also OCI compatible.
+ - The destination can be provided in O(outputs[].dest).
+ If not specified, the tar will be loaded automatically to the local image store.
+ - The Docker context where to import the result can be provided in O(outputs[].context).
+ image:
+ - This exporter writes the build result as an image or a manifest list.
+ When using this driver, the image will appear in C(docker images).
+ - The image name can be provided in O(outputs[].name). If it is not provided, the
+ - Optionally, image can be automatically pushed to a registry by setting O(outputs[].push=true).
+ required: true
+ dest:
+ description:
+ - The destination path.
+ - Required for O(outputs[].type=local), O(outputs[].type=tar), O(outputs[].type=oci).
+ - Optional for O(outputs[].type=docker).
+ type: path
+ context:
+ description:
+ - Name for the Docker context where to import the result.
+ - Optional for O(outputs[].type=docker).
+ type: str
+ name:
+ description:
+ - Name under which the image is stored under.
+ - If not provided, O(name) and O(tag) will be used.
+ - Optional for O(outputs[].type=image).
+ type: str
+ push:
+ description:
+ - Whether to push the built image to a registry.
+ - Only used for O(outputs[].type=image).
+ type: bool
+ default: false
requirements:
- "Docker CLI with Docker buildx plugin"
@@ -128,6 +247,15 @@ EXAMPLES = '''
name: localhost/python/3.12:latest
path: /home/user/images/python
dockerfile: Dockerfile-3.12
+
+- name: Build multi-platform image
+ community.docker.docker_image_build:
+ name: multi-platform-image
+ tag: "1.5.2"
+ path: /home/user/images/multi-platform
+ platform:
+ - linux/amd64
+ - linux/arm64/v8
'''
RETURN = '''
@@ -138,6 +266,7 @@ image:
sample: {}
'''
+import base64
import os
import traceback
@@ -156,6 +285,8 @@ from ansible_collections.community.docker.plugins.module_utils.util import (
is_valid_tag,
)
+from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion
+
from ansible_collections.community.docker.plugins.module_utils._api.utils.utils import (
parse_repository_tag,
)
@@ -194,10 +325,26 @@ class ImageBuilder(DockerBaseClass):
self.shm_size = convert_to_bytes(parameters['shm_size'], self.client.module, 'shm_size')
self.labels = clean_dict_booleans_for_docker_api(parameters['labels'])
self.rebuild = parameters['rebuild']
+ self.secrets = parameters['secrets']
+ self.outputs = parameters['outputs']
buildx = self.client.get_client_plugin_info('buildx')
if buildx is None:
self.fail('Docker CLI {0} does not have the buildx plugin installed'.format(self.client.get_cli()))
+ buildx_version = buildx['Version'].lstrip('v')
+
+ if self.secrets:
+ for secret in self.secrets:
+ if secret['type'] in ('env', 'value'):
+ if LooseVersion(buildx_version) < LooseVersion('0.6.0'):
+ self.fail('The Docker buildx plugin has version {version}, but 0.6.0 is needed for secrets of type=env and type=value'.format(
+ version=buildx_version,
+ ))
+ if self.outputs and len(self.outputs) > 1:
+ if LooseVersion(buildx_version) < LooseVersion('0.13.0'):
+ self.fail('The Docker buildx plugin has version {version}, but 0.13.0 is needed to specify more than one output'.format(
+ version=buildx_version,
+ ))
self.path = parameters['path']
if not os.path.isdir(self.path):
@@ -230,6 +377,7 @@ class ImageBuilder(DockerBaseClass):
args.extend([option, value])
def add_args(self, args):
+ environ_update = {}
args.extend(['--tag', '%s:%s' % (self.name, self.tag)])
if self.dockerfile:
args.extend(['--file', os.path.join(self.path, self.dockerfile)])
@@ -248,11 +396,54 @@ class ImageBuilder(DockerBaseClass):
if self.target:
args.extend(['--target', self.target])
if self.platform:
- args.extend(['--platform', self.platform])
+ for platform in self.platform:
+ args.extend(['--platform', platform])
if self.shm_size:
args.extend(['--shm-size', str(self.shm_size)])
if self.labels:
self.add_list_arg(args, '--label', dict_to_list(self.labels))
+ if self.secrets:
+ random_prefix = None
+ for index, secret in enumerate(self.secrets):
+ if secret['type'] == 'file':
+ args.extend(['--secret', 'id={id},type=file,src={src}'.format(id=secret['id'], src=secret['src'])])
+ if secret['type'] == 'env':
+ args.extend(['--secret', 'id={id},type=env,env={env}'.format(id=secret['id'], env=secret['src'])])
+ if secret['type'] == 'value':
+ # We pass values on using environment variables. The user has been warned in the documentation
+ # that they should only use this mechanism when being comfortable with it.
+ if random_prefix is None:
+ # Use /dev/urandom to generate some entropy to make the environment variable's name unguessable
+ random_prefix = base64.b64encode(os.urandom(16)).decode('utf-8').replace('=', '')
+ env_name = 'ANSIBLE_DOCKER_COMPOSE_ENV_SECRET_{random}_{id}'.format(
+ random=random_prefix,
+ id=index,
+ )
+ environ_update[env_name] = secret['value']
+ args.extend(['--secret', 'id={id},type=env,env={env}'.format(id=secret['id'], env=env_name)])
+ if self.outputs:
+ for output in self.outputs:
+ if output['type'] == 'local':
+ args.extend(['--output', 'type=local,dest={dest}'.format(dest=output['dest'])])
+ if output['type'] == 'tar':
+ args.extend(['--output', 'type=tar,dest={dest}'.format(dest=output['dest'])])
+ if output['type'] == 'oci':
+ args.extend(['--output', 'type=oci,dest={dest}'.format(dest=output['dest'])])
+ if output['type'] == 'docker':
+ more = []
+ if output['dest'] is not None:
+ more.append('dest={dest}'.format(dest=output['dest']))
+ if output['dest'] is not None:
+ more.append('context={context}'.format(context=output['context']))
+ args.extend(['--output', 'type=docker,{more}'.format(more=','.join(more))])
+ if output['type'] == 'image':
+ more = []
+ if output['name'] is not None:
+ more.append('name={name}'.format(name=output['name']))
+ if output['push']:
+ more.append('push=true')
+ args.extend(['--output', 'type=image,{more}'.format(more=','.join(more))])
+ return environ_update
def build_image(self):
image = self.client.find_image(self.name, self.tag)
@@ -269,9 +460,9 @@ class ImageBuilder(DockerBaseClass):
results['changed'] = True
if not self.check_mode:
args = ['buildx', 'build', '--progress', 'plain']
- self.add_args(args)
+ environ_update = self.add_args(args)
args.extend(['--', self.path])
- rc, stdout, stderr = self.client.call_cli(*args)
+ rc, stdout, stderr = self.client.call_cli(*args, environ_update=environ_update)
if rc != 0:
self.fail('Building %s:%s failed' % (self.name, self.tag), stdout=to_native(stdout), stderr=to_native(stderr))
results['stdout'] = to_native(stdout)
@@ -294,10 +485,52 @@ def main():
etc_hosts=dict(type='dict'),
args=dict(type='dict'),
target=dict(type='str'),
- platform=dict(type='str'),
+ platform=dict(type='list', elements='str'),
shm_size=dict(type='str'),
labels=dict(type='dict'),
rebuild=dict(type='str', choices=['never', 'always'], default='never'),
+ secrets=dict(
+ type='list',
+ elements='dict',
+ options=dict(
+ id=dict(type='str', required=True),
+ type=dict(type='str', choices=['file', 'env', 'value'], required=True),
+ src=dict(type='path'),
+ env=dict(type='str'),
+ value=dict(type='str', no_log=True),
+ ),
+ required_if=[
+ ('type', 'file', ['src']),
+ ('type', 'env', ['env']),
+ ('type', 'value', ['value']),
+ ],
+ mutually_exclusive=[
+ ('src', 'env', 'value'),
+ ],
+ no_log=False,
+ ),
+ outputs=dict(
+ type='list',
+ elements='dict',
+ options=dict(
+ type=dict(type='str', choices=['local', 'tar', 'oci', 'docker', 'image'], required=True),
+ dest=dict(type='path'),
+ context=dict(type='str'),
+ name=dict(type='str'),
+ push=dict(type='bool', default=False),
+ ),
+ required_if=[
+ ('type', 'local', ['dest']),
+ ('type', 'tar', ['dest']),
+ ('type', 'oci', ['dest']),
+ ],
+ mutually_exclusive=[
+ ('dest', 'name'),
+ ('dest', 'push'),
+ ('context', 'name'),
+ ('context', 'push'),
+ ],
+ ),
)
client = AnsibleModuleDockerClient(
diff --git a/ansible_collections/community/docker/plugins/modules/docker_network.py b/ansible_collections/community/docker/plugins/modules/docker_network.py
index 5670ceea0..c5dd3b229 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_network.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_network.py
@@ -35,6 +35,18 @@ options:
aliases:
- network_name
+ config_from:
+ description:
+ - Specifies the config only network to use the config from.
+ type: str
+ version_added: 3.10.0
+
+ config_only:
+ description:
+ - Sets that this is a config only network.
+ type: bool
+ version_added: 3.10.0
+
connected:
description:
- List of container names or container IDs to connect to a network.
@@ -283,6 +295,8 @@ class TaskParameters(DockerBaseClass):
self.name = None
self.connected = None
+ self.config_from = None
+ self.config_only = None
self.driver = None
self.driver_options = None
self.ipam_driver = None
@@ -300,6 +314,11 @@ class TaskParameters(DockerBaseClass):
for key, value in client.module.params.items():
setattr(self, key, value)
+ # config_only sets driver to 'null' (and scope to 'local') so force that here. Otherwise we get
+ # diffs of 'null' --> 'bridge' given that the driver option defaults to 'bridge'.
+ if self.config_only:
+ self.driver = 'null'
+
def container_names_in_network(network):
return [c['Name'] for c in network['Containers'].values()] if network['Containers'] else []
@@ -401,6 +420,14 @@ class DockerNetworkManager(object):
:return: (bool, list)
'''
differences = DifferenceTracker()
+ if self.parameters.config_only is not None and self.parameters.config_only != net.get('ConfigOnly', False):
+ differences.add('config_only',
+ parameter=self.parameters.config_only,
+ active=net.get('ConfigOnly', False))
+ if self.parameters.config_from is not None and self.parameters.config_from != net.get('ConfigFrom', {}).get('Network', ''):
+ differences.add('config_from',
+ parameter=self.parameters.config_from,
+ active=net.get('ConfigFrom', {}).get('Network', ''))
if self.parameters.driver and self.parameters.driver != net['Driver']:
differences.add('driver',
parameter=self.parameters.driver,
@@ -503,6 +530,10 @@ class DockerNetworkManager(object):
'CheckDuplicate': None,
}
+ if self.parameters.config_only is not None:
+ data['ConfigOnly'] = self.parameters.config_only
+ if self.parameters.config_from:
+ data['ConfigFrom'] = {'Network': self.parameters.config_from}
if self.parameters.enable_ipv6:
data['EnableIPv6'] = True
if self.parameters.internal:
@@ -630,6 +661,8 @@ class DockerNetworkManager(object):
def main():
argument_spec = dict(
name=dict(type='str', required=True, aliases=['network_name']),
+ config_from=dict(type='str'),
+ config_only=dict(type='bool'),
connected=dict(type='list', default=[], elements='str', aliases=['containers']),
state=dict(type='str', default='present', choices=['present', 'absent']),
driver=dict(type='str', default='bridge'),
@@ -653,6 +686,8 @@ def main():
)
option_minimal_versions = dict(
+ config_from=dict(docker_api_version='1.30'),
+ config_only=dict(docker_api_version='1.30'),
scope=dict(docker_api_version='1.30'),
attachable=dict(docker_api_version='1.26'),
)
diff --git a/ansible_collections/community/docker/plugins/modules/docker_prune.py b/ansible_collections/community/docker/plugins/modules/docker_prune.py
index 1dfbf290e..a333c52fe 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_prune.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_prune.py
@@ -81,6 +81,28 @@ options:
- Whether to prune the builder cache.
type: bool
default: false
+ builder_cache_all:
+ description:
+ - Whether to remove all types of build cache.
+ type: bool
+ default: false
+ version_added: 3.10.0
+ builder_cache_filters:
+ description:
+ - A dictionary of filter values used for selecting images to delete.
+ - "For example, C(until: 10m)."
+ - See L(the API documentation,https://docs.docker.com/engine/api/v1.44/#tag/Image/operation/BuildPrune)
+ for more information on possible filters.
+ type: dict
+ version_added: 3.10.0
+ builder_cache_keep_storage:
+ description:
+ - Amount of disk space to keep for cache in format C(<number>[<unit>])."
+ - "Number is a positive integer. Unit can be one of V(B) (byte), V(K) (kibibyte, 1024B), V(M) (mebibyte), V(G) (gibibyte),
+ V(T) (tebibyte), or V(P) (pebibyte)."
+ - "Omitting the unit defaults to bytes."
+ type: str
+ version_added: 3.10.0
author:
- "Felix Fontein (@felixfontein)"
@@ -181,11 +203,20 @@ builder_cache_space_reclaimed:
returned: O(builder_cache=true)
type: int
sample: 0
+builder_cache_caches_deleted:
+ description:
+ - The build caches that were deleted.
+ returned: O(builder_cache=true) and API version is 1.39 or later
+ type: list
+ elements: str
+ sample: []
+ version_added: 3.10.0
'''
import traceback
from ansible.module_utils.common.text.converters import to_native
+from ansible.module_utils.common.text.formatters import human_to_bytes
from ansible_collections.community.docker.plugins.module_utils.common_api import (
AnsibleDockerClient,
@@ -209,13 +240,29 @@ def main():
volumes=dict(type='bool', default=False),
volumes_filters=dict(type='dict'),
builder_cache=dict(type='bool', default=False),
+ builder_cache_all=dict(type='bool', default=False),
+ builder_cache_filters=dict(type='dict'),
+ builder_cache_keep_storage=dict(type='str'), # convert to bytes
)
client = AnsibleDockerClient(
argument_spec=argument_spec,
+ option_minimal_versions=dict(
+ builder_cache=dict(docker_py_version='1.31'),
+ builder_cache_all=dict(docker_py_version='1.39'),
+ builder_cache_filters=dict(docker_py_version='1.31'),
+ builder_cache_keep_storage=dict(docker_py_version='1.39'),
+ ),
# supports_check_mode=True,
)
+ builder_cache_keep_storage = None
+ if client.module.params.get('builder_cache_keep_storage') is not None:
+ try:
+ builder_cache_keep_storage = human_to_bytes(client.module.params.get('builder_cache_keep_storage'))
+ except ValueError as exc:
+ client.module.fail_json(msg='Error while parsing value of builder_cache_keep_storage: {0}'.format(exc))
+
try:
result = dict()
changed = False
@@ -256,10 +303,21 @@ def main():
changed = True
if client.module.params['builder_cache']:
- res = client.post_to_json('/build/prune')
+ filters = clean_dict_booleans_for_docker_api(client.module.params.get('builder_cache_filters'))
+ params = {'filters': convert_filters(filters)}
+ if client.module.params.get('builder_cache_all'):
+ params['all'] = 'true'
+ if builder_cache_keep_storage is not None:
+ params['keep-storage'] = builder_cache_keep_storage
+ res = client.post_to_json('/build/prune', params=params)
result['builder_cache_space_reclaimed'] = res['SpaceReclaimed']
if result['builder_cache_space_reclaimed']:
changed = True
+ if 'CachesDeleted' in res:
+ # API version 1.39+: return value CachesDeleted (list of str)
+ result['builder_cache_caches_deleted'] = res['CachesDeleted']
+ if result['builder_cache_caches_deleted']:
+ changed = True
result['changed'] = changed
client.module.exit_json(**result)
diff --git a/ansible_collections/community/docker/plugins/modules/docker_swarm_service.py b/ansible_collections/community/docker/plugins/modules/docker_swarm_service.py
index 95cc10366..4660d1138 100644
--- a/ansible_collections/community/docker/plugins/modules/docker_swarm_service.py
+++ b/ansible_collections/community/docker/plugins/modules/docker_swarm_service.py
@@ -83,6 +83,11 @@ options:
- Dictionary of key value pairs.
- Corresponds to the C(--container-label) option of C(docker service create).
type: dict
+ sysctls:
+ description:
+ - Dictionary of key, value pairs.
+ version_added: 3.10.0
+ type: dict
dns:
description:
- List of custom DNS servers.
@@ -681,6 +686,7 @@ swarm_service:
"engine.labels.operatingsystem == ubuntu 14.04"
],
"container_labels": null,
+ "sysctls": null,
"dns": null,
"dns_options": null,
"dns_search": null,
@@ -1226,6 +1232,7 @@ class DockerService(DockerBaseClass):
self.log_driver_options = None
self.labels = None
self.container_labels = None
+ self.sysctls = None
self.limit_cpu = None
self.limit_memory = None
self.reserve_cpu = None
@@ -1292,6 +1299,7 @@ class DockerService(DockerBaseClass):
'placement_preferences': self.placement_preferences,
'labels': self.labels,
'container_labels': self.container_labels,
+ 'sysctls': self.sysctls,
'mode': self.mode,
'replicas': self.replicas,
'endpoint_mode': self.endpoint_mode,
@@ -1539,6 +1547,7 @@ class DockerService(DockerBaseClass):
s.tty = ap['tty']
s.labels = ap['labels']
s.container_labels = ap['container_labels']
+ s.sysctls = ap['sysctls']
s.mode = ap['mode']
s.stop_signal = ap['stop_signal']
s.user = ap['user']
@@ -1740,6 +1749,8 @@ class DockerService(DockerBaseClass):
differences.add('reserve_memory', parameter=self.reserve_memory, active=os.reserve_memory)
if self.container_labels is not None and self.container_labels != (os.container_labels or {}):
differences.add('container_labels', parameter=self.container_labels, active=os.container_labels)
+ if self.sysctls is not None and self.sysctls != (os.sysctls or {}):
+ differences.add('sysctls', parameter=self.sysctls, active=os.sysctls)
if self.stop_signal is not None and self.stop_signal != os.stop_signal:
differences.add('stop_signal', parameter=self.stop_signal, active=os.stop_signal)
if self.stop_grace_period is not None and self.stop_grace_period != os.stop_grace_period:
@@ -1934,6 +1945,8 @@ class DockerService(DockerBaseClass):
container_spec_args['user'] = self.user
if self.container_labels is not None:
container_spec_args['labels'] = self.container_labels
+ if self.sysctls is not None:
+ container_spec_args['sysctls'] = self.sysctls
if self.healthcheck is not None:
container_spec_args['healthcheck'] = types.Healthcheck(**self.healthcheck)
elif self.healthcheck_disabled:
@@ -2163,6 +2176,7 @@ class DockerServiceManager(object):
ds.read_only = task_template_data['ContainerSpec'].get('ReadOnly')
ds.cap_add = task_template_data['ContainerSpec'].get('CapabilityAdd')
ds.cap_drop = task_template_data['ContainerSpec'].get('CapabilityDrop')
+ ds.sysctls = task_template_data['ContainerSpec'].get('Sysctls')
healthcheck_data = task_template_data['ContainerSpec'].get('Healthcheck')
if healthcheck_data:
@@ -2676,6 +2690,7 @@ def main():
hosts=dict(type='dict'),
labels=dict(type='dict'),
container_labels=dict(type='dict'),
+ sysctls=dict(type='dict'),
mode=dict(
type='str',
default='replicated',
@@ -2751,6 +2766,7 @@ def main():
init=dict(docker_py_version='4.0.0', docker_api_version='1.37'),
cap_add=dict(docker_py_version='5.0.3', docker_api_version='1.41'),
cap_drop=dict(docker_py_version='5.0.3', docker_api_version='1.41'),
+ sysctls=dict(docker_py_version='6.0.0', docker_api_version='1.40'),
# specials
publish_mode=dict(
docker_py_version='3.0.0',
diff --git a/ansible_collections/community/docker/plugins/plugin_utils/socket_handler.py b/ansible_collections/community/docker/plugins/plugin_utils/socket_handler.py
index 204996f24..e8fd266c8 100644
--- a/ansible_collections/community/docker/plugins/plugin_utils/socket_handler.py
+++ b/ansible_collections/community/docker/plugins/plugin_utils/socket_handler.py
@@ -6,7 +6,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
-from ansible.compat import selectors
+from ansible_collections.community.docker.plugins.module_utils.selectors import selectors
from ansible_collections.community.docker.plugins.module_utils.socket_handler import (
DockerSocketHandlerBase,
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/main.yml b/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/main.yml
index 8813f0e71..dbb2ece71 100644
--- a/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/main.yml
@@ -20,7 +20,8 @@
# Run the tests
- block:
- - command: docker compose --help
+ - name: Show docker compose --help output
+ command: docker compose --help
- include_tasks: run-test.yml
with_fileglob:
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2_pull/tasks/main.yml b/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2_pull/tasks/main.yml
index 8813f0e71..d2c8497b1 100644
--- a/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2_pull/tasks/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2_pull/tasks/main.yml
@@ -18,9 +18,13 @@
- debug:
msg: "Using name prefix {{ name_prefix }}"
+- name: Show images
+ command: docker images --all --digests
+
# Run the tests
- block:
- - command: docker compose --help
+ - name: Show docker compose --help output
+ command: docker compose --help
- include_tasks: run-test.yml
with_fileglob:
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/test.yml b/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/test.yml
index af6e75b22..57130ef1a 100644
--- a/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/test.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/test.yml
@@ -28,12 +28,24 @@
- Dockerfile
- EtcHostsDockerfile
- MyDockerfile
+ - SecretsDockerfile
- StagedDockerfile
- debug:
msg: "Has buildx plugin: {{ docker_has_buildx }}"
- block:
+ - name: Determine plugin versions
+ command: docker info -f '{{ "{{" }}json .ClientInfo.Plugins{{ "}}" }}'
+ register: plugin_versions
+
+ - name: Determine buildx plugin version
+ set_fact:
+ buildx_version: >-
+ {{
+ (plugin_versions.stdout | from_json | selectattr('Name', 'eq', 'buildx') | map(attribute='Version') | first).lstrip('v')
+ }}
+
- include_tasks: run-test.yml
with_fileglob:
- "tests/*.yml"
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/tests/options.yml b/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/tests/options.yml
index 990035788..5c1211c71 100644
--- a/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/tests/options.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_image_build/tasks/tests/options.yml
@@ -202,3 +202,88 @@
- labels_1 is changed
- labels_1.image.Config.Labels.FOO == 'BAR'
- labels_1.image.Config.Labels["this is a label"] == "this is the label's value"
+
+####################################################################
+## secrets #########################################################
+####################################################################
+
+- name: Generate secret
+ set_fact:
+ docker_image_build_secret_value: this is my secret {{ '%0x' % ((2**32) | random) }}
+
+- when: buildx_version is version('0.6.0', '>=')
+ block:
+ - name: Build image with secrets via environment variables
+ docker_image_build:
+ name: "{{ iname }}"
+ path: "{{ remote_tmp_dir }}/files"
+ dockerfile: "SecretsDockerfile"
+ pull: false
+ secrets:
+ - id: my-awesome-secret
+ type: value
+ value: '{{ docker_image_build_secret_value }}'
+ nocache: true # using a cache can result in the output step being CACHED
+ register: secrets_1
+
+ - name: cleanup
+ docker_image_remove:
+ name: "{{ iname }}"
+
+ - name: Show image information
+ debug:
+ var: secrets_1.stderr_lines
+
+ - assert:
+ that:
+ - secrets_1 is changed
+ - (docker_image_build_secret_value | b64encode) in secrets_1.stderr
+
+####################################################################
+## outputs #########################################################
+####################################################################
+
+- name: Make sure the image is not there
+ docker_image_remove:
+ name: "{{ iname }}"
+
+- name: Make sure the image tarball is not there
+ file:
+ path: "{{ remote_tmp_dir }}/container.tar"
+ state: absent
+
+- name: Build image with outputs
+ docker_image_build:
+ name: "{{ iname }}"
+ path: "{{ remote_tmp_dir }}/files"
+ dockerfile: "Dockerfile"
+ pull: false
+ outputs:
+ - type: tar
+ dest: "{{ remote_tmp_dir }}/container.tar"
+ register: outputs_1
+
+- name: cleanup (should not be changed)
+ docker_image_remove:
+ name: "{{ iname }}"
+ register: outputs_1_cleanup
+
+- name: Gather information on tarball
+ stat:
+ path: "{{ remote_tmp_dir }}/container.tar"
+ register: outputs_1_stat
+
+- name: Show image information
+ debug:
+ var: outputs_1.image
+
+- name: Show tarball information
+ debug:
+ var: outputs_1_stat.stat
+
+- assert:
+ that:
+ - outputs_1 is changed
+ - outputs_1.image | length == 0
+ - outputs_1_cleanup is not changed
+ - outputs_1_stat.stat.exists
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_image_build/templates/SecretsDockerfile b/ansible_collections/community/docker/tests/integration/targets/docker_image_build/templates/SecretsDockerfile
new file mode 100644
index 000000000..31bec8262
--- /dev/null
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_image_build/templates/SecretsDockerfile
@@ -0,0 +1,7 @@
+# Copyright (c) 2024, Felix Fontein
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+FROM {{ docker_test_image_busybox }}
+RUN --mount=type=secret,id=my-awesome-secret \
+ cat /run/secrets/my-awesome-secret | base64
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_prune/tasks/main.yml b/ansible_collections/community/docker/tests/integration/targets/docker_prune/tasks/main.yml
index b2160ef0e..8c1309bc4 100644
--- a/ansible_collections/community/docker/tests/integration/targets/docker_prune/tasks/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_prune/tasks/main.yml
@@ -126,6 +126,28 @@
debug:
var: result
+ - name: Prune build cache (API version 1.39+)
+ when: docker_api_version is version('1.39', '>=')
+ block:
+ - name: Prune build cache with option
+ docker_prune:
+ builder_cache: true
+ builder_cache_all: true
+ builder_cache_filters:
+ until: 10m
+ builder_cache_keep_storage: 1MB
+ register: result
+
+ - name: Show results
+ debug:
+ var: result
+
+ - name: Check results
+ assert:
+ that:
+ - "'builder_cache_space_reclaimed' in result"
+ - "'builder_cache_caches_deleted' in result"
+
- name: Prune volumes with all filter (API version 1.42+)
when: docker_api_version is version('1.42', '>=')
block:
diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_swarm_service/vars/main.yml b/ansible_collections/community/docker/tests/integration/targets/docker_swarm_service/vars/main.yml
index 836ee41c4..bd8c799e2 100644
--- a/ansible_collections/community/docker/tests/integration/targets/docker_swarm_service/vars/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/docker_swarm_service/vars/main.yml
@@ -58,3 +58,4 @@ service_expected_output:
user: null
working_dir: null
init: null
+ sysctls: null
diff --git a/ansible_collections/community/docker/tests/integration/targets/generic_connection_tests/tasks/main.yml b/ansible_collections/community/docker/tests/integration/targets/generic_connection_tests/tasks/main.yml
index abbb02956..e43833b8d 100644
--- a/ansible_collections/community/docker/tests/integration/targets/generic_connection_tests/tasks/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/generic_connection_tests/tasks/main.yml
@@ -174,7 +174,8 @@
- (output_direct.host_info | sanitize_host_info) == (output_https.host_info | sanitize_host_info)
always:
- - command: docker logs {{ daemon_nginx_frontend }}
+ - name: Obtain logs from the nginx frontend
+ command: docker logs {{ daemon_nginx_frontend }}
register: output
ignore_errors: true
- debug:
diff --git a/ansible_collections/community/docker/tests/integration/targets/setup_docker/tasks/main.yml b/ansible_collections/community/docker/tests/integration/targets/setup_docker/tasks/main.yml
index e3d7c413f..54c27e43e 100644
--- a/ansible_collections/community/docker/tests/integration/targets/setup_docker/tasks/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/setup_docker/tasks/main.yml
@@ -91,7 +91,8 @@
- block:
# Cleanup docker daemon
- - command: 'docker ps --no-trunc --format {% raw %}"{{.Names}}"{% endraw %}'
+ - name: Show all containers
+ command: 'docker ps --no-trunc --format {% raw %}"{{.Names}}"{% endraw %}'
- name: "Remove all ansible-docker-test-* docker containers"
shell: 'docker ps --no-trunc --format {% raw %}"{{.Names}}"{% endraw %} | grep "^ansible-docker-test-" | xargs -r docker rm -f'
diff --git a/ansible_collections/community/docker/tests/integration/targets/setup_docker_cli_compose/tasks/main.yml b/ansible_collections/community/docker/tests/integration/targets/setup_docker_cli_compose/tasks/main.yml
index 7a971c229..5a58c982c 100644
--- a/ansible_collections/community/docker/tests/integration/targets/setup_docker_cli_compose/tasks/main.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/setup_docker_cli_compose/tasks/main.yml
@@ -52,7 +52,8 @@
- name: Obtain Docker Compose version
when: docker_has_compose
block:
- - command:
+ - name: Obtain docker info
+ command:
cmd: docker info --format '{% raw %}{{ json .ClientInfo.Plugins }}{% endraw %}'
register: docker_cli_plugins_stdout
- set_fact:
diff --git a/ansible_collections/community/docker/tests/integration/targets/setup_docker_compose_v1/vars/Alpine.yml b/ansible_collections/community/docker/tests/integration/targets/setup_docker_compose_v1/vars/Alpine.yml
index fb03ae738..65f6f4326 100644
--- a/ansible_collections/community/docker/tests/integration/targets/setup_docker_compose_v1/vars/Alpine.yml
+++ b/ansible_collections/community/docker/tests/integration/targets/setup_docker_compose_v1/vars/Alpine.yml
@@ -9,3 +9,5 @@ docker_compose_pip_packages:
- docker-compose
# Force PyYAML to 5.3.1
- PyYAML==5.3.1
+ # Force requests to < 2.32.0 (https://github.com/docker/docker-py/issues/3256)
+ - requests<2.32.0
diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.11.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.11.txt
index 2bc38ac22..8dce572fc 100644
--- a/ansible_collections/community/docker/tests/sanity/ignore-2.11.txt
+++ b/ansible_collections/community/docker/tests/sanity/ignore-2.11.txt
@@ -11,3 +11,4 @@ plugins/modules/docker_compose_v2.py validate-modules:return-syntax-error
plugins/modules/docker_compose_v2_pull.py validate-modules:return-syntax-error
plugins/modules/docker_container.py import-2.6!skip # Import uses Python 2.7+ syntax
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
+plugins/modules/docker_image_build.py validate-modules:invalid-documentation
diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.12.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.12.txt
index f3c4575fb..a3d961e4d 100644
--- a/ansible_collections/community/docker/tests/sanity/ignore-2.12.txt
+++ b/ansible_collections/community/docker/tests/sanity/ignore-2.12.txt
@@ -3,3 +3,4 @@ plugins/modules/current_container_facts.py validate-modules:return-syntax-error
plugins/modules/docker_compose_v2.py validate-modules:return-syntax-error
plugins/modules/docker_compose_v2_pull.py validate-modules:return-syntax-error
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
+plugins/modules/docker_image_build.py validate-modules:invalid-documentation
diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.13.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.13.txt
index c0d5c549c..ef8aab6c4 100644
--- a/ansible_collections/community/docker/tests/sanity/ignore-2.13.txt
+++ b/ansible_collections/community/docker/tests/sanity/ignore-2.13.txt
@@ -1,3 +1,4 @@
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
plugins/modules/docker_compose_v2.py validate-modules:return-syntax-error
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
+plugins/modules/docker_image_build.py validate-modules:invalid-documentation
diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.14.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.14.txt
index 2a06013da..f717d24a7 100644
--- a/ansible_collections/community/docker/tests/sanity/ignore-2.14.txt
+++ b/ansible_collections/community/docker/tests/sanity/ignore-2.14.txt
@@ -1,2 +1,3 @@
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
+plugins/modules/docker_image_build.py validate-modules:invalid-documentation
diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.15.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.15.txt
index 2a06013da..f717d24a7 100644
--- a/ansible_collections/community/docker/tests/sanity/ignore-2.15.txt
+++ b/ansible_collections/community/docker/tests/sanity/ignore-2.15.txt
@@ -1,2 +1,3 @@
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
+plugins/modules/docker_image_build.py validate-modules:invalid-documentation
diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.16.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.16.txt
index 12e0b26f9..b60ad3445 100644
--- a/ansible_collections/community/docker/tests/sanity/ignore-2.16.txt
+++ b/ansible_collections/community/docker/tests/sanity/ignore-2.16.txt
@@ -1 +1,2 @@
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
+plugins/modules/docker_image_build.py validate-modules:invalid-documentation
diff --git a/ansible_collections/community/docker/tests/unit/plugins/plugin_utils/test_unsafe.py b/ansible_collections/community/docker/tests/unit/plugins/plugin_utils/test_unsafe.py
new file mode 100644
index 000000000..286c51cfe
--- /dev/null
+++ b/ansible_collections/community/docker/tests/unit/plugins/plugin_utils/test_unsafe.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+import pytest
+
+from ansible.utils.unsafe_proxy import AnsibleUnsafe
+
+from ansible_collections.community.docker.plugins.plugin_utils.unsafe import (
+ make_unsafe,
+)
+
+
+TEST_MAKE_UNSAFE = [
+ (
+ u'text',
+ [],
+ [
+ (),
+ ],
+ ),
+ (
+ u'{{text}}',
+ [
+ (),
+ ],
+ [],
+ ),
+ (
+ b'text',
+ [],
+ [
+ (),
+ ],
+ ),
+ (
+ b'{{text}}',
+ [
+ (),
+ ],
+ [],
+ ),
+ (
+ {
+ 'skey': 'value',
+ 'ukey': '{{value}}',
+ 1: [
+ 'value',
+ '{{value}}',
+ {
+ 1.0: '{{value}}',
+ 2.0: 'value',
+ },
+ ],
+ },
+ [
+ ('ukey', ),
+ (1, 1),
+ (1, 2, 1.0),
+ ],
+ [
+ ('skey', ),
+ (1, 0),
+ (1, 2, 2.0),
+ ],
+ ),
+ (
+ ['value', '{{value}}'],
+ [
+ (1, ),
+ ],
+ [
+ (0, ),
+ ],
+ ),
+]
+
+
+@pytest.mark.parametrize("value, check_unsafe_paths, check_safe_paths", TEST_MAKE_UNSAFE)
+def test_make_unsafe(value, check_unsafe_paths, check_safe_paths):
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for check_path in check_unsafe_paths:
+ obj = unsafe_value
+ for elt in check_path:
+ obj = obj[elt]
+ assert isinstance(obj, AnsibleUnsafe)
+ for check_path in check_safe_paths:
+ obj = unsafe_value
+ for elt in check_path:
+ obj = obj[elt]
+ assert not isinstance(obj, AnsibleUnsafe)
+
+
+def test_make_unsafe_dict_key():
+ value = {
+ b'test': 1,
+ u'test': 2,
+ }
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert not isinstance(obj, AnsibleUnsafe)
+
+ value = {
+ b'{{test}}': 1,
+ u'{{test}}': 2,
+ }
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert isinstance(obj, AnsibleUnsafe)
+
+
+def test_make_unsafe_set():
+ value = set([b'test', u'test'])
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert not isinstance(obj, AnsibleUnsafe)
+
+ value = set([b'{{test}}', u'{{test}}'])
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert isinstance(obj, AnsibleUnsafe)
diff --git a/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml
index be8f011bd..7dc438ad3 100644
--- a/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml
+++ b/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml
@@ -29,14 +29,14 @@ schedules:
always: true
branches:
include:
+ - stable-9
- stable-8
- - stable-7
- cron: 0 11 * * 0
displayName: Weekly (old stable branches)
always: true
branches:
include:
- - stable-6
+ - stable-7
variables:
- name: checkoutPath
@@ -336,7 +336,7 @@ stages:
- name: Debian Bookworm
test: debian-bookworm/3.11
- name: ArchLinux
- test: archlinux/3.11
+ test: archlinux/3.12
groups:
- 1
- 2
diff --git a/ansible_collections/community/general/.github/BOTMETA.yml b/ansible_collections/community/general/.github/BOTMETA.yml
index e21d0c81c..add324935 100644
--- a/ansible_collections/community/general/.github/BOTMETA.yml
+++ b/ansible_collections/community/general/.github/BOTMETA.yml
@@ -33,6 +33,8 @@ files:
maintainers: $team_ansible_core
$becomes/pmrun.py:
maintainers: $team_ansible_core
+ $becomes/run0.py:
+ maintainers: konstruktoid
$becomes/sesu.py:
maintainers: nekonyuu
$becomes/sudosu.py:
@@ -89,6 +91,8 @@ files:
maintainers: ryancurrah
$callbacks/syslog_json.py:
maintainers: imjoseangel
+ $callbacks/timestamp.py:
+ maintainers: kurokobo
$callbacks/unixy.py:
labels: unixy
maintainers: akatch
@@ -117,6 +121,8 @@ files:
maintainers: $team_ansible_core
$doc_fragments/:
labels: docs_fragments
+ $doc_fragments/django.py:
+ maintainers: russoz
$doc_fragments/hpe3par.py:
labels: hpe3par
maintainers: farhan7500 gautamphegde
@@ -294,8 +300,12 @@ files:
labels: module_utils
$module_utils/btrfs.py:
maintainers: gnfzdz
+ $module_utils/cmd_runner.py:
+ maintainers: russoz
$module_utils/deps.py:
maintainers: russoz
+ $module_utils/django.py:
+ maintainers: russoz
$module_utils/gconftool2.py:
labels: gconftool2
maintainers: russoz
@@ -339,6 +349,8 @@ files:
$module_utils/pipx.py:
labels: pipx
maintainers: russoz
+ $module_utils/python_runner.py:
+ maintainers: russoz
$module_utils/puppet.py:
labels: puppet
maintainers: russoz
@@ -494,6 +506,8 @@ files:
ignore: scottanderson42 tastychutney
labels: django_manage
maintainers: russoz
+ $modules/django_command.py:
+ maintainers: russoz
$modules/dnf_versionlock.py:
maintainers: moreda
$modules/dnf_config_manager.py:
@@ -532,8 +546,6 @@ files:
maintainers: $team_flatpak
$modules/flatpak_remote.py:
maintainers: $team_flatpak
- $modules/flowdock.py:
- ignore: mcodd
$modules/gandi_livedns.py:
maintainers: gthiemonge
$modules/gconftool2.py:
@@ -1096,46 +1108,6 @@ files:
$modules/python_requirements_info.py:
ignore: ryansb
maintainers: willthames
- $modules/rax:
- ignore: ryansb sivel
- $modules/rax.py:
- maintainers: omgjlk sivel
- $modules/rax_cbs.py:
- maintainers: claco
- $modules/rax_cbs_attachments.py:
- maintainers: claco
- $modules/rax_cdb.py:
- maintainers: jails
- $modules/rax_cdb_database.py:
- maintainers: jails
- $modules/rax_cdb_user.py:
- maintainers: jails
- $modules/rax_clb.py:
- maintainers: claco
- $modules/rax_clb_nodes.py:
- maintainers: neuroid
- $modules/rax_clb_ssl.py:
- maintainers: smashwilson
- $modules/rax_files.py:
- maintainers: angstwad
- $modules/rax_files_objects.py:
- maintainers: angstwad
- $modules/rax_identity.py:
- maintainers: claco
- $modules/rax_mon_alarm.py:
- maintainers: smashwilson
- $modules/rax_mon_check.py:
- maintainers: smashwilson
- $modules/rax_mon_entity.py:
- maintainers: smashwilson
- $modules/rax_mon_notification.py:
- maintainers: smashwilson
- $modules/rax_mon_notification_plan.py:
- maintainers: smashwilson
- $modules/rax_network.py:
- maintainers: claco omgjlk
- $modules/rax_queue.py:
- maintainers: claco
$modules/read_csv.py:
maintainers: dagwieers
$modules/redfish_:
@@ -1300,8 +1272,6 @@ files:
maintainers: farhan7500 gautamphegde
$modules/ssh_config.py:
maintainers: gaqzi Akasurde
- $modules/stackdriver.py:
- maintainers: bwhaley
$modules/stacki_host.py:
labels: stacki_host
maintainers: bsanders bbyhuy
@@ -1394,8 +1364,6 @@ files:
maintainers: $team_wdc
$modules/wdc_redfish_info.py:
maintainers: $team_wdc
- $modules/webfaction_:
- maintainers: quentinsf
$modules/xattr.py:
labels: xattr
maintainers: bcoca
diff --git a/ansible_collections/community/general/.github/workflows/ansible-test.yml b/ansible_collections/community/general/.github/workflows/ansible-test.yml
index ecfc36565..e57213e9f 100644
--- a/ansible_collections/community/general/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/general/.github/workflows/ansible-test.yml
@@ -42,6 +42,7 @@ jobs:
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pull-request-change-detection: 'true'
testing-type: sanity
@@ -83,6 +84,7 @@ jobs:
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
pre-test-cmd: >-
mkdir -p ../../ansible
@@ -183,6 +185,7 @@ jobs:
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: stable-${{ matrix.ansible }}
+ codecov-token: ${{ secrets.CODECOV_TOKEN }}
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
docker-image: ${{ matrix.docker }}
integration-continue-on-error: 'false'
diff --git a/ansible_collections/community/general/.gitignore b/ansible_collections/community/general/.gitignore
index b7868a9e4..cf1f74e41 100644
--- a/ansible_collections/community/general/.gitignore
+++ b/ansible_collections/community/general/.gitignore
@@ -512,3 +512,7 @@ $RECYCLE.BIN/
# Integration tests cloud configs
tests/integration/cloud-config-*.ini
+
+
+# VSCode specific extensions
+.vscode/settings.json
diff --git a/ansible_collections/community/general/CHANGELOG.md b/ansible_collections/community/general/CHANGELOG.md
index 8f23931fe..91922fb7a 100644
--- a/ansible_collections/community/general/CHANGELOG.md
+++ b/ansible_collections/community/general/CHANGELOG.md
@@ -2,234 +2,79 @@
**Topics**
-- <a href="#v8-6-0">v8\.6\.0</a>
+- <a href="#v9-0-1">v9\.0\.1</a>
- <a href="#release-summary">Release Summary</a>
- <a href="#minor-changes">Minor Changes</a>
- - <a href="#deprecated-features">Deprecated Features</a>
- <a href="#bugfixes">Bugfixes</a>
- - <a href="#new-modules">New Modules</a>
-- <a href="#v8-5-0">v8\.5\.0</a>
+- <a href="#v9-0-0">v9\.0\.0</a>
- <a href="#release-summary-1">Release Summary</a>
- <a href="#minor-changes-1">Minor Changes</a>
+ - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
+ - <a href="#deprecated-features">Deprecated Features</a>
+ - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- <a href="#security-fixes">Security Fixes</a>
- <a href="#bugfixes-1">Bugfixes</a>
- - <a href="#new-modules-1">New Modules</a>
-- <a href="#v8-4-0">v8\.4\.0</a>
- - <a href="#release-summary-2">Release Summary</a>
- - <a href="#minor-changes-2">Minor Changes</a>
- - <a href="#bugfixes-2">Bugfixes</a>
- <a href="#new-plugins">New Plugins</a>
+ - <a href="#become">Become</a>
- <a href="#callback">Callback</a>
- - <a href="#filter">Filter</a>
- - <a href="#new-modules-2">New Modules</a>
-- <a href="#v8-3-0">v8\.3\.0</a>
- - <a href="#release-summary-3">Release Summary</a>
- - <a href="#minor-changes-3">Minor Changes</a>
- - <a href="#deprecated-features-1">Deprecated Features</a>
- - <a href="#bugfixes-3">Bugfixes</a>
- - <a href="#new-modules-3">New Modules</a>
-- <a href="#v8-2-0">v8\.2\.0</a>
- - <a href="#release-summary-4">Release Summary</a>
- - <a href="#minor-changes-4">Minor Changes</a>
- - <a href="#bugfixes-4">Bugfixes</a>
- - <a href="#new-plugins-1">New Plugins</a>
- <a href="#connection">Connection</a>
- - <a href="#filter-1">Filter</a>
+ - <a href="#filter">Filter</a>
- <a href="#lookup">Lookup</a>
- - <a href="#new-modules-4">New Modules</a>
-- <a href="#v8-1-0">v8\.1\.0</a>
- - <a href="#release-summary-5">Release Summary</a>
- - <a href="#minor-changes-5">Minor Changes</a>
- - <a href="#bugfixes-5">Bugfixes</a>
- - <a href="#new-plugins-2">New Plugins</a>
- - <a href="#lookup-1">Lookup</a>
- <a href="#test">Test</a>
- - <a href="#new-modules-5">New Modules</a>
-- <a href="#v8-0-2">v8\.0\.2</a>
- - <a href="#release-summary-6">Release Summary</a>
- - <a href="#bugfixes-6">Bugfixes</a>
-- <a href="#v8-0-1">v8\.0\.1</a>
- - <a href="#release-summary-7">Release Summary</a>
- - <a href="#bugfixes-7">Bugfixes</a>
-- <a href="#v8-0-0">v8\.0\.0</a>
- - <a href="#release-summary-8">Release Summary</a>
- - <a href="#minor-changes-6">Minor Changes</a>
- - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
- - <a href="#deprecated-features-2">Deprecated Features</a>
- - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
- - <a href="#bugfixes-8">Bugfixes</a>
- - <a href="#known-issues">Known Issues</a>
- - <a href="#new-plugins-3">New Plugins</a>
- - <a href="#lookup-2">Lookup</a>
- - <a href="#new-modules-6">New Modules</a>
-This changelog describes changes after version 7\.0\.0\.
+ - <a href="#new-modules">New Modules</a>
+This changelog describes changes after version 8\.0\.0\.
-<a id="v8-6-0"></a>
-## v8\.6\.0
+<a id="v9-0-1"></a>
+## v9\.0\.1
<a id="release-summary"></a>
### Release Summary
-Regular bugfix and features release\.
+Bugfix release for inclusion in Ansible 10\.0\.0rc1\.
<a id="minor-changes"></a>
### Minor Changes
-* Use offset\-aware <code>datetime\.datetime</code> objects \(with timezone UTC\) instead of offset\-naive UTC timestamps\, which are deprecated in Python 3\.12 \([https\://github\.com/ansible\-collections/community\.general/pull/8222](https\://github\.com/ansible\-collections/community\.general/pull/8222)\)\.
-* apt\_rpm \- add new states <code>latest</code> and <code>present\_not\_latest</code>\. The value <code>latest</code> is equivalent to the current behavior of <code>present</code>\, which will upgrade a package if a newer version exists\. <code>present\_not\_latest</code> does what most users would expect <code>present</code> to do\: it does not upgrade if the package is already installed\. The current behavior of <code>present</code> will be deprecated in a later version\, and eventually changed to that of <code>present\_not\_latest</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8217](https\://github\.com/ansible\-collections/community\.general/issues/8217)\, [https\://github\.com/ansible\-collections/community\.general/pull/8247](https\://github\.com/ansible\-collections/community\.general/pull/8247)\)\.
-* bitwarden lookup plugin \- add support to filter by organization ID \([https\://github\.com/ansible\-collections/community\.general/pull/8188](https\://github\.com/ansible\-collections/community\.general/pull/8188)\)\.
-* filesystem \- add bcachefs support \([https\://github\.com/ansible\-collections/community\.general/pull/8126](https\://github\.com/ansible\-collections/community\.general/pull/8126)\)\.
-* ini\_file \- add an optional parameter <code>section\_has\_values</code>\. If the target ini file contains more than one <code>section</code>\, use <code>section\_has\_values</code> to specify which one should be updated \([https\://github\.com/ansible\-collections/community\.general/pull/7505](https\://github\.com/ansible\-collections/community\.general/pull/7505)\)\.
-* java\_cert \- add <code>cert\_content</code> argument \([https\://github\.com/ansible\-collections/community\.general/pull/8153](https\://github\.com/ansible\-collections/community\.general/pull/8153)\)\.
-* keycloak\_client\, keycloak\_clientscope\, keycloak\_clienttemplate \- added <code>docker\-v2</code> protocol support\, enhancing alignment with Keycloak\'s protocol options \([https\://github\.com/ansible\-collections/community\.general/issues/8215](https\://github\.com/ansible\-collections/community\.general/issues/8215)\, [https\://github\.com/ansible\-collections/community\.general/pull/8216](https\://github\.com/ansible\-collections/community\.general/pull/8216)\)\.
-* nmcli \- adds OpenvSwitch support with new <code>type</code> values <code>ovs\-port</code>\, <code>ovs\-interface</code>\, and <code>ovs\-bridge</code>\, and new <code>slave\_type</code> value <code>ovs\-port</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8154](https\://github\.com/ansible\-collections/community\.general/pull/8154)\)\.
-* osx\_defaults \- add option <code>check\_types</code> to enable changing the type of existing defaults on the fly \([https\://github\.com/ansible\-collections/community\.general/pull/8173](https\://github\.com/ansible\-collections/community\.general/pull/8173)\)\.
-* passwordstore lookup \- add <code>missing\_subkey</code> parameter defining the behavior of the lookup when a passwordstore subkey is missing \([https\://github\.com/ansible\-collections/community\.general/pull/8166](https\://github\.com/ansible\-collections/community\.general/pull/8166)\)\.
-* portage \- adds the possibility to explicitely tell portage to write packages to world file \([https\://github\.com/ansible\-collections/community\.general/issues/6226](https\://github\.com/ansible\-collections/community\.general/issues/6226)\, [https\://github\.com/ansible\-collections/community\.general/pull/8236](https\://github\.com/ansible\-collections/community\.general/pull/8236)\)\.
-* redfish\_command \- add command <code>ResetToDefaults</code> to reset manager to default state \([https\://github\.com/ansible\-collections/community\.general/issues/8163](https\://github\.com/ansible\-collections/community\.general/issues/8163)\)\.
-* redfish\_info \- add boolean return value <code>MultipartHttpPush</code> to <code>GetFirmwareUpdateCapabilities</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8194](https\://github\.com/ansible\-collections/community\.general/issues/8194)\, [https\://github\.com/ansible\-collections/community\.general/pull/8195](https\://github\.com/ansible\-collections/community\.general/pull/8195)\)\.
-* ssh\_config \- allow <code>accept\-new</code> as valid value for <code>strict\_host\_key\_checking</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8257](https\://github\.com/ansible\-collections/community\.general/pull/8257)\)\.
-
-<a id="deprecated-features"></a>
-### Deprecated Features
-
-* hipchat callback plugin \- the hipchat service has been discontinued and the self\-hosted variant has been End of Life since 2020\. The callback plugin is therefore deprecated and will be removed from community\.general 10\.0\.0 if nobody provides compelling reasons to still keep it \([https\://github\.com/ansible\-collections/community\.general/issues/8184](https\://github\.com/ansible\-collections/community\.general/issues/8184)\, [https\://github\.com/ansible\-collections/community\.general/pull/8189](https\://github\.com/ansible\-collections/community\.general/pull/8189)\)\.
+* ansible\_galaxy\_install \- minor refactor in the module \([https\://github\.com/ansible\-collections/community\.general/pull/8413](https\://github\.com/ansible\-collections/community\.general/pull/8413)\)\.
<a id="bugfixes"></a>
### Bugfixes
-* aix\_filesystem \- fix <code>\_validate\_vg</code> not passing VG name to <code>lsvg\_cmd</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8151](https\://github\.com/ansible\-collections/community\.general/issues/8151)\)\.
-* apt\_rpm \- when checking whether packages were installed after running <code>apt\-get \-y install \<packages\></code>\, only the last package name was checked \([https\://github\.com/ansible\-collections/community\.general/pull/8263](https\://github\.com/ansible\-collections/community\.general/pull/8263)\)\.
-* bitwarden\_secrets\_manager lookup plugin \- implements retry with exponential backoff to avoid lookup errors when Bitwardn\'s API rate limiting is encountered \([https\://github\.com/ansible\-collections/community\.general/issues/8230](https\://github\.com/ansible\-collections/community\.general/issues/8230)\, [https\://github\.com/ansible\-collections/community\.general/pull/8238](https\://github\.com/ansible\-collections/community\.general/pull/8238)\)\.
-* from\_ini filter plugin \- disabling interpolation of <code>ConfigParser</code> to allow converting values with a <code>\%</code> sign \([https\://github\.com/ansible\-collections/community\.general/issues/8183](https\://github\.com/ansible\-collections/community\.general/issues/8183)\, [https\://github\.com/ansible\-collections/community\.general/pull/8185](https\://github\.com/ansible\-collections/community\.general/pull/8185)\)\.
-* gitlab\_issue\, gitlab\_label\, gitlab\_milestone \- avoid crash during version comparison when the python\-gitlab Python module is not installed \([https\://github\.com/ansible\-collections/community\.general/pull/8158](https\://github\.com/ansible\-collections/community\.general/pull/8158)\)\.
-* haproxy \- fix an issue where HAProxy could get stuck in DRAIN mode when the backend was unreachable \([https\://github\.com/ansible\-collections/community\.general/issues/8092](https\://github\.com/ansible\-collections/community\.general/issues/8092)\)\.
-* inventory plugins \- add unsafe wrapper to avoid marking strings that do not contain <code>\{</code> or <code>\}</code> as unsafe\, to work around a bug in AWX \(\([https\://github\.com/ansible\-collections/community\.general/issues/8212](https\://github\.com/ansible\-collections/community\.general/issues/8212)\, [https\://github\.com/ansible\-collections/community\.general/pull/8225](https\://github\.com/ansible\-collections/community\.general/pull/8225)\)\.
-* ipa \- fix get version regex in IPA module\_utils \([https\://github\.com/ansible\-collections/community\.general/pull/8175](https\://github\.com/ansible\-collections/community\.general/pull/8175)\)\.
-* keycloak\_client \- add sorted <code>defaultClientScopes</code> and <code>optionalClientScopes</code> to normalizations \([https\://github\.com/ansible\-collections/community\.general/pull/8223](https\://github\.com/ansible\-collections/community\.general/pull/8223)\)\.
-* keycloak\_realm \- add normalizations for <code>enabledEventTypes</code> and <code>supportedLocales</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8224](https\://github\.com/ansible\-collections/community\.general/pull/8224)\)\.
-* puppet \- add option <code>environment\_lang</code> to set the environment language encoding\. Defaults to lang <code>C</code>\. It is recommended to set it to <code>C\.UTF\-8</code> or <code>en\_US\.UTF\-8</code> depending on what is available on your system\. \([https\://github\.com/ansible\-collections/community\.general/issues/8000](https\://github\.com/ansible\-collections/community\.general/issues/8000)\)
-* riak \- support <code>riak admin</code> sub\-command in newer Riak KV versions beside the legacy <code>riak\-admin</code> main command \([https\://github\.com/ansible\-collections/community\.general/pull/8211](https\://github\.com/ansible\-collections/community\.general/pull/8211)\)\.
-* to\_ini filter plugin \- disabling interpolation of <code>ConfigParser</code> to allow converting values with a <code>\%</code> sign \([https\://github\.com/ansible\-collections/community\.general/issues/8183](https\://github\.com/ansible\-collections/community\.general/issues/8183)\, [https\://github\.com/ansible\-collections/community\.general/pull/8185](https\://github\.com/ansible\-collections/community\.general/pull/8185)\)\.
-* xml \- make module work with lxml 5\.1\.1\, which removed some internals that the module was relying on \([https\://github\.com/ansible\-collections/community\.general/pull/8169](https\://github\.com/ansible\-collections/community\.general/pull/8169)\)\.
-
-<a id="new-modules"></a>
-### New Modules
-
-* keycloak\_client\_rolescope \- Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications\.
-
-<a id="v8-5-0"></a>
-## v8\.5\.0
+* cpanm \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* django module utils \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* gconftool2\_info \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* homebrew \- do not fail when brew prints warnings \([https\://github\.com/ansible\-collections/community\.general/pull/8406](https\://github\.com/ansible\-collections/community\.general/pull/8406)\, [https\://github\.com/ansible\-collections/community\.general/issues/7044](https\://github\.com/ansible\-collections/community\.general/issues/7044)\)\.
+* hponcfg \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* kernel\_blacklist \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* keycloak\_client \- fix TypeError when sanitizing the <code>saml\.signing\.private\.key</code> attribute in the module\'s diff or state output\. The <code>sanitize\_cr</code> function expected a dict where in some cases a list might occur \([https\://github\.com/ansible\-collections/community\.general/pull/8403](https\://github\.com/ansible\-collections/community\.general/pull/8403)\)\.
+* locale\_gen \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* mksysb \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* pipx\_info \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* snap \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+* snap\_alias \- use new <code>VarDict</code> to prevent deprecation warning \([https\://github\.com/ansible\-collections/community\.general/issues/8410](https\://github\.com/ansible\-collections/community\.general/issues/8410)\, [https\://github\.com/ansible\-collections/community\.general/pull/8411](https\://github\.com/ansible\-collections/community\.general/pull/8411)\)\.
+
+<a id="v9-0-0"></a>
+## v9\.0\.0
<a id="release-summary-1"></a>
### Release Summary
-Regular feature and bugfix release with security fixes\.
+This is release 9\.0\.0 of <code>community\.general</code>\, released on 2024\-05\-20\.
<a id="minor-changes-1"></a>
### Minor Changes
-* bitwarden lookup plugin \- allows to fetch all records of a given collection ID\, by allowing to pass an empty value for <code>search\_value</code> when <code>collection\_id</code> is provided \([https\://github\.com/ansible\-collections/community\.general/pull/8013](https\://github\.com/ansible\-collections/community\.general/pull/8013)\)\.
-* icinga2 inventory plugin \- adds new parameter <code>group\_by\_hostgroups</code> in order to make grouping by Icinga2 hostgroups optional \([https\://github\.com/ansible\-collections/community\.general/pull/7998](https\://github\.com/ansible\-collections/community\.general/pull/7998)\)\.
-* ini\_file \- support optional spaces between section names and their surrounding brackets \([https\://github\.com/ansible\-collections/community\.general/pull/8075](https\://github\.com/ansible\-collections/community\.general/pull/8075)\)\.
-* java\_cert \- enable <code>owner</code>\, <code>group</code>\, <code>mode</code>\, and other generic file arguments \([https\://github\.com/ansible\-collections/community\.general/pull/8116](https\://github\.com/ansible\-collections/community\.general/pull/8116)\)\.
-* ldap\_attrs \- module now supports diff mode\, showing which attributes are changed within an operation \([https\://github\.com/ansible\-collections/community\.general/pull/8073](https\://github\.com/ansible\-collections/community\.general/pull/8073)\)\.
-* lxd\_container \- uses <code>/1\.0/instances</code> API endpoint\, if available\. Falls back to <code>/1\.0/containers</code> or <code>/1\.0/virtual\-machines</code>\. Fixes issue when using Incus or LXD 5\.19 due to migrating to <code>/1\.0/instances</code> endpoint \([https\://github\.com/ansible\-collections/community\.general/pull/7980](https\://github\.com/ansible\-collections/community\.general/pull/7980)\)\.
-* nmcli \- allow setting <code>MTU</code> for <code>bond\-slave</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/8118](https\://github\.com/ansible\-collections/community\.general/pull/8118)\)\.
-* proxmox \- adds <code>startup</code> parameters to configure startup order\, startup delay and shutdown delay \([https\://github\.com/ansible\-collections/community\.general/pull/8038](https\://github\.com/ansible\-collections/community\.general/pull/8038)\)\.
-* revbitspss lookup plugin \- removed a redundant unicode prefix\. The prefix was not necessary for Python 3 and has been cleaned up to streamline the code \([https\://github\.com/ansible\-collections/community\.general/pull/8087](https\://github\.com/ansible\-collections/community\.general/pull/8087)\)\.
-
-<a id="security-fixes"></a>
-### Security Fixes
-
-* cobbler\, gitlab\_runners\, icinga2\, linode\, lxd\, nmap\, online\, opennebula\, proxmox\, scaleway\, stackpath\_compute\, virtualbox\, and xen\_orchestra inventory plugin \- make sure all data received from the remote servers is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.general/pull/8098](https\://github\.com/ansible\-collections/community\.general/pull/8098)\)\.
-
-<a id="bugfixes-1"></a>
-### Bugfixes
-
-* aix\_filesystem \- fix issue with empty list items in crfs logic and option order \([https\://github\.com/ansible\-collections/community\.general/pull/8052](https\://github\.com/ansible\-collections/community\.general/pull/8052)\)\.
-* consul\_token \- fix token creation without <code>accessor\_id</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8091](https\://github\.com/ansible\-collections/community\.general/pull/8091)\)\.
-* homebrew \- error returned from brew command was ignored and tried to parse empty JSON\. Fix now checks for an error and raises it to give accurate error message to users \([https\://github\.com/ansible\-collections/community\.general/issues/8047](https\://github\.com/ansible\-collections/community\.general/issues/8047)\)\.
-* ipa\_hbacrule \- the module uses a string for <code>ipaenabledflag</code> for new FreeIPA versions while the returned value is a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7880](https\://github\.com/ansible\-collections/community\.general/pull/7880)\)\.
-* ipa\_sudorule \- the module uses a string for <code>ipaenabledflag</code> for new FreeIPA versions while the returned value is a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7880](https\://github\.com/ansible\-collections/community\.general/pull/7880)\)\.
-* iptables\_state \- fix idempotency issues when restoring incomplete iptables dumps \([https\://github\.com/ansible\-collections/community\.general/issues/8029](https\://github\.com/ansible\-collections/community\.general/issues/8029)\)\.
-* linode inventory plugin \- add descriptive error message for linode inventory plugin \([https\://github\.com/ansible\-collections/community\.general/pull/8133](https\://github\.com/ansible\-collections/community\.general/pull/8133)\)\.
-* pacemaker\_cluster \- actually implement check mode\, which the module claims to support\. This means that until now the module also did changes in check mode \([https\://github\.com/ansible\-collections/community\.general/pull/8081](https\://github\.com/ansible\-collections/community\.general/pull/8081)\)\.
-* pam\_limits \- when the file does not exist\, do not create it in check mode \([https\://github\.com/ansible\-collections/community\.general/issues/8050](https\://github\.com/ansible\-collections/community\.general/issues/8050)\, [https\://github\.com/ansible\-collections/community\.general/pull/8057](https\://github\.com/ansible\-collections/community\.general/pull/8057)\)\.
-* proxmox\_kvm \- fixed status check getting from node\-specific API endpoint \([https\://github\.com/ansible\-collections/community\.general/issues/7817](https\://github\.com/ansible\-collections/community\.general/issues/7817)\)\.
-
-<a id="new-modules-1"></a>
-### New Modules
-
-* usb\_facts \- Allows listing information about USB devices
-
-<a id="v8-4-0"></a>
-## v8\.4\.0
-
-<a id="release-summary-2"></a>
-### Release Summary
-
-Regular bugfix and feature release\.
-
-<a id="minor-changes-2"></a>
-### Minor Changes
-
+* PythonRunner module utils \- specialisation of <code>CmdRunner</code> to execute Python scripts \([https\://github\.com/ansible\-collections/community\.general/pull/8289](https\://github\.com/ansible\-collections/community\.general/pull/8289)\)\.
+* Use offset\-aware <code>datetime\.datetime</code> objects \(with timezone UTC\) instead of offset\-naive UTC timestamps\, which are deprecated in Python 3\.12 \([https\://github\.com/ansible\-collections/community\.general/pull/8222](https\://github\.com/ansible\-collections/community\.general/pull/8222)\)\.
+* aix\_lvol \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* apt\_rpm \- add new states <code>latest</code> and <code>present\_not\_latest</code>\. The value <code>latest</code> is equivalent to the current behavior of <code>present</code>\, which will upgrade a package if a newer version exists\. <code>present\_not\_latest</code> does what most users would expect <code>present</code> to do\: it does not upgrade if the package is already installed\. The current behavior of <code>present</code> will be deprecated in a later version\, and eventually changed to that of <code>present\_not\_latest</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8217](https\://github\.com/ansible\-collections/community\.general/issues/8217)\, [https\://github\.com/ansible\-collections/community\.general/pull/8247](https\://github\.com/ansible\-collections/community\.general/pull/8247)\)\.
+* apt\_rpm \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
* bitwarden lookup plugin \- add <code>bw\_session</code> option\, to pass session key instead of reading from env \([https\://github\.com/ansible\-collections/community\.general/pull/7994](https\://github\.com/ansible\-collections/community\.general/pull/7994)\)\.
-* gitlab\_deploy\_key\, gitlab\_group\_members\, gitlab\_group\_variable\, gitlab\_hook\, gitlab\_instance\_variable\, gitlab\_project\_badge\, gitlab\_project\_variable\, gitlab\_user \- improve API pagination and compatibility with different versions of <code>python\-gitlab</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7790](https\://github\.com/ansible\-collections/community\.general/pull/7790)\)\.
-* gitlab\_hook \- adds <code>releases\_events</code> parameter for supporting Releases events triggers on GitLab hooks \([https\://github\.com/ansible\-collections/community\.general/pull/7956](https\://github\.com/ansible\-collections/community\.general/pull/7956)\)\.
-* icinga2 inventory plugin \- add Jinja2 templating support to <code>url</code>\, <code>user</code>\, and <code>password</code> paramenters \([https\://github\.com/ansible\-collections/community\.general/issues/7074](https\://github\.com/ansible\-collections/community\.general/issues/7074)\, [https\://github\.com/ansible\-collections/community\.general/pull/7996](https\://github\.com/ansible\-collections/community\.general/pull/7996)\)\.
-* mssql\_script \- adds transactional \(rollback/commit\) support via optional boolean param <code>transaction</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7976](https\://github\.com/ansible\-collections/community\.general/pull/7976)\)\.
-* proxmox\_kvm \- add parameter <code>update\_unsafe</code> to avoid limitations when updating dangerous values \([https\://github\.com/ansible\-collections/community\.general/pull/7843](https\://github\.com/ansible\-collections/community\.general/pull/7843)\)\.
-* redfish\_config \- add command <code>SetServiceIdentification</code> to set service identification \([https\://github\.com/ansible\-collections/community\.general/issues/7916](https\://github\.com/ansible\-collections/community\.general/issues/7916)\)\.
-* sudoers \- add support for the <code>NOEXEC</code> tag in sudoers rules \([https\://github\.com/ansible\-collections/community\.general/pull/7983](https\://github\.com/ansible\-collections/community\.general/pull/7983)\)\.
-* terraform \- fix <code>diff\_mode</code> in state <code>absent</code> and when terraform <code>resource\_changes</code> does not exist \([https\://github\.com/ansible\-collections/community\.general/pull/7963](https\://github\.com/ansible\-collections/community\.general/pull/7963)\)\.
-
-<a id="bugfixes-2"></a>
-### Bugfixes
-
-* cargo \- fix idempotency issues when using a custom installation path for packages \(using the <code>\-\-path</code> parameter\)\. The initial installation runs fine\, but subsequent runs use the <code>get\_installed\(\)</code> function which did not check the given installation location\, before running <code>cargo install</code>\. This resulted in a false <code>changed</code> state\. Also the removal of packeges using <code>state\: absent</code> failed\, as the installation check did not use the given parameter \([https\://github\.com/ansible\-collections/community\.general/pull/7970](https\://github\.com/ansible\-collections/community\.general/pull/7970)\)\.
-* gitlab\_issue \- fix behavior to search GitLab issue\, using <code>search</code> keyword instead of <code>title</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7846](https\://github\.com/ansible\-collections/community\.general/issues/7846)\)\.
-* gitlab\_runner \- fix pagination when checking for existing runners \([https\://github\.com/ansible\-collections/community\.general/pull/7790](https\://github\.com/ansible\-collections/community\.general/pull/7790)\)\.
-* keycloak\_client \- fixes issue when metadata is provided in desired state when task is in check mode \([https\://github\.com/ansible\-collections/community\.general/issues/1226](https\://github\.com/ansible\-collections/community\.general/issues/1226)\, [https\://github\.com/ansible\-collections/community\.general/pull/7881](https\://github\.com/ansible\-collections/community\.general/pull/7881)\)\.
-* modprobe \- listing modules files or modprobe files could trigger a FileNotFoundError if <code>/etc/modprobe\.d</code> or <code>/etc/modules\-load\.d</code> did not exist\. Relevant functions now return empty lists if the directories do not exist to avoid crashing the module \([https\://github\.com/ansible\-collections/community\.general/issues/7717](https\://github\.com/ansible\-collections/community\.general/issues/7717)\)\.
-* onepassword lookup plugin \- failed for fields that were in sections and had uppercase letters in the label/ID\. Field lookups are now case insensitive in all cases \([https\://github\.com/ansible\-collections/community\.general/pull/7919](https\://github\.com/ansible\-collections/community\.general/pull/7919)\)\.
-* pkgin \- pkgin \(pkgsrc package manager used by SmartOS\) raises erratic exceptions and spurious <code>changed\=true</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7971](https\://github\.com/ansible\-collections/community\.general/pull/7971)\)\.
-* redfish\_info \- allow for a GET operation invoked by <code>GetUpdateStatus</code> to allow for an empty response body for cases where a service returns 204 No Content \([https\://github\.com/ansible\-collections/community\.general/issues/8003](https\://github\.com/ansible\-collections/community\.general/issues/8003)\)\.
-* redfish\_info \- correct uncaught exception when attempting to retrieve <code>Chassis</code> information \([https\://github\.com/ansible\-collections/community\.general/pull/7952](https\://github\.com/ansible\-collections/community\.general/pull/7952)\)\.
-
-<a id="new-plugins"></a>
-### New Plugins
-
-<a id="callback"></a>
-#### Callback
-
-* default\_without\_diff \- The default ansible callback without diff output
-
-<a id="filter"></a>
-#### Filter
-
-* lists\_difference \- Difference of lists with a predictive order
-* lists\_intersect \- Intersection of lists with a predictive order
-* lists\_symmetric\_difference \- Symmetric Difference of lists with a predictive order
-* lists\_union \- Union of lists with a predictive order
-
-<a id="new-modules-2"></a>
-### New Modules
-
-* gitlab\_group\_access\_token \- Manages GitLab group access tokens
-* gitlab\_project\_access\_token \- Manages GitLab project access tokens
-
-<a id="v8-3-0"></a>
-## v8\.3\.0
-
-<a id="release-summary-3"></a>
-### Release Summary
-
-Regular bugfix and feature release\.
-
-<a id="minor-changes-3"></a>
-### Minor Changes
-
+* bitwarden lookup plugin \- add support to filter by organization ID \([https\://github\.com/ansible\-collections/community\.general/pull/8188](https\://github\.com/ansible\-collections/community\.general/pull/8188)\)\.
+* bitwarden lookup plugin \- allows to fetch all records of a given collection ID\, by allowing to pass an empty value for <code>search\_value</code> when <code>collection\_id</code> is provided \([https\://github\.com/ansible\-collections/community\.general/pull/8013](https\://github\.com/ansible\-collections/community\.general/pull/8013)\)\.
+* bitwarden lookup plugin \- when looking for items using an item ID\, the item is now accessed directly with <code>bw get item</code> instead of searching through all items\. This doubles the lookup speed \([https\://github\.com/ansible\-collections/community\.general/pull/7468](https\://github\.com/ansible\-collections/community\.general/pull/7468)\)\.
+* btrfs\_subvolume \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* cmd\_runner module\_utils \- add validation for minimum and maximum length in the value passed to <code>cmd\_runner\_fmt\.as\_list\(\)</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8288](https\://github\.com/ansible\-collections/community\.general/pull/8288)\)\.
* consul\_auth\_method\, consul\_binding\_rule\, consul\_policy\, consul\_role\, consul\_session\, consul\_token \- added action group <code>community\.general\.consul</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7897](https\://github\.com/ansible\-collections/community\.general/pull/7897)\)\.
* consul\_policy \- added support for diff and check mode \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
* consul\_policy\, consul\_role\, consul\_session \- removed dependency on <code>requests</code> and factored out common parts \([https\://github\.com/ansible\-collections/community\.general/pull/7826](https\://github\.com/ansible\-collections/community\.general/pull/7826)\, [https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
@@ -237,532 +82,289 @@ Regular bugfix and feature release\.
* consul\_role \- <code>service\_identities</code> now expects a <code>service\_name</code> option to match the Consul API\, the old <code>name</code> is still supported as alias \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
* consul\_role \- added support for diff mode \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
* consul\_role \- added support for templated policies \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
-* redfish\_info \- add command <code>GetServiceIdentification</code> to get service identification \([https\://github\.com/ansible\-collections/community\.general/issues/7882](https\://github\.com/ansible\-collections/community\.general/issues/7882)\)\.
-* terraform \- add support for <code>diff\_mode</code> for terraform resource\_changes \([https\://github\.com/ansible\-collections/community\.general/pull/7896](https\://github\.com/ansible\-collections/community\.general/pull/7896)\)\.
-
-<a id="deprecated-features-1"></a>
-### Deprecated Features
-
-* consul\_acl \- the module has been deprecated and will be removed in community\.general 10\.0\.0\. <code>consul\_token</code> and <code>consul\_policy</code> can be used instead \([https\://github\.com/ansible\-collections/community\.general/pull/7901](https\://github\.com/ansible\-collections/community\.general/pull/7901)\)\.
-
-<a id="bugfixes-3"></a>
-### Bugfixes
-
-* homebrew \- detect already installed formulae and casks using JSON output from <code>brew info</code> \([https\://github\.com/ansible\-collections/community\.general/issues/864](https\://github\.com/ansible\-collections/community\.general/issues/864)\)\.
-* incus connection plugin \- treats <code>inventory\_hostname</code> as a variable instead of a literal in remote connections \([https\://github\.com/ansible\-collections/community\.general/issues/7874](https\://github\.com/ansible\-collections/community\.general/issues/7874)\)\.
-* ipa\_otptoken \- the module expect <code>ipatokendisabled</code> as string but the <code>ipatokendisabled</code> value is returned as a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7795](https\://github\.com/ansible\-collections/community\.general/pull/7795)\)\.
-* ldap \- previously the order number \(if present\) was expected to follow an equals sign in the DN\. This makes it so the order number string is identified correctly anywhere within the DN \([https\://github\.com/ansible\-collections/community\.general/issues/7646](https\://github\.com/ansible\-collections/community\.general/issues/7646)\)\.
-* mssql\_script \- make the module work with Python 2 \([https\://github\.com/ansible\-collections/community\.general/issues/7818](https\://github\.com/ansible\-collections/community\.general/issues/7818)\, [https\://github\.com/ansible\-collections/community\.general/pull/7821](https\://github\.com/ansible\-collections/community\.general/pull/7821)\)\.
-* nmcli \- fix <code>connection\.slave\-type</code> wired to <code>bond</code> and not with parameter <code>slave\_type</code> in case of connection type <code>wifi</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7389](https\://github\.com/ansible\-collections/community\.general/issues/7389)\)\.
-* proxmox \- fix updating a container config if the setting does not already exist \([https\://github\.com/ansible\-collections/community\.general/pull/7872](https\://github\.com/ansible\-collections/community\.general/pull/7872)\)\.
-
-<a id="new-modules-3"></a>
-### New Modules
-
-* consul\_acl\_bootstrap \- Bootstrap ACLs in Consul
-* consul\_auth\_method \- Manipulate Consul auth methods
-* consul\_binding\_rule \- Manipulate Consul binding rules
-* consul\_token \- Manipulate Consul tokens
-* gitlab\_label \- Creates/updates/deletes GitLab Labels belonging to project or group\.
-* gitlab\_milestone \- Creates/updates/deletes GitLab Milestones belonging to project or group
-
-<a id="v8-2-0"></a>
-## v8\.2\.0
-
-<a id="release-summary-4"></a>
-### Release Summary
-
-Regular bugfix and feature release\.
-
-<a id="minor-changes-4"></a>
-### Minor Changes
-
-* ipa\_dnsrecord \- adds ability to manage NS record types \([https\://github\.com/ansible\-collections/community\.general/pull/7737](https\://github\.com/ansible\-collections/community\.general/pull/7737)\)\.
-* ipa\_pwpolicy \- refactor module and exchange a sequence <code>if</code> statements with a <code>for</code> loop \([https\://github\.com/ansible\-collections/community\.general/pull/7723](https\://github\.com/ansible\-collections/community\.general/pull/7723)\)\.
-* ipa\_pwpolicy \- update module to support <code>maxrepeat</code>\, <code>maxsequence</code>\, <code>dictcheck</code>\, <code>usercheck</code>\, <code>gracelimit</code> parameters in FreeIPA password policies \([https\://github\.com/ansible\-collections/community\.general/pull/7723](https\://github\.com/ansible\-collections/community\.general/pull/7723)\)\.
-* keycloak\_realm\_key \- the <code>config\.algorithm</code> option now supports 8 additional key algorithms \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
-* keycloak\_realm\_key \- the <code>config\.certificate</code> option value is no longer defined with <code>no\_log\=True</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
-* keycloak\_realm\_key \- the <code>provider\_id</code> option now supports RSA encryption key usage \(value <code>rsa\-enc</code>\) \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
-* keycloak\_user\_federation \- allow custom user storage providers to be set through <code>provider\_id</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7789](https\://github\.com/ansible\-collections/community\.general/pull/7789)\)\.
-* mail \- add <code>Message\-ID</code> header\; which is required by some mail servers \([https\://github\.com/ansible\-collections/community\.general/pull/7740](https\://github\.com/ansible\-collections/community\.general/pull/7740)\)\.
-* mail module\, mail callback plugin \- allow to configure the domain name of the Message\-ID header with a new <code>message\_id\_domain</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7765](https\://github\.com/ansible\-collections/community\.general/pull/7765)\)\.
-* ssh\_config \- new feature to set <code>AddKeysToAgent</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7703](https\://github\.com/ansible\-collections/community\.general/pull/7703)\)\.
-* ssh\_config \- new feature to set <code>IdentitiesOnly</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7704](https\://github\.com/ansible\-collections/community\.general/pull/7704)\)\.
-* xcc\_redfish\_command \- added support for raw POSTs \(<code>command\=PostResource</code> in <code>category\=Raw</code>\) without a specific action info \([https\://github\.com/ansible\-collections/community\.general/pull/7746](https\://github\.com/ansible\-collections/community\.general/pull/7746)\)\.
-
-<a id="bugfixes-4"></a>
-### Bugfixes
-
-* keycloak\_identity\_provider \- <code>mappers</code> processing was not idempotent if the mappers configuration list had not been sorted by name \(in ascending order\)\. Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
-* keycloak\_identity\_provider \- it was not possible to reconfigure \(add\, remove\) <code>mappers</code> once they were created initially\. Removal was ignored\, adding new ones resulted in dropping the pre\-existing unmodified mappers\. Fix resolves the issue by supplying correct input to the internal update call \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
-* keycloak\_user \- when <code>force</code> is set\, but user does not exist\, do not try to delete it \([https\://github\.com/ansible\-collections/community\.general/pull/7696](https\://github\.com/ansible\-collections/community\.general/pull/7696)\)\.
-* proxmox\_kvm \- running <code>state\=template</code> will first check whether VM is already a template \([https\://github\.com/ansible\-collections/community\.general/pull/7792](https\://github\.com/ansible\-collections/community\.general/pull/7792)\)\.
-* statusio\_maintenance \- fix error caused by incorrectly formed API data payload\. Was raising \"Failed to create maintenance HTTP Error 400 Bad Request\" caused by bad data type for date/time and deprecated dict keys \([https\://github\.com/ansible\-collections/community\.general/pull/7754](https\://github\.com/ansible\-collections/community\.general/pull/7754)\)\.
-
-<a id="new-plugins-1"></a>
-### New Plugins
-
-<a id="connection"></a>
-#### Connection
-
-* incus \- Run tasks in Incus instances via the Incus CLI\.
-
-<a id="filter-1"></a>
-#### Filter
-
-* from\_ini \- Converts INI text input into a dictionary
-* to\_ini \- Converts a dictionary to the INI file format
-
-<a id="lookup"></a>
-#### Lookup
-
-* github\_app\_access\_token \- Obtain short\-lived Github App Access tokens
-
-<a id="new-modules-4"></a>
-### New Modules
-
-* dnf\_config\_manager \- Enable or disable dnf repositories using config\-manager
-* keycloak\_component\_info \- Retrive component info in Keycloak
-* keycloak\_realm\_rolemapping \- Allows administration of Keycloak realm role mappings into groups with the Keycloak API
-* proxmox\_node\_info \- Retrieve information about one or more Proxmox VE nodes
-* proxmox\_storage\_contents\_info \- List content from a Proxmox VE storage
-
-<a id="v8-1-0"></a>
-## v8\.1\.0
-
-<a id="release-summary-5"></a>
-### Release Summary
-
-Regular bugfix and feature release\.
-
-<a id="minor-changes-5"></a>
-### Minor Changes
-
-* bitwarden lookup plugin \- when looking for items using an item ID\, the item is now accessed directly with <code>bw get item</code> instead of searching through all items\. This doubles the lookup speed \([https\://github\.com/ansible\-collections/community\.general/pull/7468](https\://github\.com/ansible\-collections/community\.general/pull/7468)\)\.
* elastic callback plugin \- close elastic client to not leak resources \([https\://github\.com/ansible\-collections/community\.general/pull/7517](https\://github\.com/ansible\-collections/community\.general/pull/7517)\)\.
+* filesystem \- add bcachefs support \([https\://github\.com/ansible\-collections/community\.general/pull/8126](https\://github\.com/ansible\-collections/community\.general/pull/8126)\)\.
+* gandi\_livedns \- adds support for personal access tokens \([https\://github\.com/ansible\-collections/community\.general/issues/7639](https\://github\.com/ansible\-collections/community\.general/issues/7639)\, [https\://github\.com/ansible\-collections/community\.general/pull/8337](https\://github\.com/ansible\-collections/community\.general/pull/8337)\)\.
+* gconftool2 \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
* git\_config \- allow multiple git configs for the same name with the new <code>add\_mode</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7260](https\://github\.com/ansible\-collections/community\.general/pull/7260)\)\.
* git\_config \- the <code>after</code> and <code>before</code> fields in the <code>diff</code> of the return value can be a list instead of a string in case more configs with the same key are affected \([https\://github\.com/ansible\-collections/community\.general/pull/7260](https\://github\.com/ansible\-collections/community\.general/pull/7260)\)\.
* git\_config \- when a value is unset\, all configs with the same key are unset \([https\://github\.com/ansible\-collections/community\.general/pull/7260](https\://github\.com/ansible\-collections/community\.general/pull/7260)\)\.
* gitlab modules \- add <code>ca\_path</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7472](https\://github\.com/ansible\-collections/community\.general/pull/7472)\)\.
* gitlab modules \- remove duplicate <code>gitlab</code> package check \([https\://github\.com/ansible\-collections/community\.general/pull/7486](https\://github\.com/ansible\-collections/community\.general/pull/7486)\)\.
+* gitlab\_deploy\_key\, gitlab\_group\_members\, gitlab\_group\_variable\, gitlab\_hook\, gitlab\_instance\_variable\, gitlab\_project\_badge\, gitlab\_project\_variable\, gitlab\_user \- improve API pagination and compatibility with different versions of <code>python\-gitlab</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7790](https\://github\.com/ansible\-collections/community\.general/pull/7790)\)\.
+* gitlab\_hook \- adds <code>releases\_events</code> parameter for supporting Releases events triggers on GitLab hooks \([https\://github\.com/ansible\-collections/community\.general/pull/7956](https\://github\.com/ansible\-collections/community\.general/pull/7956)\)\.
* gitlab\_runner \- add support for new runner creation workflow \([https\://github\.com/ansible\-collections/community\.general/pull/7199](https\://github\.com/ansible\-collections/community\.general/pull/7199)\)\.
+* homebrew \- adds <code>force\_formula</code> parameter to disambiguate a formula from a cask of the same name \([https\://github\.com/ansible\-collections/community\.general/issues/8274](https\://github\.com/ansible\-collections/community\.general/issues/8274)\)\.
+* homebrew\, homebrew\_cask \- refactor common argument validation logic into a dedicated <code>homebrew</code> module utils \([https\://github\.com/ansible\-collections/community\.general/issues/8323](https\://github\.com/ansible\-collections/community\.general/issues/8323)\, [https\://github\.com/ansible\-collections/community\.general/pull/8324](https\://github\.com/ansible\-collections/community\.general/pull/8324)\)\.
+* icinga2 inventory plugin \- add Jinja2 templating support to <code>url</code>\, <code>user</code>\, and <code>password</code> paramenters \([https\://github\.com/ansible\-collections/community\.general/issues/7074](https\://github\.com/ansible\-collections/community\.general/issues/7074)\, [https\://github\.com/ansible\-collections/community\.general/pull/7996](https\://github\.com/ansible\-collections/community\.general/pull/7996)\)\.
+* icinga2 inventory plugin \- adds new parameter <code>group\_by\_hostgroups</code> in order to make grouping by Icinga2 hostgroups optional \([https\://github\.com/ansible\-collections/community\.general/pull/7998](https\://github\.com/ansible\-collections/community\.general/pull/7998)\)\.
+* ini\_file \- add an optional parameter <code>section\_has\_values</code>\. If the target ini file contains more than one <code>section</code>\, use <code>section\_has\_values</code> to specify which one should be updated \([https\://github\.com/ansible\-collections/community\.general/pull/7505](https\://github\.com/ansible\-collections/community\.general/pull/7505)\)\.
+* ini\_file \- support optional spaces between section names and their surrounding brackets \([https\://github\.com/ansible\-collections/community\.general/pull/8075](https\://github\.com/ansible\-collections/community\.general/pull/8075)\)\.
+* installp \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
* ipa\_config \- adds <code>passkey</code> choice to <code>ipauserauthtype</code> parameter\'s choices \([https\://github\.com/ansible\-collections/community\.general/pull/7588](https\://github\.com/ansible\-collections/community\.general/pull/7588)\)\.
+* ipa\_dnsrecord \- adds ability to manage NS record types \([https\://github\.com/ansible\-collections/community\.general/pull/7737](https\://github\.com/ansible\-collections/community\.general/pull/7737)\)\.
+* ipa\_pwpolicy \- refactor module and exchange a sequence <code>if</code> statements with a <code>for</code> loop \([https\://github\.com/ansible\-collections/community\.general/pull/7723](https\://github\.com/ansible\-collections/community\.general/pull/7723)\)\.
+* ipa\_pwpolicy \- update module to support <code>maxrepeat</code>\, <code>maxsequence</code>\, <code>dictcheck</code>\, <code>usercheck</code>\, <code>gracelimit</code> parameters in FreeIPA password policies \([https\://github\.com/ansible\-collections/community\.general/pull/7723](https\://github\.com/ansible\-collections/community\.general/pull/7723)\)\.
* ipa\_sudorule \- adds options to include denied commands or command groups \([https\://github\.com/ansible\-collections/community\.general/pull/7415](https\://github\.com/ansible\-collections/community\.general/pull/7415)\)\.
* ipa\_user \- adds <code>idp</code> and <code>passkey</code> choice to <code>ipauserauthtype</code> parameter\'s choices \([https\://github\.com/ansible\-collections/community\.general/pull/7589](https\://github\.com/ansible\-collections/community\.general/pull/7589)\)\.
* irc \- add <code>validate\_certs</code> option\, and rename <code>use\_ssl</code> to <code>use\_tls</code>\, while keeping <code>use\_ssl</code> as an alias\. The default value for <code>validate\_certs</code> is <code>false</code> for backwards compatibility\. We recommend to every user of this module to explicitly set <code>use\_tls\=true</code> and <em class="title-reference">validate\_certs\=true\`</em> whenever possible\, especially when communicating to IRC servers over the internet \([https\://github\.com/ansible\-collections/community\.general/pull/7550](https\://github\.com/ansible\-collections/community\.general/pull/7550)\)\.
+* java\_cert \- add <code>cert\_content</code> argument \([https\://github\.com/ansible\-collections/community\.general/pull/8153](https\://github\.com/ansible\-collections/community\.general/pull/8153)\)\.
+* java\_cert \- enable <code>owner</code>\, <code>group</code>\, <code>mode</code>\, and other generic file arguments \([https\://github\.com/ansible\-collections/community\.general/pull/8116](https\://github\.com/ansible\-collections/community\.general/pull/8116)\)\.
+* kernel\_blacklist \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
* keycloak module utils \- expose error message from Keycloak server for HTTP errors in some specific situations \([https\://github\.com/ansible\-collections/community\.general/pull/7645](https\://github\.com/ansible\-collections/community\.general/pull/7645)\)\.
+* keycloak\_client\, keycloak\_clientscope\, keycloak\_clienttemplate \- added <code>docker\-v2</code> protocol support\, enhancing alignment with Keycloak\'s protocol options \([https\://github\.com/ansible\-collections/community\.general/issues/8215](https\://github\.com/ansible\-collections/community\.general/issues/8215)\, [https\://github\.com/ansible\-collections/community\.general/pull/8216](https\://github\.com/ansible\-collections/community\.general/pull/8216)\)\.
+* keycloak\_realm\_key \- the <code>config\.algorithm</code> option now supports 8 additional key algorithms \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
+* keycloak\_realm\_key \- the <code>config\.certificate</code> option value is no longer defined with <code>no\_log\=True</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
+* keycloak\_realm\_key \- the <code>provider\_id</code> option now supports RSA encryption key usage \(value <code>rsa\-enc</code>\) \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
* keycloak\_user\_federation \- add option for <code>krbPrincipalAttribute</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7538](https\://github\.com/ansible\-collections/community\.general/pull/7538)\)\.
+* keycloak\_user\_federation \- allow custom user storage providers to be set through <code>provider\_id</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7789](https\://github\.com/ansible\-collections/community\.general/pull/7789)\)\.
+* ldap\_attrs \- module now supports diff mode\, showing which attributes are changed within an operation \([https\://github\.com/ansible\-collections/community\.general/pull/8073](https\://github\.com/ansible\-collections/community\.general/pull/8073)\)\.
+* lvg \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
* lvol \- change <code>pvs</code> argument type to list of strings \([https\://github\.com/ansible\-collections/community\.general/pull/7676](https\://github\.com/ansible\-collections/community\.general/pull/7676)\, [https\://github\.com/ansible\-collections/community\.general/issues/7504](https\://github\.com/ansible\-collections/community\.general/issues/7504)\)\.
+* lvol \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
* lxd connection plugin \- tighten the detection logic for lxd <code>Instance not found</code> errors\, to avoid false detection on unrelated errors such as <code>/usr/bin/python3\: not found</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7521](https\://github\.com/ansible\-collections/community\.general/pull/7521)\)\.
+* lxd\_container \- uses <code>/1\.0/instances</code> API endpoint\, if available\. Falls back to <code>/1\.0/containers</code> or <code>/1\.0/virtual\-machines</code>\. Fixes issue when using Incus or LXD 5\.19 due to migrating to <code>/1\.0/instances</code> endpoint \([https\://github\.com/ansible\-collections/community\.general/pull/7980](https\://github\.com/ansible\-collections/community\.general/pull/7980)\)\.
+* macports \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* mail \- add <code>Message\-ID</code> header\; which is required by some mail servers \([https\://github\.com/ansible\-collections/community\.general/pull/7740](https\://github\.com/ansible\-collections/community\.general/pull/7740)\)\.
+* mail module\, mail callback plugin \- allow to configure the domain name of the Message\-ID header with a new <code>message\_id\_domain</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7765](https\://github\.com/ansible\-collections/community\.general/pull/7765)\)\.
+* mssql\_script \- adds transactional \(rollback/commit\) support via optional boolean param <code>transaction</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7976](https\://github\.com/ansible\-collections/community\.general/pull/7976)\)\.
* netcup\_dns \- adds support for record types <code>OPENPGPKEY</code>\, <code>SMIMEA</code>\, and <code>SSHFP</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7489](https\://github\.com/ansible\-collections/community\.general/pull/7489)\)\.
* nmcli \- add support for new connection type <code>loopback</code> \([https\://github\.com/ansible\-collections/community\.general/issues/6572](https\://github\.com/ansible\-collections/community\.general/issues/6572)\)\.
+* nmcli \- adds OpenvSwitch support with new <code>type</code> values <code>ovs\-port</code>\, <code>ovs\-interface</code>\, and <code>ovs\-bridge</code>\, and new <code>slave\_type</code> value <code>ovs\-port</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8154](https\://github\.com/ansible\-collections/community\.general/pull/8154)\)\.
* nmcli \- allow for <code>infiniband</code> slaves of <code>bond</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/7569](https\://github\.com/ansible\-collections/community\.general/pull/7569)\)\.
* nmcli \- allow for the setting of <code>MTU</code> for <code>infiniband</code> and <code>bond</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/7499](https\://github\.com/ansible\-collections/community\.general/pull/7499)\)\.
+* nmcli \- allow setting <code>MTU</code> for <code>bond\-slave</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/8118](https\://github\.com/ansible\-collections/community\.general/pull/8118)\)\.
* onepassword lookup plugin \- support 1Password Connect with the opv2 client by setting the connect\_host and connect\_token parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7116](https\://github\.com/ansible\-collections/community\.general/pull/7116)\)\.
* onepassword\_raw lookup plugin \- support 1Password Connect with the opv2 client by setting the connect\_host and connect\_token parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7116](https\://github\.com/ansible\-collections/community\.general/pull/7116)\)
+* opentelemetry \- add support for HTTP trace\_exporter and configures the behavior via <code>OTEL\_EXPORTER\_OTLP\_TRACES\_PROTOCOL</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7888](https\://github\.com/ansible\-collections/community\.general/issues/7888)\, [https\://github\.com/ansible\-collections/community\.general/pull/8321](https\://github\.com/ansible\-collections/community\.general/pull/8321)\)\.
+* opentelemetry \- add support for exporting spans in a file via <code>ANSIBLE\_OPENTELEMETRY\_STORE\_SPANS\_IN\_FILE</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7888](https\://github\.com/ansible\-collections/community\.general/issues/7888)\, [https\://github\.com/ansible\-collections/community\.general/pull/8363](https\://github\.com/ansible\-collections/community\.general/pull/8363)\)\.
+* opkg \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
+* osx\_defaults \- add option <code>check\_types</code> to enable changing the type of existing defaults on the fly \([https\://github\.com/ansible\-collections/community\.general/pull/8173](https\://github\.com/ansible\-collections/community\.general/pull/8173)\)\.
+* parted \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
* passwordstore \- adds <code>timestamp</code> and <code>preserve</code> parameters to modify the stored password format \([https\://github\.com/ansible\-collections/community\.general/pull/7426](https\://github\.com/ansible\-collections/community\.general/pull/7426)\)\.
+* passwordstore lookup \- add <code>missing\_subkey</code> parameter defining the behavior of the lookup when a passwordstore subkey is missing \([https\://github\.com/ansible\-collections/community\.general/pull/8166](https\://github\.com/ansible\-collections/community\.general/pull/8166)\)\.
+* pipx \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
+* pkg5 \- add support for non\-silent execution \([https\://github\.com/ansible\-collections/community\.general/issues/8379](https\://github\.com/ansible\-collections/community\.general/issues/8379)\, [https\://github\.com/ansible\-collections/community\.general/pull/8382](https\://github\.com/ansible\-collections/community\.general/pull/8382)\)\.
+* pkgin \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* portage \- adds the possibility to explicitely tell portage to write packages to world file \([https\://github\.com/ansible\-collections/community\.general/issues/6226](https\://github\.com/ansible\-collections/community\.general/issues/6226)\, [https\://github\.com/ansible\-collections/community\.general/pull/8236](https\://github\.com/ansible\-collections/community\.general/pull/8236)\)\.
+* portinstall \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* proxmox \- adds <code>startup</code> parameters to configure startup order\, startup delay and shutdown delay \([https\://github\.com/ansible\-collections/community\.general/pull/8038](https\://github\.com/ansible\-collections/community\.general/pull/8038)\)\.
* proxmox \- adds <code>template</code> value to the <code>state</code> parameter\, allowing conversion of container to a template \([https\://github\.com/ansible\-collections/community\.general/pull/7143](https\://github\.com/ansible\-collections/community\.general/pull/7143)\)\.
* proxmox \- adds <code>update</code> parameter\, allowing update of an already existing containers configuration \([https\://github\.com/ansible\-collections/community\.general/pull/7540](https\://github\.com/ansible\-collections/community\.general/pull/7540)\)\.
* proxmox inventory plugin \- adds an option to exclude nodes from the dynamic inventory generation\. The new setting is optional\, not using this option will behave as usual \([https\://github\.com/ansible\-collections/community\.general/issues/6714](https\://github\.com/ansible\-collections/community\.general/issues/6714)\, [https\://github\.com/ansible\-collections/community\.general/pull/7461](https\://github\.com/ansible\-collections/community\.general/pull/7461)\)\.
+* proxmox\* modules \- there is now a <code>community\.general\.proxmox</code> module defaults group that can be used to set default options for all Proxmox modules \([https\://github\.com/ansible\-collections/community\.general/pull/8334](https\://github\.com/ansible\-collections/community\.general/pull/8334)\)\.
* proxmox\_disk \- add ability to manipulate CD\-ROM drive \([https\://github\.com/ansible\-collections/community\.general/pull/7495](https\://github\.com/ansible\-collections/community\.general/pull/7495)\)\.
+* proxmox\_kvm \- add parameter <code>update\_unsafe</code> to avoid limitations when updating dangerous values \([https\://github\.com/ansible\-collections/community\.general/pull/7843](https\://github\.com/ansible\-collections/community\.general/pull/7843)\)\.
* proxmox\_kvm \- adds <code>template</code> value to the <code>state</code> parameter\, allowing conversion of a VM to a template \([https\://github\.com/ansible\-collections/community\.general/pull/7143](https\://github\.com/ansible\-collections/community\.general/pull/7143)\)\.
+* proxmox\_kvm \- adds\`\`usb\`\` parameter for setting USB devices on proxmox KVM VMs \([https\://github\.com/ansible\-collections/community\.general/pull/8199](https\://github\.com/ansible\-collections/community\.general/pull/8199)\)\.
* proxmox\_kvm \- support the <code>hookscript</code> parameter \([https\://github\.com/ansible\-collections/community\.general/issues/7600](https\://github\.com/ansible\-collections/community\.general/issues/7600)\)\.
* proxmox\_ostype \- it is now possible to specify the <code>ostype</code> when creating an LXC container \([https\://github\.com/ansible\-collections/community\.general/pull/7462](https\://github\.com/ansible\-collections/community\.general/pull/7462)\)\.
* proxmox\_vm\_info \- add ability to retrieve configuration info \([https\://github\.com/ansible\-collections/community\.general/pull/7485](https\://github\.com/ansible\-collections/community\.general/pull/7485)\)\.
+* puppet \- new feature to set <code>\-\-waitforlock</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/8282](https\://github\.com/ansible\-collections/community\.general/pull/8282)\)\.
+* redfish\_command \- add command <code>ResetToDefaults</code> to reset manager to default state \([https\://github\.com/ansible\-collections/community\.general/issues/8163](https\://github\.com/ansible\-collections/community\.general/issues/8163)\)\.
+* redfish\_config \- add command <code>SetServiceIdentification</code> to set service identification \([https\://github\.com/ansible\-collections/community\.general/issues/7916](https\://github\.com/ansible\-collections/community\.general/issues/7916)\)\.
+* redfish\_info \- add boolean return value <code>MultipartHttpPush</code> to <code>GetFirmwareUpdateCapabilities</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8194](https\://github\.com/ansible\-collections/community\.general/issues/8194)\, [https\://github\.com/ansible\-collections/community\.general/pull/8195](https\://github\.com/ansible\-collections/community\.general/pull/8195)\)\.
+* redfish\_info \- add command <code>GetServiceIdentification</code> to get service identification \([https\://github\.com/ansible\-collections/community\.general/issues/7882](https\://github\.com/ansible\-collections/community\.general/issues/7882)\)\.
* redfish\_info \- adding the <code>BootProgress</code> property when getting <code>Systems</code> info \([https\://github\.com/ansible\-collections/community\.general/pull/7626](https\://github\.com/ansible\-collections/community\.general/pull/7626)\)\.
+* revbitspss lookup plugin \- removed a redundant unicode prefix\. The prefix was not necessary for Python 3 and has been cleaned up to streamline the code \([https\://github\.com/ansible\-collections/community\.general/pull/8087](https\://github\.com/ansible\-collections/community\.general/pull/8087)\)\.
+* rundeck module utils \- allow to pass <code>Content\-Type</code> to API requests \([https\://github\.com/ansible\-collections/community\.general/pull/7684](https\://github\.com/ansible\-collections/community\.general/pull/7684)\)\.
+* slackpkg \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
* ssh\_config \- adds <code>controlmaster</code>\, <code>controlpath</code> and <code>controlpersist</code> parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7456](https\://github\.com/ansible\-collections/community\.general/pull/7456)\)\.
+* ssh\_config \- allow <code>accept\-new</code> as valid value for <code>strict\_host\_key\_checking</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8257](https\://github\.com/ansible\-collections/community\.general/pull/8257)\)\.
+* ssh\_config \- new feature to set <code>AddKeysToAgent</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7703](https\://github\.com/ansible\-collections/community\.general/pull/7703)\)\.
+* ssh\_config \- new feature to set <code>IdentitiesOnly</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7704](https\://github\.com/ansible\-collections/community\.general/pull/7704)\)\.
+* sudoers \- add support for the <code>NOEXEC</code> tag in sudoers rules \([https\://github\.com/ansible\-collections/community\.general/pull/7983](https\://github\.com/ansible\-collections/community\.general/pull/7983)\)\.
+* svr4pkg \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* swdepot \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
+* terraform \- add support for <code>diff\_mode</code> for terraform resource\_changes \([https\://github\.com/ansible\-collections/community\.general/pull/7896](https\://github\.com/ansible\-collections/community\.general/pull/7896)\)\.
+* terraform \- fix <code>diff\_mode</code> in state <code>absent</code> and when terraform <code>resource\_changes</code> does not exist \([https\://github\.com/ansible\-collections/community\.general/pull/7963](https\://github\.com/ansible\-collections/community\.general/pull/7963)\)\.
+* xcc\_redfish\_command \- added support for raw POSTs \(<code>command\=PostResource</code> in <code>category\=Raw</code>\) without a specific action info \([https\://github\.com/ansible\-collections/community\.general/pull/7746](https\://github\.com/ansible\-collections/community\.general/pull/7746)\)\.
+* xfconf \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
+* xfconf\_info \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
+
+<a id="breaking-changes--porting-guide"></a>
+### Breaking Changes / Porting Guide
+
+* cpanm \- the default of the <code>mode</code> option changed from <code>compatibility</code> to <code>new</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* django\_manage \- the module now requires Django \>\= 4\.1 \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* django\_manage \- the module will now fail if <code>virtualenv</code> is specified but no virtual environment exists at that location \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* redfish\_command\, redfish\_config\, redfish\_info \- change the default for <code>timeout</code> from 10 to 60 \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+
+<a id="deprecated-features"></a>
+### Deprecated Features
+
+* MH DependencyCtxMgr module\_utils \- deprecate <code>module\_utils\.mh\.mixin\.deps\.DependencyCtxMgr</code> in favour of <code>module\_utils\.deps</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.AnsibleModule</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.DependencyCtxMgr</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.StateMixin</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.VarDict\,</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.VarMeta</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.VarsMixin</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
+* ModuleHelper module\_utils \- deprecate use of <code>VarsMixin</code> in favor of using the <code>VardDict</code> module\_utils \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
+* ModuleHelper vars module\_utils \- bump deprecation of <code>VarMeta</code>\, <code>VarDict</code> and <code>VarsMixin</code> to version 11\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
+* apt\_rpm \- the behavior of <code>state\=present</code> and <code>state\=installed</code> is deprecated and will change in community\.general 11\.0\.0\. Right now the module will upgrade a package to the latest version if one of these two states is used\. You should explicitly use <code>state\=latest</code> if you want this behavior\, and switch to <code>state\=present\_not\_latest</code> if you do not want to upgrade the package if it is already installed\. In community\.general 11\.0\.0 the behavior of <code>state\=present</code> and <code>state\=installed</code> will change to that of <code>state\=present\_not\_latest</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8217](https\://github\.com/ansible\-collections/community\.general/issues/8217)\, [https\://github\.com/ansible\-collections/community\.general/pull/8285](https\://github\.com/ansible\-collections/community\.general/pull/8285)\)\.
+* consul\_acl \- the module has been deprecated and will be removed in community\.general 10\.0\.0\. <code>consul\_token</code> and <code>consul\_policy</code> can be used instead \([https\://github\.com/ansible\-collections/community\.general/pull/7901](https\://github\.com/ansible\-collections/community\.general/pull/7901)\)\.
+* django\_manage \- the <code>ack\_venv\_creation\_deprecation</code> option has no more effect and will be removed from community\.general 11\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* gitlab modules \- the basic auth method on GitLab API have been deprecated and will be removed in community\.general 10\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/8383](https\://github\.com/ansible\-collections/community\.general/pull/8383)\)\.
+* hipchat callback plugin \- the hipchat service has been discontinued and the self\-hosted variant has been End of Life since 2020\. The callback plugin is therefore deprecated and will be removed from community\.general 10\.0\.0 if nobody provides compelling reasons to still keep it \([https\://github\.com/ansible\-collections/community\.general/issues/8184](https\://github\.com/ansible\-collections/community\.general/issues/8184)\, [https\://github\.com/ansible\-collections/community\.general/pull/8189](https\://github\.com/ansible\-collections/community\.general/pull/8189)\)\.
+* irc \- the defaults <code>false</code> for <code>use\_tls</code> and <code>validate\_certs</code> have been deprecated and will change to <code>true</code> in community\.general 10\.0\.0 to improve security\. You can already improve security now by explicitly setting them to <code>true</code>\. Specifying values now disables the deprecation warning \([https\://github\.com/ansible\-collections/community\.general/pull/7578](https\://github\.com/ansible\-collections/community\.general/pull/7578)\)\.
+
+<a id="removed-features-previously-deprecated"></a>
+### Removed Features \(previously deprecated\)
-<a id="bugfixes-5"></a>
+* The deprecated redirects for internal module names have been removed\. These internal redirects were extra\-long FQCNs like <code>community\.general\.packaging\.os\.apt\_rpm</code> that redirect to the short FQCN <code>community\.general\.apt\_rpm</code>\. They were originally needed to implement flatmapping\; as various tooling started to recommend users to use the long names flatmapping was removed from the collection and redirects were added for users who already followed these incorrect recommendations \([https\://github\.com/ansible\-collections/community\.general/pull/7835](https\://github\.com/ansible\-collections/community\.general/pull/7835)\)\.
+* ansible\_galaxy\_install \- the <code>ack\_ansible29</code> and <code>ack\_min\_ansiblecore211</code> options have been removed\. They no longer had any effect \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* cloudflare\_dns \- remove support for SPF records\. These are no longer supported by CloudFlare \([https\://github\.com/ansible\-collections/community\.general/pull/7782](https\://github\.com/ansible\-collections/community\.general/pull/7782)\)\.
+* django\_manage \- support for the <code>command</code> values <code>cleanup</code>\, <code>syncdb</code>\, and <code>validate</code> were removed\. Use <code>clearsessions</code>\, <code>migrate</code>\, and <code>check</code> instead\, respectively \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* flowdock \- this module relied on HTTPS APIs that do not exist anymore and was thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* mh\.mixins\.deps module utils \- the <code>DependencyMixin</code> has been removed\. Use the <code>deps</code> module utils instead \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* proxmox \- the <code>proxmox\_default\_behavior</code> option has been removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* rax\* modules\, rax module utils\, rax docs fragment \- the Rackspace modules relied on the deprecated package <code>pyrax</code> and were thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* redhat module utils \- the classes <code>Rhsm</code>\, <code>RhsmPool</code>\, and <code>RhsmPools</code> have been removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* redhat\_subscription \- the alias <code>autosubscribe</code> of the <code>auto\_attach</code> option was removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* stackdriver \- this module relied on HTTPS APIs that do not exist anymore and was thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+* webfaction\_\* modules \- these modules relied on HTTPS APIs that do not exist anymore and were thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
+
+<a id="security-fixes"></a>
+### Security Fixes
+
+* cobbler\, gitlab\_runners\, icinga2\, linode\, lxd\, nmap\, online\, opennebula\, proxmox\, scaleway\, stackpath\_compute\, virtualbox\, and xen\_orchestra inventory plugin \- make sure all data received from the remote servers is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.general/pull/8098](https\://github\.com/ansible\-collections/community\.general/pull/8098)\)\.
+* keycloak\_identity\_provider \- the client secret was not correctly sanitized by the module\. The return values <code>proposed</code>\, <code>existing</code>\, and <code>end\_state</code>\, as well as the diff\, did contain the client secret unmasked \([https\://github\.com/ansible\-collections/community\.general/pull/8355](https\://github\.com/ansible\-collections/community\.general/pull/8355)\)\.
+
+<a id="bugfixes-1"></a>
### Bugfixes
+* aix\_filesystem \- fix <code>\_validate\_vg</code> not passing VG name to <code>lsvg\_cmd</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8151](https\://github\.com/ansible\-collections/community\.general/issues/8151)\)\.
+* aix\_filesystem \- fix issue with empty list items in crfs logic and option order \([https\://github\.com/ansible\-collections/community\.general/pull/8052](https\://github\.com/ansible\-collections/community\.general/pull/8052)\)\.
* apt\-rpm \- the module did not upgrade packages if a newer version exists\. Now the package will be reinstalled if the candidate is newer than the installed version \([https\://github\.com/ansible\-collections/community\.general/issues/7414](https\://github\.com/ansible\-collections/community\.general/issues/7414)\)\.
+* apt\_rpm \- when checking whether packages were installed after running <code>apt\-get \-y install \<packages\></code>\, only the last package name was checked \([https\://github\.com/ansible\-collections/community\.general/pull/8263](https\://github\.com/ansible\-collections/community\.general/pull/8263)\)\.
+* bitwarden\_secrets\_manager lookup plugin \- implements retry with exponential backoff to avoid lookup errors when Bitwardn\'s API rate limiting is encountered \([https\://github\.com/ansible\-collections/community\.general/issues/8230](https\://github\.com/ansible\-collections/community\.general/issues/8230)\, [https\://github\.com/ansible\-collections/community\.general/pull/8238](https\://github\.com/ansible\-collections/community\.general/pull/8238)\)\.
+* cargo \- fix idempotency issues when using a custom installation path for packages \(using the <code>\-\-path</code> parameter\)\. The initial installation runs fine\, but subsequent runs use the <code>get\_installed\(\)</code> function which did not check the given installation location\, before running <code>cargo install</code>\. This resulted in a false <code>changed</code> state\. Also the removal of packeges using <code>state\: absent</code> failed\, as the installation check did not use the given parameter \([https\://github\.com/ansible\-collections/community\.general/pull/7970](https\://github\.com/ansible\-collections/community\.general/pull/7970)\)\.
* cloudflare\_dns \- fix Cloudflare lookup of SHFP records \([https\://github\.com/ansible\-collections/community\.general/issues/7652](https\://github\.com/ansible\-collections/community\.general/issues/7652)\)\.
+* consul\_token \- fix token creation without <code>accessor\_id</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8091](https\://github\.com/ansible\-collections/community\.general/pull/8091)\)\.
+* from\_ini filter plugin \- disabling interpolation of <code>ConfigParser</code> to allow converting values with a <code>\%</code> sign \([https\://github\.com/ansible\-collections/community\.general/issues/8183](https\://github\.com/ansible\-collections/community\.general/issues/8183)\, [https\://github\.com/ansible\-collections/community\.general/pull/8185](https\://github\.com/ansible\-collections/community\.general/pull/8185)\)\.
+* gitlab\_group\_members \- fix gitlab constants call in <code>gitlab\_group\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
+* gitlab\_issue \- fix behavior to search GitLab issue\, using <code>search</code> keyword instead of <code>title</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7846](https\://github\.com/ansible\-collections/community\.general/issues/7846)\)\.
+* gitlab\_issue\, gitlab\_label\, gitlab\_milestone \- avoid crash during version comparison when the python\-gitlab Python module is not installed \([https\://github\.com/ansible\-collections/community\.general/pull/8158](https\://github\.com/ansible\-collections/community\.general/pull/8158)\)\.
+* gitlab\_project\_members \- fix gitlab constants call in <code>gitlab\_project\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
+* gitlab\_protected\_branches \- fix gitlab constants call in <code>gitlab\_protected\_branches</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
+* gitlab\_runner \- fix pagination when checking for existing runners \([https\://github\.com/ansible\-collections/community\.general/pull/7790](https\://github\.com/ansible\-collections/community\.general/pull/7790)\)\.
+* gitlab\_user \- fix gitlab constants call in <code>gitlab\_user</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
+* haproxy \- fix an issue where HAProxy could get stuck in DRAIN mode when the backend was unreachable \([https\://github\.com/ansible\-collections/community\.general/issues/8092](https\://github\.com/ansible\-collections/community\.general/issues/8092)\)\.
+* homebrew \- detect already installed formulae and casks using JSON output from <code>brew info</code> \([https\://github\.com/ansible\-collections/community\.general/issues/864](https\://github\.com/ansible\-collections/community\.general/issues/864)\)\.
+* homebrew \- error returned from brew command was ignored and tried to parse empty JSON\. Fix now checks for an error and raises it to give accurate error message to users \([https\://github\.com/ansible\-collections/community\.general/issues/8047](https\://github\.com/ansible\-collections/community\.general/issues/8047)\)\.
+* incus connection plugin \- treats <code>inventory\_hostname</code> as a variable instead of a literal in remote connections \([https\://github\.com/ansible\-collections/community\.general/issues/7874](https\://github\.com/ansible\-collections/community\.general/issues/7874)\)\.
* interface\_files \- also consider <code>address\_family</code> when changing <code>option\=method</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7610](https\://github\.com/ansible\-collections/community\.general/issues/7610)\, [https\://github\.com/ansible\-collections/community\.general/pull/7612](https\://github\.com/ansible\-collections/community\.general/pull/7612)\)\.
+* inventory plugins \- add unsafe wrapper to avoid marking strings that do not contain <code>\{</code> or <code>\}</code> as unsafe\, to work around a bug in AWX \(\([https\://github\.com/ansible\-collections/community\.general/issues/8212](https\://github\.com/ansible\-collections/community\.general/issues/8212)\, [https\://github\.com/ansible\-collections/community\.general/pull/8225](https\://github\.com/ansible\-collections/community\.general/pull/8225)\)\.
+* ipa \- fix get version regex in IPA module\_utils \([https\://github\.com/ansible\-collections/community\.general/pull/8175](https\://github\.com/ansible\-collections/community\.general/pull/8175)\)\.
+* ipa\_hbacrule \- the module uses a string for <code>ipaenabledflag</code> for new FreeIPA versions while the returned value is a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7880](https\://github\.com/ansible\-collections/community\.general/pull/7880)\)\.
+* ipa\_otptoken \- the module expect <code>ipatokendisabled</code> as string but the <code>ipatokendisabled</code> value is returned as a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7795](https\://github\.com/ansible\-collections/community\.general/pull/7795)\)\.
+* ipa\_sudorule \- the module uses a string for <code>ipaenabledflag</code> for new FreeIPA versions while the returned value is a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7880](https\://github\.com/ansible\-collections/community\.general/pull/7880)\)\.
+* iptables\_state \- fix idempotency issues when restoring incomplete iptables dumps \([https\://github\.com/ansible\-collections/community\.general/issues/8029](https\://github\.com/ansible\-collections/community\.general/issues/8029)\)\.
* irc \- replace <code>ssl\.wrap\_socket</code> that was removed from Python 3\.12 with code for creating a proper SSL context \([https\://github\.com/ansible\-collections/community\.general/pull/7542](https\://github\.com/ansible\-collections/community\.general/pull/7542)\)\.
* keycloak\_\* \- fix Keycloak API client to quote <code>/</code> properly \([https\://github\.com/ansible\-collections/community\.general/pull/7641](https\://github\.com/ansible\-collections/community\.general/pull/7641)\)\.
* keycloak\_authz\_permission \- resource payload variable for scope\-based permission was constructed as a string\, when it needs to be a list\, even for a single item \([https\://github\.com/ansible\-collections/community\.general/issues/7151](https\://github\.com/ansible\-collections/community\.general/issues/7151)\)\.
+* keycloak\_client \- add sorted <code>defaultClientScopes</code> and <code>optionalClientScopes</code> to normalizations \([https\://github\.com/ansible\-collections/community\.general/pull/8223](https\://github\.com/ansible\-collections/community\.general/pull/8223)\)\.
+* keycloak\_client \- fixes issue when metadata is provided in desired state when task is in check mode \([https\://github\.com/ansible\-collections/community\.general/issues/1226](https\://github\.com/ansible\-collections/community\.general/issues/1226)\, [https\://github\.com/ansible\-collections/community\.general/pull/7881](https\://github\.com/ansible\-collections/community\.general/pull/7881)\)\.
+* keycloak\_identity\_provider \- <code>mappers</code> processing was not idempotent if the mappers configuration list had not been sorted by name \(in ascending order\)\. Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
+* keycloak\_identity\_provider \- it was not possible to reconfigure \(add\, remove\) <code>mappers</code> once they were created initially\. Removal was ignored\, adding new ones resulted in dropping the pre\-existing unmodified mappers\. Fix resolves the issue by supplying correct input to the internal update call \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
+* keycloak\_realm \- add normalizations for <code>enabledEventTypes</code> and <code>supportedLocales</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8224](https\://github\.com/ansible\-collections/community\.general/pull/8224)\)\.
+* keycloak\_user \- when <code>force</code> is set\, but user does not exist\, do not try to delete it \([https\://github\.com/ansible\-collections/community\.general/pull/7696](https\://github\.com/ansible\-collections/community\.general/pull/7696)\)\.
+* keycloak\_user\_federation \- fix diff of empty <code>krbPrincipalAttribute</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8320](https\://github\.com/ansible\-collections/community\.general/pull/8320)\)\.
+* ldap \- previously the order number \(if present\) was expected to follow an equals sign in the DN\. This makes it so the order number string is identified correctly anywhere within the DN \([https\://github\.com/ansible\-collections/community\.general/issues/7646](https\://github\.com/ansible\-collections/community\.general/issues/7646)\)\.
+* linode inventory plugin \- add descriptive error message for linode inventory plugin \([https\://github\.com/ansible\-collections/community\.general/pull/8133](https\://github\.com/ansible\-collections/community\.general/pull/8133)\)\.
* log\_entries callback plugin \- replace <code>ssl\.wrap\_socket</code> that was removed from Python 3\.12 with code for creating a proper SSL context \([https\://github\.com/ansible\-collections/community\.general/pull/7542](https\://github\.com/ansible\-collections/community\.general/pull/7542)\)\.
* lvol \- test for output messages in both <code>stdout</code> and <code>stderr</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7601](https\://github\.com/ansible\-collections/community\.general/pull/7601)\, [https\://github\.com/ansible\-collections/community\.general/issues/7182](https\://github\.com/ansible\-collections/community\.general/issues/7182)\)\.
+* merge\_variables lookup plugin \- fixing cross host merge\: providing access to foreign hosts variables to the perspective of the host that is performing the merge \([https\://github\.com/ansible\-collections/community\.general/pull/8303](https\://github\.com/ansible\-collections/community\.general/pull/8303)\)\.
+* modprobe \- listing modules files or modprobe files could trigger a FileNotFoundError if <code>/etc/modprobe\.d</code> or <code>/etc/modules\-load\.d</code> did not exist\. Relevant functions now return empty lists if the directories do not exist to avoid crashing the module \([https\://github\.com/ansible\-collections/community\.general/issues/7717](https\://github\.com/ansible\-collections/community\.general/issues/7717)\)\.
+* mssql\_script \- make the module work with Python 2 \([https\://github\.com/ansible\-collections/community\.general/issues/7818](https\://github\.com/ansible\-collections/community\.general/issues/7818)\, [https\://github\.com/ansible\-collections/community\.general/pull/7821](https\://github\.com/ansible\-collections/community\.general/pull/7821)\)\.
+* nmcli \- fix <code>connection\.slave\-type</code> wired to <code>bond</code> and not with parameter <code>slave\_type</code> in case of connection type <code>wifi</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7389](https\://github\.com/ansible\-collections/community\.general/issues/7389)\)\.
+* ocapi\_utils\, oci\_utils\, redfish\_utils module utils \- replace <code>type\(\)</code> calls with <code>isinstance\(\)</code> calls \([https\://github\.com/ansible\-collections/community\.general/pull/7501](https\://github\.com/ansible\-collections/community\.general/pull/7501)\)\.
+* onepassword lookup plugin \- failed for fields that were in sections and had uppercase letters in the label/ID\. Field lookups are now case insensitive in all cases \([https\://github\.com/ansible\-collections/community\.general/pull/7919](https\://github\.com/ansible\-collections/community\.general/pull/7919)\)\.
* onepassword lookup plugin \- field and section titles are now case insensitive when using op CLI version two or later\. This matches the behavior of version one \([https\://github\.com/ansible\-collections/community\.general/pull/7564](https\://github\.com/ansible\-collections/community\.general/pull/7564)\)\.
+* opentelemetry callback plugin \- close spans always \([https\://github\.com/ansible\-collections/community\.general/pull/8367](https\://github\.com/ansible\-collections/community\.general/pull/8367)\)\.
+* opentelemetry callback plugin \- honour the <code>disable\_logs</code> option to avoid storing task results since they are not used regardless \([https\://github\.com/ansible\-collections/community\.general/pull/8373](https\://github\.com/ansible\-collections/community\.general/pull/8373)\)\.
+* pacemaker\_cluster \- actually implement check mode\, which the module claims to support\. This means that until now the module also did changes in check mode \([https\://github\.com/ansible\-collections/community\.general/pull/8081](https\://github\.com/ansible\-collections/community\.general/pull/8081)\)\.
+* pam\_limits \- when the file does not exist\, do not create it in check mode \([https\://github\.com/ansible\-collections/community\.general/issues/8050](https\://github\.com/ansible\-collections/community\.general/issues/8050)\, [https\://github\.com/ansible\-collections/community\.general/pull/8057](https\://github\.com/ansible\-collections/community\.general/pull/8057)\)\.
+* pipx module utils \- change the CLI argument formatter for the <code>pip\_args</code> parameter \([https\://github\.com/ansible\-collections/community\.general/issues/7497](https\://github\.com/ansible\-collections/community\.general/issues/7497)\, [https\://github\.com/ansible\-collections/community\.general/pull/7506](https\://github\.com/ansible\-collections/community\.general/pull/7506)\)\.
+* pkgin \- pkgin \(pkgsrc package manager used by SmartOS\) raises erratic exceptions and spurious <code>changed\=true</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7971](https\://github\.com/ansible\-collections/community\.general/pull/7971)\)\.
+* proxmox \- fix updating a container config if the setting does not already exist \([https\://github\.com/ansible\-collections/community\.general/pull/7872](https\://github\.com/ansible\-collections/community\.general/pull/7872)\)\.
+* proxmox\_kvm \- fixed status check getting from node\-specific API endpoint \([https\://github\.com/ansible\-collections/community\.general/issues/7817](https\://github\.com/ansible\-collections/community\.general/issues/7817)\)\.
+* proxmox\_kvm \- running <code>state\=template</code> will first check whether VM is already a template \([https\://github\.com/ansible\-collections/community\.general/pull/7792](https\://github\.com/ansible\-collections/community\.general/pull/7792)\)\.
+* proxmox\_pool\_member \- absent state for type VM did not delete VMs from the pools \([https\://github\.com/ansible\-collections/community\.general/pull/7464](https\://github\.com/ansible\-collections/community\.general/pull/7464)\)\.
+* puppet \- add option <code>environment\_lang</code> to set the environment language encoding\. Defaults to lang <code>C</code>\. It is recommended to set it to <code>C\.UTF\-8</code> or <code>en\_US\.UTF\-8</code> depending on what is available on your system\. \([https\://github\.com/ansible\-collections/community\.general/issues/8000](https\://github\.com/ansible\-collections/community\.general/issues/8000)\)
+* redfish\_command \- fix usage of message parsing in <code>SimpleUpdate</code> and <code>MultipartHTTPPushUpdate</code> commands to treat the lack of a <code>MessageId</code> as no message \([https\://github\.com/ansible\-collections/community\.general/issues/7465](https\://github\.com/ansible\-collections/community\.general/issues/7465)\, [https\://github\.com/ansible\-collections/community\.general/pull/7471](https\://github\.com/ansible\-collections/community\.general/pull/7471)\)\.
+* redfish\_info \- allow for a GET operation invoked by <code>GetUpdateStatus</code> to allow for an empty response body for cases where a service returns 204 No Content \([https\://github\.com/ansible\-collections/community\.general/issues/8003](https\://github\.com/ansible\-collections/community\.general/issues/8003)\)\.
+* redfish\_info \- correct uncaught exception when attempting to retrieve <code>Chassis</code> information \([https\://github\.com/ansible\-collections/community\.general/pull/7952](https\://github\.com/ansible\-collections/community\.general/pull/7952)\)\.
* redhat\_subscription \- use the D\-Bus registration on RHEL 7 only on 7\.4 and
greater\; older versions of RHEL 7 do not have it
\([https\://github\.com/ansible\-collections/community\.general/issues/7622](https\://github\.com/ansible\-collections/community\.general/issues/7622)\,
[https\://github\.com/ansible\-collections/community\.general/pull/7624](https\://github\.com/ansible\-collections/community\.general/pull/7624)\)\.
+* riak \- support <code>riak admin</code> sub\-command in newer Riak KV versions beside the legacy <code>riak\-admin</code> main command \([https\://github\.com/ansible\-collections/community\.general/pull/8211](https\://github\.com/ansible\-collections/community\.general/pull/8211)\)\.
+* statusio\_maintenance \- fix error caused by incorrectly formed API data payload\. Was raising \"Failed to create maintenance HTTP Error 400 Bad Request\" caused by bad data type for date/time and deprecated dict keys \([https\://github\.com/ansible\-collections/community\.general/pull/7754](https\://github\.com/ansible\-collections/community\.general/pull/7754)\)\.
* terraform \- fix multiline string handling in complex variables \([https\://github\.com/ansible\-collections/community\.general/pull/7535](https\://github\.com/ansible\-collections/community\.general/pull/7535)\)\.
+* to\_ini filter plugin \- disabling interpolation of <code>ConfigParser</code> to allow converting values with a <code>\%</code> sign \([https\://github\.com/ansible\-collections/community\.general/issues/8183](https\://github\.com/ansible\-collections/community\.general/issues/8183)\, [https\://github\.com/ansible\-collections/community\.general/pull/8185](https\://github\.com/ansible\-collections/community\.general/pull/8185)\)\.
+* xml \- make module work with lxml 5\.1\.1\, which removed some internals that the module was relying on \([https\://github\.com/ansible\-collections/community\.general/pull/8169](https\://github\.com/ansible\-collections/community\.general/pull/8169)\)\.
-<a id="new-plugins-2"></a>
+<a id="new-plugins"></a>
### New Plugins
-<a id="lookup-1"></a>
-#### Lookup
-
-* onepassword\_doc \- Fetch documents stored in 1Password
-
-<a id="test"></a>
-#### Test
-
-* fqdn\_valid \- Validates fully\-qualified domain names against RFC 1123
-
-<a id="new-modules-5"></a>
-### New Modules
-
-* git\_config\_info \- Read git configuration
-* gitlab\_issue \- Create\, update\, or delete GitLab issues
-* nomad\_token \- Manage Nomad ACL tokens
+<a id="become"></a>
+#### Become
-<a id="v8-0-2"></a>
-## v8\.0\.2
+* community\.general\.run0 \- Systemd\'s run0\.
-<a id="release-summary-6"></a>
-### Release Summary
-
-Bugfix release for inclusion in Ansible 9\.0\.0rc1\.
-
-<a id="bugfixes-6"></a>
-### Bugfixes
-
-* ocapi\_utils\, oci\_utils\, redfish\_utils module utils \- replace <code>type\(\)</code> calls with <code>isinstance\(\)</code> calls \([https\://github\.com/ansible\-collections/community\.general/pull/7501](https\://github\.com/ansible\-collections/community\.general/pull/7501)\)\.
-* pipx module utils \- change the CLI argument formatter for the <code>pip\_args</code> parameter \([https\://github\.com/ansible\-collections/community\.general/issues/7497](https\://github\.com/ansible\-collections/community\.general/issues/7497)\, [https\://github\.com/ansible\-collections/community\.general/pull/7506](https\://github\.com/ansible\-collections/community\.general/pull/7506)\)\.
-
-<a id="v8-0-1"></a>
-## v8\.0\.1
-
-<a id="release-summary-7"></a>
-### Release Summary
-
-Bugfix release for inclusion in Ansible 9\.0\.0b1\.
-
-<a id="bugfixes-7"></a>
-### Bugfixes
-
-* gitlab\_group\_members \- fix gitlab constants call in <code>gitlab\_group\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
-* gitlab\_project\_members \- fix gitlab constants call in <code>gitlab\_project\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
-* gitlab\_protected\_branches \- fix gitlab constants call in <code>gitlab\_protected\_branches</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
-* gitlab\_user \- fix gitlab constants call in <code>gitlab\_user</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
-* proxmox\_pool\_member \- absent state for type VM did not delete VMs from the pools \([https\://github\.com/ansible\-collections/community\.general/pull/7464](https\://github\.com/ansible\-collections/community\.general/pull/7464)\)\.
-* redfish\_command \- fix usage of message parsing in <code>SimpleUpdate</code> and <code>MultipartHTTPPushUpdate</code> commands to treat the lack of a <code>MessageId</code> as no message \([https\://github\.com/ansible\-collections/community\.general/issues/7465](https\://github\.com/ansible\-collections/community\.general/issues/7465)\, [https\://github\.com/ansible\-collections/community\.general/pull/7471](https\://github\.com/ansible\-collections/community\.general/pull/7471)\)\.
-
-<a id="v8-0-0"></a>
-## v8\.0\.0
-
-<a id="release-summary-8"></a>
-### Release Summary
-
-This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-11\-01\.
-
-<a id="minor-changes-6"></a>
-### Minor Changes
-
-* The collection will start using semantic markup \([https\://github\.com/ansible\-collections/community\.general/pull/6539](https\://github\.com/ansible\-collections/community\.general/pull/6539)\)\.
-* VarDict module utils \- add method <code>VarDict\.as\_dict\(\)</code> to convert to a plain <code>dict</code> object \([https\://github\.com/ansible\-collections/community\.general/pull/6602](https\://github\.com/ansible\-collections/community\.general/pull/6602)\)\.
-* apt\_rpm \- extract package name from local <code>\.rpm</code> path when verifying
- installation success\. Allows installing packages from local <code>\.rpm</code> files
- \([https\://github\.com/ansible\-collections/community\.general/pull/7396](https\://github\.com/ansible\-collections/community\.general/pull/7396)\)\.
-* cargo \- add option <code>executable</code>\, which allows user to specify path to the cargo binary \([https\://github\.com/ansible\-collections/community\.general/pull/7352](https\://github\.com/ansible\-collections/community\.general/pull/7352)\)\.
-* cargo \- add option <code>locked</code> which allows user to specify install the locked version of dependency instead of latest compatible version \([https\://github\.com/ansible\-collections/community\.general/pull/6134](https\://github\.com/ansible\-collections/community\.general/pull/6134)\)\.
-* chroot connection plugin \- add <code>disable\_root\_check</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7099](https\://github\.com/ansible\-collections/community\.general/pull/7099)\)\.
-* cloudflare\_dns \- add CAA record support \([https\://github\.com/ansible\-collections/community\.general/pull/7399](https\://github\.com/ansible\-collections/community\.general/pull/7399)\)\.
-* cobbler inventory plugin \- add <code>exclude\_mgmt\_classes</code> and <code>include\_mgmt\_classes</code> options to exclude or include hosts based on management classes \([https\://github\.com/ansible\-collections/community\.general/pull/7184](https\://github\.com/ansible\-collections/community\.general/pull/7184)\)\.
-* cobbler inventory plugin \- add <code>inventory\_hostname</code> option to allow using the system name for the inventory hostname \([https\://github\.com/ansible\-collections/community\.general/pull/6502](https\://github\.com/ansible\-collections/community\.general/pull/6502)\)\.
-* cobbler inventory plugin \- add <code>want\_ip\_addresses</code> option to collect all interface DNS name to IP address mapping \([https\://github\.com/ansible\-collections/community\.general/pull/6711](https\://github\.com/ansible\-collections/community\.general/pull/6711)\)\.
-* cobbler inventory plugin \- add primary IP addess to <code>cobbler\_ipv4\_address</code> and IPv6 address to <code>cobbler\_ipv6\_address</code> host variable \([https\://github\.com/ansible\-collections/community\.general/pull/6711](https\://github\.com/ansible\-collections/community\.general/pull/6711)\)\.
-* cobbler inventory plugin \- add warning for systems with empty profiles \([https\://github\.com/ansible\-collections/community\.general/pull/6502](https\://github\.com/ansible\-collections/community\.general/pull/6502)\)\.
-* cobbler inventory plugin \- convert Ansible unicode strings to native Python unicode strings before passing user/password to XMLRPC client \([https\://github\.com/ansible\-collections/community\.general/pull/6923](https\://github\.com/ansible\-collections/community\.general/pull/6923)\)\.
-* consul\_session \- drops requirement for the <code>python\-consul</code> library to communicate with the Consul API\, instead relying on the existing <code>requests</code> library requirement \([https\://github\.com/ansible\-collections/community\.general/pull/6755](https\://github\.com/ansible\-collections/community\.general/pull/6755)\)\.
-* copr \- respawn module to use the system python interpreter when the <code>dnf</code> python module is not available in <code>ansible\_python\_interpreter</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6522](https\://github\.com/ansible\-collections/community\.general/pull/6522)\)\.
-* cpanm \- minor refactor when creating the <code>CmdRunner</code> object \([https\://github\.com/ansible\-collections/community\.general/pull/7231](https\://github\.com/ansible\-collections/community\.general/pull/7231)\)\.
-* datadog\_monitor \- adds <code>notification\_preset\_name</code>\, <code>renotify\_occurrences</code> and <code>renotify\_statuses</code> parameters \([https\://github\.com/ansible\-collections/community\.general/issues/6521\,https\://github\.com/ansible\-collections/community\.general/issues/5823](https\://github\.com/ansible\-collections/community\.general/issues/6521\,https\://github\.com/ansible\-collections/community\.general/issues/5823)\)\.
-* dig lookup plugin \- add TCP option to enable the use of TCP connection during DNS lookup \([https\://github\.com/ansible\-collections/community\.general/pull/7343](https\://github\.com/ansible\-collections/community\.general/pull/7343)\)\.
-* ejabberd\_user \- module now using <code>CmdRunner</code> to execute external command \([https\://github\.com/ansible\-collections/community\.general/pull/7075](https\://github\.com/ansible\-collections/community\.general/pull/7075)\)\.
-* filesystem \- add <code>uuid</code> parameter for UUID change feature \([https\://github\.com/ansible\-collections/community\.general/pull/6680](https\://github\.com/ansible\-collections/community\.general/pull/6680)\)\.
-* gitlab\_group \- add option <code>force\_delete</code> \(default\: false\) which allows delete group even if projects exists in it \([https\://github\.com/ansible\-collections/community\.general/pull/7364](https\://github\.com/ansible\-collections/community\.general/pull/7364)\)\.
-* gitlab\_group\_variable \- add support for <code>raw</code> variables suboption \([https\://github\.com/ansible\-collections/community\.general/pull/7132](https\://github\.com/ansible\-collections/community\.general/pull/7132)\)\.
-* gitlab\_project\_variable \- add support for <code>raw</code> variables suboption \([https\://github\.com/ansible\-collections/community\.general/pull/7132](https\://github\.com/ansible\-collections/community\.general/pull/7132)\)\.
-* gitlab\_project\_variable \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6928](https\://github\.com/ansible\-collections/community\.general/pull/6928)\)\.
-* gitlab\_runner \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6927](https\://github\.com/ansible\-collections/community\.general/pull/6927)\)\.
-* htpasswd \- minor code improvements in the module \([https\://github\.com/ansible\-collections/community\.general/pull/6901](https\://github\.com/ansible\-collections/community\.general/pull/6901)\)\.
-* htpasswd \- the parameter <code>crypt\_scheme</code> is being renamed as <code>hash\_scheme</code> and added as an alias to it \([https\://github\.com/ansible\-collections/community\.general/pull/6841](https\://github\.com/ansible\-collections/community\.general/pull/6841)\)\.
-* icinga2\_host \- the <code>ip</code> option is no longer required\, since Icinga 2 allows for an empty address attribute \([https\://github\.com/ansible\-collections/community\.general/pull/7452](https\://github\.com/ansible\-collections/community\.general/pull/7452)\)\.
-* ini\_file \- add <code>ignore\_spaces</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7273](https\://github\.com/ansible\-collections/community\.general/pull/7273)\)\.
-* ini\_file \- add <code>modify\_inactive\_option</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7401](https\://github\.com/ansible\-collections/community\.general/pull/7401)\)\.
-* ipa\_config \- add module parameters to manage FreeIPA user and group objectclasses \([https\://github\.com/ansible\-collections/community\.general/pull/7019](https\://github\.com/ansible\-collections/community\.general/pull/7019)\)\.
-* ipa\_config \- adds <code>idp</code> choice to <code>ipauserauthtype</code> parameter\'s choices \([https\://github\.com/ansible\-collections/community\.general/pull/7051](https\://github\.com/ansible\-collections/community\.general/pull/7051)\)\.
-* jenkins\_build \- add new <code>detach</code> option\, which allows the module to exit successfully as long as the build is created \(default functionality is still waiting for the build to end before exiting\) \([https\://github\.com/ansible\-collections/community\.general/pull/7204](https\://github\.com/ansible\-collections/community\.general/pull/7204)\)\.
-* jenkins\_build \- add new <code>time\_between\_checks</code> option\, which allows to configure the wait time between requests to the Jenkins server \([https\://github\.com/ansible\-collections/community\.general/pull/7204](https\://github\.com/ansible\-collections/community\.general/pull/7204)\)\.
-* keycloak\_authentication \- added provider ID choices\, since Keycloak supports only those two specific ones \([https\://github\.com/ansible\-collections/community\.general/pull/6763](https\://github\.com/ansible\-collections/community\.general/pull/6763)\)\.
-* keycloak\_client\_rolemapping \- adds support for subgroups with additional parameter <code>parents</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6687](https\://github\.com/ansible\-collections/community\.general/pull/6687)\)\.
-* keycloak\_role \- add composite roles support for realm and client roles \([https\://github\.com/ansible\-collections/community\.general/pull/6469](https\://github\.com/ansible\-collections/community\.general/pull/6469)\)\.
-* keyring \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6927](https\://github\.com/ansible\-collections/community\.general/pull/6927)\)\.
-* ldap\_\* \- add new arguments <code>client\_cert</code> and <code>client\_key</code> to the LDAP modules in order to allow certificate authentication \([https\://github\.com/ansible\-collections/community\.general/pull/6668](https\://github\.com/ansible\-collections/community\.general/pull/6668)\)\.
-* ldap\_search \- add a new <code>page\_size</code> option to enable paged searches \([https\://github\.com/ansible\-collections/community\.general/pull/6648](https\://github\.com/ansible\-collections/community\.general/pull/6648)\)\.
-* locale\_gen \- module has been refactored to use <code>ModuleHelper</code> and <code>CmdRunner</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6903](https\://github\.com/ansible\-collections/community\.general/pull/6903)\)\.
-* locale\_gen \- module now using <code>CmdRunner</code> to execute external commands \([https\://github\.com/ansible\-collections/community\.general/pull/6820](https\://github\.com/ansible\-collections/community\.general/pull/6820)\)\.
-* lvg \- add <code>active</code> and <code>inactive</code> values to the <code>state</code> option for active state management feature \([https\://github\.com/ansible\-collections/community\.general/pull/6682](https\://github\.com/ansible\-collections/community\.general/pull/6682)\)\.
-* lvg \- add <code>reset\_vg\_uuid</code>\, <code>reset\_pv\_uuid</code> options for UUID reset feature \([https\://github\.com/ansible\-collections/community\.general/pull/6682](https\://github\.com/ansible\-collections/community\.general/pull/6682)\)\.
-* lxc connection plugin \- properly handle a change of the <code>remote\_addr</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7373](https\://github\.com/ansible\-collections/community\.general/pull/7373)\)\.
-* lxd connection plugin \- automatically translate <code>remote\_addr</code> from FQDN to \(short\) hostname \([https\://github\.com/ansible\-collections/community\.general/pull/7360](https\://github\.com/ansible\-collections/community\.general/pull/7360)\)\.
-* lxd connection plugin \- update error parsing to work with newer messages mentioning instances \([https\://github\.com/ansible\-collections/community\.general/pull/7360](https\://github\.com/ansible\-collections/community\.general/pull/7360)\)\.
-* lxd inventory plugin \- add <code>server\_cert</code> option for trust anchor to use for TLS verification of server certificates \([https\://github\.com/ansible\-collections/community\.general/pull/7392](https\://github\.com/ansible\-collections/community\.general/pull/7392)\)\.
-* lxd inventory plugin \- add <code>server\_check\_hostname</code> option to disable hostname verification of server certificates \([https\://github\.com/ansible\-collections/community\.general/pull/7392](https\://github\.com/ansible\-collections/community\.general/pull/7392)\)\.
-* make \- add new <code>targets</code> parameter allowing multiple targets to be used with <code>make</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6882](https\://github\.com/ansible\-collections/community\.general/pull/6882)\, [https\://github\.com/ansible\-collections/community\.general/issues/4919](https\://github\.com/ansible\-collections/community\.general/issues/4919)\)\.
-* make \- allows <code>params</code> to be used without value \([https\://github\.com/ansible\-collections/community\.general/pull/7180](https\://github\.com/ansible\-collections/community\.general/pull/7180)\)\.
-* mas \- disable sign\-in check for macOS 12\+ as <code>mas account</code> is non\-functional \([https\://github\.com/ansible\-collections/community\.general/pull/6520](https\://github\.com/ansible\-collections/community\.general/pull/6520)\)\.
-* newrelic\_deployment \- add option <code>app\_name\_exact\_match</code>\, which filters results for the exact app\_name provided \([https\://github\.com/ansible\-collections/community\.general/pull/7355](https\://github\.com/ansible\-collections/community\.general/pull/7355)\)\.
-* nmap inventory plugin \- now has a <code>use\_arp\_ping</code> option to allow the user to disable the default ARP ping query for a more reliable form \([https\://github\.com/ansible\-collections/community\.general/pull/7119](https\://github\.com/ansible\-collections/community\.general/pull/7119)\)\.
-* nmcli \- add support for <code>ipv4\.dns\-options</code> and <code>ipv6\.dns\-options</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6902](https\://github\.com/ansible\-collections/community\.general/pull/6902)\)\.
-* nomad\_job\, nomad\_job\_info \- add <code>port</code> parameter \([https\://github\.com/ansible\-collections/community\.general/pull/7412](https\://github\.com/ansible\-collections/community\.general/pull/7412)\)\.
-* npm \- minor improvement on parameter validation \([https\://github\.com/ansible\-collections/community\.general/pull/6848](https\://github\.com/ansible\-collections/community\.general/pull/6848)\)\.
-* npm \- module now using <code>CmdRunner</code> to execute external commands \([https\://github\.com/ansible\-collections/community\.general/pull/6989](https\://github\.com/ansible\-collections/community\.general/pull/6989)\)\.
-* onepassword lookup plugin \- add service account support \([https\://github\.com/ansible\-collections/community\.general/issues/6635](https\://github\.com/ansible\-collections/community\.general/issues/6635)\, [https\://github\.com/ansible\-collections/community\.general/pull/6660](https\://github\.com/ansible\-collections/community\.general/pull/6660)\)\.
-* onepassword lookup plugin \- introduce <code>account\_id</code> option which allows specifying which account to use \([https\://github\.com/ansible\-collections/community\.general/pull/7308](https\://github\.com/ansible\-collections/community\.general/pull/7308)\)\.
-* onepassword\_raw lookup plugin \- add service account support \([https\://github\.com/ansible\-collections/community\.general/issues/6635](https\://github\.com/ansible\-collections/community\.general/issues/6635)\, [https\://github\.com/ansible\-collections/community\.general/pull/6660](https\://github\.com/ansible\-collections/community\.general/pull/6660)\)\.
-* onepassword\_raw lookup plugin \- introduce <code>account\_id</code> option which allows specifying which account to use \([https\://github\.com/ansible\-collections/community\.general/pull/7308](https\://github\.com/ansible\-collections/community\.general/pull/7308)\)\.
-* opentelemetry callback plugin \- add span attributes in the span event \([https\://github\.com/ansible\-collections/community\.general/pull/6531](https\://github\.com/ansible\-collections/community\.general/pull/6531)\)\.
-* opkg \- add <code>executable</code> parameter allowing to specify the path of the <code>opkg</code> command \([https\://github\.com/ansible\-collections/community\.general/pull/6862](https\://github\.com/ansible\-collections/community\.general/pull/6862)\)\.
-* opkg \- remove default value <code>\"\"</code> for parameter <code>force</code> as it causes the same behaviour of not having that parameter \([https\://github\.com/ansible\-collections/community\.general/pull/6513](https\://github\.com/ansible\-collections/community\.general/pull/6513)\)\.
-* pagerduty \- adds in option to use v2 API for creating pagerduty incidents \([https\://github\.com/ansible\-collections/community\.general/issues/6151](https\://github\.com/ansible\-collections/community\.general/issues/6151)\)
-* parted \- on resize\, use <code>\-\-fix</code> option if available \([https\://github\.com/ansible\-collections/community\.general/pull/7304](https\://github\.com/ansible\-collections/community\.general/pull/7304)\)\.
-* pnpm \- set correct version when state is latest or version is not mentioned\. Resolves previous idempotency problem \([https\://github\.com/ansible\-collections/community\.general/pull/7339](https\://github\.com/ansible\-collections/community\.general/pull/7339)\)\.
-* pritunl module utils \- ensure <code>validate\_certs</code> parameter is honoured in all methods \([https\://github\.com/ansible\-collections/community\.general/pull/7156](https\://github\.com/ansible\-collections/community\.general/pull/7156)\)\.
-* proxmox \- add <code>vmid</code> \(and <code>taskid</code> when possible\) to return values \([https\://github\.com/ansible\-collections/community\.general/pull/7263](https\://github\.com/ansible\-collections/community\.general/pull/7263)\)\.
-* proxmox \- support <code>timezone</code> parameter at container creation \([https\://github\.com/ansible\-collections/community\.general/pull/6510](https\://github\.com/ansible\-collections/community\.general/pull/6510)\)\.
-* proxmox inventory plugin \- add composite variables support for Proxmox nodes \([https\://github\.com/ansible\-collections/community\.general/issues/6640](https\://github\.com/ansible\-collections/community\.general/issues/6640)\)\.
-* proxmox\_kvm \- added support for <code>tpmstate0</code> parameter to configure TPM \(Trusted Platform Module\) disk\. TPM is required for Windows 11 installations \([https\://github\.com/ansible\-collections/community\.general/pull/6533](https\://github\.com/ansible\-collections/community\.general/pull/6533)\)\.
-* proxmox\_kvm \- enabled force restart of VM\, bringing the <code>force</code> parameter functionality in line with what is described in the docs \([https\://github\.com/ansible\-collections/community\.general/pull/6914](https\://github\.com/ansible\-collections/community\.general/pull/6914)\)\.
-* proxmox\_kvm \- re\-use <code>timeout</code> module param to forcefully shutdown a virtual machine when <code>state</code> is <code>stopped</code> \([https\://github\.com/ansible\-collections/community\.general/issues/6257](https\://github\.com/ansible\-collections/community\.general/issues/6257)\)\.
-* proxmox\_snap \- add <code>retention</code> parameter to delete old snapshots \([https\://github\.com/ansible\-collections/community\.general/pull/6576](https\://github\.com/ansible\-collections/community\.general/pull/6576)\)\.
-* proxmox\_vm\_info \- <code>node</code> parameter is no longer required\. Information can be obtained for the whole cluster \([https\://github\.com/ansible\-collections/community\.general/pull/6976](https\://github\.com/ansible\-collections/community\.general/pull/6976)\)\.
-* proxmox\_vm\_info \- non\-existing provided by name/vmid VM would return empty results instead of failing \([https\://github\.com/ansible\-collections/community\.general/pull/7049](https\://github\.com/ansible\-collections/community\.general/pull/7049)\)\.
-* pubnub\_blocks \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6928](https\://github\.com/ansible\-collections/community\.general/pull/6928)\)\.
-* random\_string \- added new <code>ignore\_similar\_chars</code> and <code>similar\_chars</code> option to ignore certain chars \([https\://github\.com/ansible\-collections/community\.general/pull/7242](https\://github\.com/ansible\-collections/community\.general/pull/7242)\)\.
-* redfish\_command \- add <code>MultipartHTTPPushUpdate</code> command \([https\://github\.com/ansible\-collections/community\.general/issues/6471](https\://github\.com/ansible\-collections/community\.general/issues/6471)\, [https\://github\.com/ansible\-collections/community\.general/pull/6612](https\://github\.com/ansible\-collections/community\.general/pull/6612)\)\.
-* redfish\_command \- add <code>account\_types</code> and <code>oem\_account\_types</code> as optional inputs to <code>AddUser</code> \([https\://github\.com/ansible\-collections/community\.general/issues/6823](https\://github\.com/ansible\-collections/community\.general/issues/6823)\, [https\://github\.com/ansible\-collections/community\.general/pull/6871](https\://github\.com/ansible\-collections/community\.general/pull/6871)\)\.
-* redfish\_command \- add new option <code>update\_oem\_params</code> for the <code>MultipartHTTPPushUpdate</code> command \([https\://github\.com/ansible\-collections/community\.general/issues/7331](https\://github\.com/ansible\-collections/community\.general/issues/7331)\)\.
-* redfish\_config \- add <code>CreateVolume</code> command to allow creation of volumes on servers \([https\://github\.com/ansible\-collections/community\.general/pull/6813](https\://github\.com/ansible\-collections/community\.general/pull/6813)\)\.
-* redfish\_config \- add <code>DeleteAllVolumes</code> command to allow deletion of all volumes on servers \([https\://github\.com/ansible\-collections/community\.general/pull/6814](https\://github\.com/ansible\-collections/community\.general/pull/6814)\)\.
-* redfish\_config \- adding <code>SetSecureBoot</code> command \([https\://github\.com/ansible\-collections/community\.general/pull/7129](https\://github\.com/ansible\-collections/community\.general/pull/7129)\)\.
-* redfish\_info \- add <code>AccountTypes</code> and <code>OEMAccountTypes</code> to the output of <code>ListUsers</code> \([https\://github\.com/ansible\-collections/community\.general/issues/6823](https\://github\.com/ansible\-collections/community\.general/issues/6823)\, [https\://github\.com/ansible\-collections/community\.general/pull/6871](https\://github\.com/ansible\-collections/community\.general/pull/6871)\)\.
-* redfish\_info \- add support for <code>GetBiosRegistries</code> command \([https\://github\.com/ansible\-collections/community\.general/pull/7144](https\://github\.com/ansible\-collections/community\.general/pull/7144)\)\.
-* redfish\_info \- adds <code>LinkStatus</code> to NIC inventory \([https\://github\.com/ansible\-collections/community\.general/pull/7318](https\://github\.com/ansible\-collections/community\.general/pull/7318)\)\.
-* redfish\_info \- adds <code>ProcessorArchitecture</code> to CPU inventory \([https\://github\.com/ansible\-collections/community\.general/pull/6864](https\://github\.com/ansible\-collections/community\.general/pull/6864)\)\.
-* redfish\_info \- fix for <code>GetVolumeInventory</code>\, Controller name was getting populated incorrectly and duplicates were seen in the volumes retrieved \([https\://github\.com/ansible\-collections/community\.general/pull/6719](https\://github\.com/ansible\-collections/community\.general/pull/6719)\)\.
-* redfish\_info \- report <code>Id</code> in the output of <code>GetManagerInventory</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7140](https\://github\.com/ansible\-collections/community\.general/pull/7140)\)\.
-* redfish\_utils \- use <code>Controllers</code> key in redfish data to obtain Storage controllers properties \([https\://github\.com/ansible\-collections/community\.general/pull/7081](https\://github\.com/ansible\-collections/community\.general/pull/7081)\)\.
-* redfish\_utils module utils \- add support for <code>PowerCycle</code> reset type for <code>redfish\_command</code> responses feature \([https\://github\.com/ansible\-collections/community\.general/issues/7083](https\://github\.com/ansible\-collections/community\.general/issues/7083)\)\.
-* redfish\_utils module utils \- add support for following <code>\@odata\.nextLink</code> pagination in <code>software\_inventory</code> responses feature \([https\://github\.com/ansible\-collections/community\.general/pull/7020](https\://github\.com/ansible\-collections/community\.general/pull/7020)\)\.
-* redfish\_utils module utils \- support <code>Volumes</code> in response for <code>GetDiskInventory</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6819](https\://github\.com/ansible\-collections/community\.general/pull/6819)\)\.
-* redhat\_subscription \- the internal <code>RegistrationBase</code> class was folded
- into the other internal <code>Rhsm</code> class\, as the separation had no purpose
- anymore
- \([https\://github\.com/ansible\-collections/community\.general/pull/6658](https\://github\.com/ansible\-collections/community\.general/pull/6658)\)\.
-* redis\_info \- refactor the redis\_info module to use the redis module\_utils enabling to pass TLS parameters to the Redis client \([https\://github\.com/ansible\-collections/community\.general/pull/7267](https\://github\.com/ansible\-collections/community\.general/pull/7267)\)\.
-* rhsm\_release \- improve/harden the way <code>subscription\-manager</code> is run\;
- no behaviour change is expected
- \([https\://github\.com/ansible\-collections/community\.general/pull/6669](https\://github\.com/ansible\-collections/community\.general/pull/6669)\)\.
-* rhsm\_repository \- the interaction with <code>subscription\-manager</code> was
- refactored by grouping things together\, removing unused bits\, and hardening
- the way it is run\; also\, the parsing of <code>subscription\-manager repos \-\-list</code>
- was improved and made slightly faster\; no behaviour change is expected
- \([https\://github\.com/ansible\-collections/community\.general/pull/6783](https\://github\.com/ansible\-collections/community\.general/pull/6783)\,
- [https\://github\.com/ansible\-collections/community\.general/pull/6837](https\://github\.com/ansible\-collections/community\.general/pull/6837)\)\.
-* scaleway\_security\_group\_rule \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6928](https\://github\.com/ansible\-collections/community\.general/pull/6928)\)\.
-* shutdown \- use <code>shutdown \-p \.\.\.</code> with FreeBSD to halt and power off machine \([https\://github\.com/ansible\-collections/community\.general/pull/7102](https\://github\.com/ansible\-collections/community\.general/pull/7102)\)\.
-* snap \- add option <code>dangerous</code> to the module\, that will map into the command line argument <code>\-\-dangerous</code>\, allowing unsigned snap files to be installed \([https\://github\.com/ansible\-collections/community\.general/pull/6908](https\://github\.com/ansible\-collections/community\.general/pull/6908)\, [https\://github\.com/ansible\-collections/community\.general/issues/5715](https\://github\.com/ansible\-collections/community\.general/issues/5715)\)\.
-* snap \- module is now aware of channel when deciding whether to install or refresh the snap \([https\://github\.com/ansible\-collections/community\.general/pull/6435](https\://github\.com/ansible\-collections/community\.general/pull/6435)\, [https\://github\.com/ansible\-collections/community\.general/issues/1606](https\://github\.com/ansible\-collections/community\.general/issues/1606)\)\.
-* sorcery \- add grimoire \(repository\) management support \([https\://github\.com/ansible\-collections/community\.general/pull/7012](https\://github\.com/ansible\-collections/community\.general/pull/7012)\)\.
-* sorcery \- minor refactor \([https\://github\.com/ansible\-collections/community\.general/pull/6525](https\://github\.com/ansible\-collections/community\.general/pull/6525)\)\.
-* supervisorctl \- allow to stop matching running processes before removing them with <code>stop\_before\_removing\=true</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7284](https\://github\.com/ansible\-collections/community\.general/pull/7284)\)\.
-* tss lookup plugin \- allow to fetch secret IDs which are in a folder based on folder ID\. Previously\, we could not fetch secrets based on folder ID but now use <code>fetch\_secret\_ids\_from\_folder</code> option to indicate to fetch secret IDs based on folder ID \([https\://github\.com/ansible\-collections/community\.general/issues/6223](https\://github\.com/ansible\-collections/community\.general/issues/6223)\)\.
-* tss lookup plugin \- allow to fetch secret by path\. Previously\, we could not fetch secret by path but now use <code>secret\_path</code> option to indicate to fetch secret by secret path \([https\://github\.com/ansible\-collections/community\.general/pull/6881](https\://github\.com/ansible\-collections/community\.general/pull/6881)\)\.
-* unixy callback plugin \- add support for <code>check\_mode\_markers</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7179](https\://github\.com/ansible\-collections/community\.general/pull/7179)\)\.
-* vardict module utils \- added convenience methods to <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6647](https\://github\.com/ansible\-collections/community\.general/pull/6647)\)\.
-* xenserver\_guest\_info \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6928](https\://github\.com/ansible\-collections/community\.general/pull/6928)\)\.
-* xenserver\_guest\_powerstate \- minor refactor removing unnecessary code statements \([https\://github\.com/ansible\-collections/community\.general/pull/6928](https\://github\.com/ansible\-collections/community\.general/pull/6928)\)\.
-* yum\_versionlock \- add support to pin specific package versions instead of only the package itself \([https\://github\.com/ansible\-collections/community\.general/pull/6861](https\://github\.com/ansible\-collections/community\.general/pull/6861)\, [https\://github\.com/ansible\-collections/community\.general/issues/4470](https\://github\.com/ansible\-collections/community\.general/issues/4470)\)\.
+<a id="callback"></a>
+#### Callback
-<a id="breaking-changes--porting-guide"></a>
-### Breaking Changes / Porting Guide
+* community\.general\.default\_without\_diff \- The default ansible callback without diff output\.
+* community\.general\.timestamp \- Adds simple timestamp for each header\.
-* collection\_version lookup plugin \- remove compatibility code for ansible\-base 2\.10 and ansible\-core 2\.11 \([https\://github\.com/ansible\-collections/community\.general/pull/7269](https\://github\.com/ansible\-collections/community\.general/pull/7269)\)\.
-* gitlab\_project \- add <code>default\_branch</code> support for project update\. If you used the module so far with <code>default\_branch</code> to update a project\, the value of <code>default\_branch</code> was ignored\. Make sure that you either do not pass a value if you are not sure whether it is the one you want to have to avoid unexpected breaking changes \([https\://github\.com/ansible\-collections/community\.general/pull/7158](https\://github\.com/ansible\-collections/community\.general/pull/7158)\)\.
-* selective callback plugin \- remove compatibility code for Ansible 2\.9 and ansible\-core 2\.10 \([https\://github\.com/ansible\-collections/community\.general/pull/7269](https\://github\.com/ansible\-collections/community\.general/pull/7269)\)\.
-* vardict module utils \- <code>VarDict</code> will no longer accept variables named <code>\_var</code>\, <code>get\_meta</code>\, and <code>as\_dict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6647](https\://github\.com/ansible\-collections/community\.general/pull/6647)\)\.
-* version module util \- remove fallback for ansible\-core 2\.11\. All modules and plugins that do version collections no longer work with ansible\-core 2\.11 \([https\://github\.com/ansible\-collections/community\.general/pull/7269](https\://github\.com/ansible\-collections/community\.general/pull/7269)\)\.
+<a id="connection"></a>
+#### Connection
-<a id="deprecated-features-2"></a>
-### Deprecated Features
+* community\.general\.incus \- Run tasks in Incus instances via the Incus CLI\.
-* CmdRunner module utils \- deprecate <code>cmd\_runner\_fmt\.as\_default\_type\(\)</code> formatter \([https\://github\.com/ansible\-collections/community\.general/pull/6601](https\://github\.com/ansible\-collections/community\.general/pull/6601)\)\.
-* MH VarsMixin module utils \- deprecates <code>VarsMixin</code> and supporting classes in favor of plain <code>vardict</code> module util \([https\://github\.com/ansible\-collections/community\.general/pull/6649](https\://github\.com/ansible\-collections/community\.general/pull/6649)\)\.
-* ansible\_galaxy\_install \- the <code>ack\_ansible29</code> and <code>ack\_min\_ansiblecore211</code> options have been deprecated and will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* consul \- the <code>ack\_params\_state\_absent</code> option has been deprecated and will be removed in community\.general 10\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* cpanm \- value <code>compatibility</code> is deprecated as default for parameter <code>mode</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6512](https\://github\.com/ansible\-collections/community\.general/pull/6512)\)\.
-* ejabberd\_user \- deprecate the parameter <code>logging</code> in favour of producing more detailed information in the module output \([https\://github\.com/ansible\-collections/community\.general/pull/7043](https\://github\.com/ansible\-collections/community\.general/pull/7043)\)\.
-* flowdock \- module relies entirely on no longer responsive API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6930](https\://github\.com/ansible\-collections/community\.general/pull/6930)\)\.
-* proxmox \- old feature flag <code>proxmox\_default\_behavior</code> will be removed in community\.general 10\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6836](https\://github\.com/ansible\-collections/community\.general/pull/6836)\)\.
-* proxmox\_kvm \- deprecate the option <code>proxmox\_default\_behavior</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7377](https\://github\.com/ansible\-collections/community\.general/pull/7377)\)\.
-* redfish\_info\, redfish\_config\, redfish\_command \- the default value <code>10</code> for the <code>timeout</code> option is deprecated and will change to <code>60</code> in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/7295](https\://github\.com/ansible\-collections/community\.general/pull/7295)\)\.
-* redhat module utils \- the <code>module\_utils\.redhat</code> module is deprecated\, as
- effectively unused\: the <code>Rhsm</code>\, <code>RhsmPool</code>\, and <code>RhsmPools</code> classes
- will be removed in community\.general 9\.0\.0\; the <code>RegistrationBase</code> class
- will be removed in community\.general 10\.0\.0 together with the
- <code>rhn\_register</code> module\, as it is the only user of this class\; this means
- that the whole <code>module\_utils\.redhat</code> module will be dropped in
- community\.general 10\.0\.0\, so importing it without even using anything of it
- will fail
- \([https\://github\.com/ansible\-collections/community\.general/pull/6663](https\://github\.com/ansible\-collections/community\.general/pull/6663)\)\.
-* redhat\_subscription \- the <code>autosubscribe</code> alias for the <code>auto\_attach</code> option has been
- deprecated for many years\, although only in the documentation\. Officially mark this alias
- as deprecated\, and it will be removed in community\.general 9\.0\.0
- \([https\://github\.com/ansible\-collections/community\.general/pull/6646](https\://github\.com/ansible\-collections/community\.general/pull/6646)\)\.
-* redhat\_subscription \- the <code>pool</code> option is deprecated in favour of the
- more precise and flexible <code>pool\_ids</code> option
- \([https\://github\.com/ansible\-collections/community\.general/pull/6650](https\://github\.com/ansible\-collections/community\.general/pull/6650)\)\.
-* rhsm\_repository \- <code>state\=present</code> has not been working as expected for many years\,
- and it seems it was not noticed so far\; also\, \"presence\" is not really a valid concept
- for subscription repositories\, which can only be enabled or disabled\. Hence\, mark the
- <code>present</code> and <code>absent</code> values of the <code>state</code> option as deprecated\, slating them
- for removal in community\.general 10\.0\.0
- \([https\://github\.com/ansible\-collections/community\.general/pull/6673](https\://github\.com/ansible\-collections/community\.general/pull/6673)\)\.
-* stackdriver \- module relies entirely on no longer existent API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6887](https\://github\.com/ansible\-collections/community\.general/pull/6887)\)\.
-* webfaction\_app \- module relies entirely on no longer existent API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6909](https\://github\.com/ansible\-collections/community\.general/pull/6909)\)\.
-* webfaction\_db \- module relies entirely on no longer existent API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6909](https\://github\.com/ansible\-collections/community\.general/pull/6909)\)\.
-* webfaction\_domain \- module relies entirely on no longer existent API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6909](https\://github\.com/ansible\-collections/community\.general/pull/6909)\)\.
-* webfaction\_mailbox \- module relies entirely on no longer existent API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6909](https\://github\.com/ansible\-collections/community\.general/pull/6909)\)\.
-* webfaction\_site \- module relies entirely on no longer existent API endpoints\, and it will be removed in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/6909](https\://github\.com/ansible\-collections/community\.general/pull/6909)\)\.
+<a id="filter"></a>
+#### Filter
-<a id="removed-features-previously-deprecated"></a>
-### Removed Features \(previously deprecated\)
+* community\.general\.from\_ini \- Converts INI text input into a dictionary\.
+* community\.general\.lists\_difference \- Difference of lists with a predictive order\.
+* community\.general\.lists\_intersect \- Intersection of lists with a predictive order\.
+* community\.general\.lists\_symmetric\_difference \- Symmetric Difference of lists with a predictive order\.
+* community\.general\.lists\_union \- Union of lists with a predictive order\.
+* community\.general\.to\_ini \- Converts a dictionary to the INI file format\.
-* The collection no longer supports ansible\-core 2\.11 and ansible\-core 2\.12\. Parts of the collection might still work on these ansible\-core versions\, but others might not \([https\://github\.com/ansible\-collections/community\.general/pull/7269](https\://github\.com/ansible\-collections/community\.general/pull/7269)\)\.
-* ansible\_galaxy\_install \- support for Ansible 2\.9 and ansible\-base 2\.10 has been removed \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* consul \- when <code>state\=absent</code>\, the options <code>script</code>\, <code>ttl</code>\, <code>tcp</code>\, <code>http</code>\, and <code>interval</code> can no longer be specified \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* gconftool2 \- <code>state\=get</code> has been removed\. Use the module <code>community\.general\.gconftool2\_info</code> instead \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* gitlab\_runner \- remove the default value for the <code>access\_level</code> option\. To restore the previous behavior\, explicitly set it to <code>ref\_protected</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* htpasswd \- removed code for passlib \<1\.6 \([https\://github\.com/ansible\-collections/community\.general/pull/6901](https\://github\.com/ansible\-collections/community\.general/pull/6901)\)\.
-* manageiq\_polices \- <code>state\=list</code> has been removed\. Use the module <code>community\.general\.manageiq\_policies\_info</code> instead \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* manageiq\_tags \- <code>state\=list</code> has been removed\. Use the module <code>community\.general\.manageiq\_tags\_info</code> instead \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* mh\.mixins\.cmd module utils \- the <code>ArgFormat</code> class has been removed \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* mh\.mixins\.cmd module utils \- the <code>CmdMixin</code> mixin has been removed\. Use <code>community\.general\.plugins\.module\_utils\.cmd\_runner\.CmdRunner</code> instead \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* mh\.mixins\.cmd module utils \- the mh\.mixins\.cmd module utils has been removed after all its contents were removed \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* mh\.module\_helper module utils \- the <code>CmdModuleHelper</code> and <code>CmdStateModuleHelper</code> classes have been removed\. Use <code>community\.general\.plugins\.module\_utils\.cmd\_runner\.CmdRunner</code> instead \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-* proxmox module utils \- removed unused imports \([https\://github\.com/ansible\-collections/community\.general/pull/6873](https\://github\.com/ansible\-collections/community\.general/pull/6873)\)\.
-* xfconf \- the deprecated <code>disable\_facts</code> option was removed \([https\://github\.com/ansible\-collections/community\.general/pull/7358](https\://github\.com/ansible\-collections/community\.general/pull/7358)\)\.
-
-<a id="bugfixes-8"></a>
-### Bugfixes
+<a id="lookup"></a>
+#### Lookup
-* CmdRunner module utils \- does not attempt to resolve path if executable is a relative or absolute path \([https\://github\.com/ansible\-collections/community\.general/pull/7200](https\://github\.com/ansible\-collections/community\.general/pull/7200)\)\.
-* MH DependencyMixin module utils \- deprecation notice was popping up for modules not using dependencies \([https\://github\.com/ansible\-collections/community\.general/pull/6644](https\://github\.com/ansible\-collections/community\.general/pull/6644)\, [https\://github\.com/ansible\-collections/community\.general/issues/6639](https\://github\.com/ansible\-collections/community\.general/issues/6639)\)\.
-* bitwarden lookup plugin \- the plugin made assumptions about the structure of a Bitwarden JSON object which may have been broken by an update in the Bitwarden API\. Remove assumptions\, and allow queries for general fields such as <code>notes</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7061](https\://github\.com/ansible\-collections/community\.general/pull/7061)\)\.
-* cmd\_runner module utils \- when a parameter in <code>argument\_spec</code> has no type\, meaning it is implicitly a <code>str</code>\, <code>CmdRunner</code> would fail trying to find the <code>type</code> key in that dictionary \([https\://github\.com/ansible\-collections/community\.general/pull/6968](https\://github\.com/ansible\-collections/community\.general/pull/6968)\)\.
-* cobbler inventory plugin \- fix calculation of cobbler\_ipv4/6\_address \([https\://github\.com/ansible\-collections/community\.general/pull/6925](https\://github\.com/ansible\-collections/community\.general/pull/6925)\)\.
-* composer \- fix impossible to run <code>working\_dir</code> dependent commands\. The module was throwing an error when trying to run a <code>working\_dir</code> dependent command\, because it tried to get the command help without passing the <code>working\_dir</code> \([https\://github\.com/ansible\-collections/community\.general/issues/3787](https\://github\.com/ansible\-collections/community\.general/issues/3787)\)\.
-* csv module utils \- detects and remove unicode BOM markers from incoming CSV content \([https\://github\.com/ansible\-collections/community\.general/pull/6662](https\://github\.com/ansible\-collections/community\.general/pull/6662)\)\.
-* datadog\_downtime \- presence of <code>rrule</code> param lead to the Datadog API returning Bad Request due to a missing recurrence type \([https\://github\.com/ansible\-collections/community\.general/pull/6811](https\://github\.com/ansible\-collections/community\.general/pull/6811)\)\.
-* ejabberd\_user \- module was failing to detect whether user was already created and/or password was changed \([https\://github\.com/ansible\-collections/community\.general/pull/7033](https\://github\.com/ansible\-collections/community\.general/pull/7033)\)\.
-* ejabberd\_user \- provide meaningful error message when the <code>ejabberdctl</code> command is not found \([https\://github\.com/ansible\-collections/community\.general/pull/7028](https\://github\.com/ansible\-collections/community\.general/pull/7028)\, [https\://github\.com/ansible\-collections/community\.general/issues/6949](https\://github\.com/ansible\-collections/community\.general/issues/6949)\)\.
-* github\_deploy\_key \- fix pagination behaviour causing a crash when only a single page of deploy keys exist \([https\://github\.com/ansible\-collections/community\.general/pull/7375](https\://github\.com/ansible\-collections/community\.general/pull/7375)\)\.
-* gitlab\_group \- the module passed parameters to the API call even when not set\. The module is now filtering out <code>None</code> values to remediate this \([https\://github\.com/ansible\-collections/community\.general/pull/6712](https\://github\.com/ansible\-collections/community\.general/pull/6712)\)\.
-* gitlab\_group\_variable \- deleted all variables when used with <code>purge\=true</code> due to missing <code>raw</code> property in KNOWN attributes \([https\://github\.com/ansible\-collections/community\.general/issues/7250](https\://github\.com/ansible\-collections/community\.general/issues/7250)\)\.
-* gitlab\_project\_variable \- deleted all variables when used with <code>purge\=true</code> due to missing <code>raw</code> property in KNOWN attributes \([https\://github\.com/ansible\-collections/community\.general/issues/7250](https\://github\.com/ansible\-collections/community\.general/issues/7250)\)\.
-* icinga2\_host \- fix a key error when updating an existing host \([https\://github\.com/ansible\-collections/community\.general/pull/6748](https\://github\.com/ansible\-collections/community\.general/pull/6748)\)\.
-* ini\_file \- add the <code>follow</code> paramter to follow the symlinks instead of replacing them \([https\://github\.com/ansible\-collections/community\.general/pull/6546](https\://github\.com/ansible\-collections/community\.general/pull/6546)\)\.
-* ini\_file \- fix a bug where the inactive options were not used when possible \([https\://github\.com/ansible\-collections/community\.general/pull/6575](https\://github\.com/ansible\-collections/community\.general/pull/6575)\)\.
-* ipa\_dnszone \- fix \'idnsallowsyncptr\' key error for reverse zone \([https\://github\.com/ansible\-collections/community\.general/pull/6906](https\://github\.com/ansible\-collections/community\.general/pull/6906)\, [https\://github\.com/ansible\-collections/community\.general/issues/6905](https\://github\.com/ansible\-collections/community\.general/issues/6905)\)\.
-* kernel\_blacklist \- simplified the mechanism to update the file\, fixing the error \([https\://github\.com/ansible\-collections/community\.general/pull/7382](https\://github\.com/ansible\-collections/community\.general/pull/7382)\, [https\://github\.com/ansible\-collections/community\.general/issues/7362](https\://github\.com/ansible\-collections/community\.general/issues/7362)\)\.
-* keycloak module util \- fix missing <code>http\_agent</code>\, <code>timeout</code>\, and <code>validate\_certs</code> <code>open\_url\(\)</code> parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7067](https\://github\.com/ansible\-collections/community\.general/pull/7067)\)\.
-* keycloak module utils \- fix <code>is\_struct\_included</code> handling of lists of lists/dictionaries \([https\://github\.com/ansible\-collections/community\.general/pull/6688](https\://github\.com/ansible\-collections/community\.general/pull/6688)\)\.
-* keycloak module utils \- the function <code>get\_user\_by\_username</code> now return the user representation or <code>None</code> as stated in the documentation \([https\://github\.com/ansible\-collections/community\.general/pull/6758](https\://github\.com/ansible\-collections/community\.general/pull/6758)\)\.
-* keycloak\_authentication \- fix Keycloak authentication flow \(step or sub\-flow\) indexing during update\, if not specified by the user \([https\://github\.com/ansible\-collections/community\.general/pull/6734](https\://github\.com/ansible\-collections/community\.general/pull/6734)\)\.
-* keycloak\_client inventory plugin \- fix missing client secret \([https\://github\.com/ansible\-collections/community\.general/pull/6931](https\://github\.com/ansible\-collections/community\.general/pull/6931)\)\.
-* ldap\_search \- fix string normalization and the <code>base64\_attributes</code> option on Python 3 \([https\://github\.com/ansible\-collections/community\.general/issues/5704](https\://github\.com/ansible\-collections/community\.general/issues/5704)\, [https\://github\.com/ansible\-collections/community\.general/pull/7264](https\://github\.com/ansible\-collections/community\.general/pull/7264)\)\.
-* locale\_gen \- now works for locales without the underscore character such as <code>C\.UTF\-8</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6774](https\://github\.com/ansible\-collections/community\.general/pull/6774)\, [https\://github\.com/ansible\-collections/community\.general/issues/5142](https\://github\.com/ansible\-collections/community\.general/issues/5142)\, [https\://github\.com/ansible\-collections/community\.general/issues/4305](https\://github\.com/ansible\-collections/community\.general/issues/4305)\)\.
-* lvol \- add support for percentage of origin size specification when creating snapshot volumes \([https\://github\.com/ansible\-collections/community\.general/issues/1630](https\://github\.com/ansible\-collections/community\.general/issues/1630)\, [https\://github\.com/ansible\-collections/community\.general/pull/7053](https\://github\.com/ansible\-collections/community\.general/pull/7053)\)\.
-* lxc connection plugin \- now handles <code>remote\_addr</code> defaulting to <code>inventory\_hostname</code> correctly \([https\://github\.com/ansible\-collections/community\.general/pull/7104](https\://github\.com/ansible\-collections/community\.general/pull/7104)\)\.
-* lxc connection plugin \- properly evaluate options \([https\://github\.com/ansible\-collections/community\.general/pull/7369](https\://github\.com/ansible\-collections/community\.general/pull/7369)\)\.
-* machinectl become plugin \- mark plugin as <code>require\_tty</code> to automatically disable pipelining\, with which this plugin is not compatible \([https\://github\.com/ansible\-collections/community\.general/issues/6932](https\://github\.com/ansible\-collections/community\.general/issues/6932)\, [https\://github\.com/ansible\-collections/community\.general/pull/6935](https\://github\.com/ansible\-collections/community\.general/pull/6935)\)\.
-* mail \- skip headers containing equals characters due to missing <code>maxsplit</code> on header key/value parsing \([https\://github\.com/ansible\-collections/community\.general/pull/7303](https\://github\.com/ansible\-collections/community\.general/pull/7303)\)\.
-* memset module utils \- make compatible with ansible\-core 2\.17 \([https\://github\.com/ansible\-collections/community\.general/pull/7379](https\://github\.com/ansible\-collections/community\.general/pull/7379)\)\.
-* nmap inventory plugin \- fix <code>get\_option</code> calls \([https\://github\.com/ansible\-collections/community\.general/pull/7323](https\://github\.com/ansible\-collections/community\.general/pull/7323)\)\.
-* nmap inventory plugin \- now uses <code>get\_option</code> in all cases to get its configuration information \([https\://github\.com/ansible\-collections/community\.general/pull/7119](https\://github\.com/ansible\-collections/community\.general/pull/7119)\)\.
-* nmcli \- fix bond option <code>xmit\_hash\_policy</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6527](https\://github\.com/ansible\-collections/community\.general/pull/6527)\)\.
-* nmcli \- fix support for empty list \(in compare and scrape\) \([https\://github\.com/ansible\-collections/community\.general/pull/6769](https\://github\.com/ansible\-collections/community\.general/pull/6769)\)\.
-* nsupdate \- fix a possible <code>list index out of range</code> exception \([https\://github\.com/ansible\-collections/community\.general/issues/836](https\://github\.com/ansible\-collections/community\.general/issues/836)\)\.
-* oci\_utils module util \- fix inappropriate logical comparison expressions and makes them simpler\. The previous checks had logical short circuits \([https\://github\.com/ansible\-collections/community\.general/pull/7125](https\://github\.com/ansible\-collections/community\.general/pull/7125)\)\.
-* oci\_utils module utils \- avoid direct type comparisons \([https\://github\.com/ansible\-collections/community\.general/pull/7085](https\://github\.com/ansible\-collections/community\.general/pull/7085)\)\.
-* onepassword \- fix KeyError exception when trying to access value of a field that is not filled out in OnePassword item \([https\://github\.com/ansible\-collections/community\.general/pull/7241](https\://github\.com/ansible\-collections/community\.general/pull/7241)\)\.
-* openbsd\_pkg \- the pkg\_info\(1\) behavior has changed in OpenBSD \>7\.3\. The error message <code>Can\'t find</code> should not lead to an error case \([https\://github\.com/ansible\-collections/community\.general/pull/6785](https\://github\.com/ansible\-collections/community\.general/pull/6785)\)\.
-* pacman \- module recognizes the output of <code>yay</code> running as <code>root</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6713](https\://github\.com/ansible\-collections/community\.general/pull/6713)\)\.
-* portage \- fix <code>changed\_use</code> and <code>newuse</code> not triggering rebuilds \([https\://github\.com/ansible\-collections/community\.general/issues/6008](https\://github\.com/ansible\-collections/community\.general/issues/6008)\, [https\://github\.com/ansible\-collections/community\.general/pull/6548](https\://github\.com/ansible\-collections/community\.general/pull/6548)\)\.
-* pritunl module utils \- fix incorrect URL parameter for orgnization add method \([https\://github\.com/ansible\-collections/community\.general/pull/7161](https\://github\.com/ansible\-collections/community\.general/pull/7161)\)\.
-* proxmox \- fix error when a configuration had no <code>template</code> field \([https\://github\.com/ansible\-collections/community\.general/pull/6838](https\://github\.com/ansible\-collections/community\.general/pull/6838)\, [https\://github\.com/ansible\-collections/community\.general/issues/5372](https\://github\.com/ansible\-collections/community\.general/issues/5372)\)\.
-* proxmox module utils \- add logic to detect whether an old Promoxer complains about the <code>token\_name</code> and <code>token\_value</code> parameters and provide a better error message when that happens \([https\://github\.com/ansible\-collections/community\.general/pull/6839](https\://github\.com/ansible\-collections/community\.general/pull/6839)\, [https\://github\.com/ansible\-collections/community\.general/issues/5371](https\://github\.com/ansible\-collections/community\.general/issues/5371)\)\.
-* proxmox module utils \- fix proxmoxer library version check \([https\://github\.com/ansible\-collections/community\.general/issues/6974](https\://github\.com/ansible\-collections/community\.general/issues/6974)\, [https\://github\.com/ansible\-collections/community\.general/issues/6975](https\://github\.com/ansible\-collections/community\.general/issues/6975)\, [https\://github\.com/ansible\-collections/community\.general/pull/6980](https\://github\.com/ansible\-collections/community\.general/pull/6980)\)\.
-* proxmox\_disk \- fix unable to create <code>cdrom</code> media due to <code>size</code> always being appended \([https\://github\.com/ansible\-collections/community\.general/pull/6770](https\://github\.com/ansible\-collections/community\.general/pull/6770)\)\.
-* proxmox\_kvm \- <code>absent</code> state with <code>force</code> specified failed to stop the VM due to the <code>timeout</code> value not being passed to <code>stop\_vm</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6827](https\://github\.com/ansible\-collections/community\.general/pull/6827)\)\.
-* proxmox\_kvm \- <code>restarted</code> state did not actually restart a VM in some VM configurations\. The state now uses the Proxmox reboot endpoint instead of calling the <code>stop\_vm</code> and <code>start\_vm</code> functions \([https\://github\.com/ansible\-collections/community\.general/pull/6773](https\://github\.com/ansible\-collections/community\.general/pull/6773)\)\.
-* proxmox\_kvm \- allow creation of VM with existing name but new vmid \([https\://github\.com/ansible\-collections/community\.general/issues/6155](https\://github\.com/ansible\-collections/community\.general/issues/6155)\, [https\://github\.com/ansible\-collections/community\.general/pull/6709](https\://github\.com/ansible\-collections/community\.general/pull/6709)\)\.
-* proxmox\_kvm \- when <code>name</code> option is provided without <code>vmid</code> and VM with that name already exists then no new VM will be created \([https\://github\.com/ansible\-collections/community\.general/issues/6911](https\://github\.com/ansible\-collections/community\.general/issues/6911)\, [https\://github\.com/ansible\-collections/community\.general/pull/6981](https\://github\.com/ansible\-collections/community\.general/pull/6981)\)\.
-* proxmox\_tasks\_info \- remove <code>api\_user</code> \+ <code>api\_password</code> constraint from <code>required\_together</code> as it causes to require <code>api\_password</code> even when API token param is used \([https\://github\.com/ansible\-collections/community\.general/issues/6201](https\://github\.com/ansible\-collections/community\.general/issues/6201)\)\.
-* proxmox\_template \- require <code>requests\_toolbelt</code> module to fix issue with uploading large templates \([https\://github\.com/ansible\-collections/community\.general/issues/5579](https\://github\.com/ansible\-collections/community\.general/issues/5579)\, [https\://github\.com/ansible\-collections/community\.general/pull/6757](https\://github\.com/ansible\-collections/community\.general/pull/6757)\)\.
-* proxmox\_user\_info \- avoid direct type comparisons \([https\://github\.com/ansible\-collections/community\.general/pull/7085](https\://github\.com/ansible\-collections/community\.general/pull/7085)\)\.
-* redfish\_info \- fix <code>ListUsers</code> to not show empty account slots \([https\://github\.com/ansible\-collections/community\.general/issues/6771](https\://github\.com/ansible\-collections/community\.general/issues/6771)\, [https\://github\.com/ansible\-collections/community\.general/pull/6772](https\://github\.com/ansible\-collections/community\.general/pull/6772)\)\.
-* redhat\_subscription \- use the right D\-Bus options for the consumer type when
- registering a RHEL system older than 9 or a RHEL 9 system older than 9\.2
- and using <code>consumer\_type</code>
- \([https\://github\.com/ansible\-collections/community\.general/pull/7378](https\://github\.com/ansible\-collections/community\.general/pull/7378)\)\.
-* refish\_utils module utils \- changing variable names to avoid issues occuring when fetching Volumes data \([https\://github\.com/ansible\-collections/community\.general/pull/6883](https\://github\.com/ansible\-collections/community\.general/pull/6883)\)\.
-* rhsm\_repository \- when using the <code>purge</code> option\, the <code>repositories</code>
- dictionary element in the returned JSON is now properly updated according
- to the pruning operation
- \([https\://github\.com/ansible\-collections/community\.general/pull/6676](https\://github\.com/ansible\-collections/community\.general/pull/6676)\)\.
-* rundeck \- fix <code>TypeError</code> on 404 API response \([https\://github\.com/ansible\-collections/community\.general/pull/6983](https\://github\.com/ansible\-collections/community\.general/pull/6983)\)\.
-* selective callback plugin \- fix length of task name lines in output always being 3 characters longer than desired \([https\://github\.com/ansible\-collections/community\.general/pull/7374](https\://github\.com/ansible\-collections/community\.general/pull/7374)\)\.
-* snap \- an exception was being raised when snap list was empty \([https\://github\.com/ansible\-collections/community\.general/pull/7124](https\://github\.com/ansible\-collections/community\.general/pull/7124)\, [https\://github\.com/ansible\-collections/community\.general/issues/7120](https\://github\.com/ansible\-collections/community\.general/issues/7120)\)\.
-* snap \- assume default track <code>latest</code> in parameter <code>channel</code> when not specified \([https\://github\.com/ansible\-collections/community\.general/pull/6835](https\://github\.com/ansible\-collections/community\.general/pull/6835)\, [https\://github\.com/ansible\-collections/community\.general/issues/6821](https\://github\.com/ansible\-collections/community\.general/issues/6821)\)\.
-* snap \- change the change detection mechanism from \"parsing installation\" to \"comparing end state with initial state\" \([https\://github\.com/ansible\-collections/community\.general/pull/7340](https\://github\.com/ansible\-collections/community\.general/pull/7340)\, [https\://github\.com/ansible\-collections/community\.general/issues/7265](https\://github\.com/ansible\-collections/community\.general/issues/7265)\)\.
-* snap \- fix crash when multiple snaps are specified and one has <code>\-\-\-</code> in its description \([https\://github\.com/ansible\-collections/community\.general/pull/7046](https\://github\.com/ansible\-collections/community\.general/pull/7046)\)\.
-* snap \- fix the processing of the commands\' output\, stripping spaces and newlines from it \([https\://github\.com/ansible\-collections/community\.general/pull/6826](https\://github\.com/ansible\-collections/community\.general/pull/6826)\, [https\://github\.com/ansible\-collections/community\.general/issues/6803](https\://github\.com/ansible\-collections/community\.general/issues/6803)\)\.
-* sorcery \- fix interruption of the multi\-stage process \([https\://github\.com/ansible\-collections/community\.general/pull/7012](https\://github\.com/ansible\-collections/community\.general/pull/7012)\)\.
-* sorcery \- fix queue generation before the whole system rebuild \([https\://github\.com/ansible\-collections/community\.general/pull/7012](https\://github\.com/ansible\-collections/community\.general/pull/7012)\)\.
-* sorcery \- latest state no longer triggers update\_cache \([https\://github\.com/ansible\-collections/community\.general/pull/7012](https\://github\.com/ansible\-collections/community\.general/pull/7012)\)\.
-* terraform \- prevents <code>\-backend\-config</code> option double encapsulating with <code>shlex\_quote</code> function\. \([https\://github\.com/ansible\-collections/community\.general/pull/7301](https\://github\.com/ansible\-collections/community\.general/pull/7301)\)\.
-* tss lookup plugin \- fix multiple issues when using <code>fetch\_attachments\=true</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6720](https\://github\.com/ansible\-collections/community\.general/pull/6720)\)\.
-* zypper \- added handling of zypper exitcode 102\. Changed state is set correctly now and rc 102 is still preserved to be evaluated by the playbook \([https\://github\.com/ansible\-collections/community\.general/pull/6534](https\://github\.com/ansible\-collections/community\.general/pull/6534)\)\.
-
-<a id="known-issues"></a>
-### Known Issues
-
-* Ansible markup will show up in raw form on ansible\-doc text output for ansible\-core before 2\.15\. If you have trouble deciphering the documentation markup\, please upgrade to ansible\-core 2\.15 \(or newer\)\, or read the HTML documentation on [https\://docs\.ansible\.com/ansible/devel/collections/community/general/](https\://docs\.ansible\.com/ansible/devel/collections/community/general/) \([https\://github\.com/ansible\-collections/community\.general/pull/6539](https\://github\.com/ansible\-collections/community\.general/pull/6539)\)\.
-
-<a id="new-plugins-3"></a>
-### New Plugins
+* community\.general\.github\_app\_access\_token \- Obtain short\-lived Github App Access tokens\.
+* community\.general\.onepassword\_doc \- Fetch documents stored in 1Password\.
-<a id="lookup-2"></a>
-#### Lookup
+<a id="test"></a>
+#### Test
-* bitwarden\_secrets\_manager \- Retrieve secrets from Bitwarden Secrets Manager
+* community\.general\.fqdn\_valid \- Validates fully\-qualified domain names against RFC 1123\.
-<a id="new-modules-6"></a>
+<a id="new-modules"></a>
### New Modules
-* consul\_policy \- Manipulate Consul policies
-* consul\_role \- Manipulate Consul roles
-* facter\_facts \- Runs the discovery program C\(facter\) on the remote system and return Ansible facts
-* gio\_mime \- Set default handler for MIME type\, for applications using Gnome GIO
-* gitlab\_instance\_variable \- Creates\, updates\, or deletes GitLab instance variables
-* gitlab\_merge\_request \- Create\, update\, or delete GitLab merge requests
-* jenkins\_build\_info \- Get information about Jenkins builds
-* keycloak\_authentication\_required\_actions \- Allows administration of Keycloak authentication required actions
-* keycloak\_authz\_custom\_policy \- Allows administration of Keycloak client custom Javascript policies via Keycloak API
-* keycloak\_authz\_permission \- Allows administration of Keycloak client authorization permissions via Keycloak API
-* keycloak\_authz\_permission\_info \- Query Keycloak client authorization permissions information
-* keycloak\_realm\_key \- Allows administration of Keycloak realm keys via Keycloak API
-* keycloak\_user \- Create and configure a user in Keycloak
-* lvg\_rename \- Renames LVM volume groups
-* pnpm \- Manage node\.js packages with pnpm
-* proxmox\_pool \- Pool management for Proxmox VE cluster
-* proxmox\_pool\_member \- Add or delete members from Proxmox VE cluster pools
-* proxmox\_vm\_info \- Retrieve information about one or more Proxmox VE virtual machines
-* simpleinit\_msb \- Manage services on Source Mage GNU/Linux
+* community\.general\.consul\_acl\_bootstrap \- Bootstrap ACLs in Consul\.
+* community\.general\.consul\_auth\_method \- Manipulate Consul auth methods\.
+* community\.general\.consul\_binding\_rule \- Manipulate Consul binding rules\.
+* community\.general\.consul\_token \- Manipulate Consul tokens\.
+* community\.general\.django\_command \- Run Django admin commands\.
+* community\.general\.dnf\_config\_manager \- Enable or disable dnf repositories using config\-manager\.
+* community\.general\.git\_config\_info \- Read git configuration\.
+* community\.general\.gitlab\_group\_access\_token \- Manages GitLab group access tokens\.
+* community\.general\.gitlab\_issue \- Create\, update\, or delete GitLab issues\.
+* community\.general\.gitlab\_label \- Creates/updates/deletes GitLab Labels belonging to project or group\.
+* community\.general\.gitlab\_milestone \- Creates/updates/deletes GitLab Milestones belonging to project or group\.
+* community\.general\.gitlab\_project\_access\_token \- Manages GitLab project access tokens\.
+* community\.general\.keycloak\_client\_rolescope \- Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications\.
+* community\.general\.keycloak\_component\_info \- Retrive component info in Keycloak\.
+* community\.general\.keycloak\_realm\_rolemapping \- Allows administration of Keycloak realm role mappings into groups with the Keycloak API\.
+* community\.general\.nomad\_token \- Manage Nomad ACL tokens\.
+* community\.general\.proxmox\_node\_info \- Retrieve information about one or more Proxmox VE nodes\.
+* community\.general\.proxmox\_storage\_contents\_info \- List content from a Proxmox VE storage\.
+* community\.general\.usb\_facts \- Allows listing information about USB devices\.
diff --git a/ansible_collections/community/general/CHANGELOG.rst b/ansible_collections/community/general/CHANGELOG.rst
index 5a5a0cb7c..384bee747 100644
--- a/ansible_collections/community/general/CHANGELOG.rst
+++ b/ansible_collections/community/general/CHANGELOG.rst
@@ -4,174 +4,59 @@ Community General Release Notes
.. contents:: Topics
-This changelog describes changes after version 7.0.0.
+This changelog describes changes after version 8.0.0.
-v8.6.0
+v9.0.1
======
Release Summary
---------------
-Regular bugfix and features release.
+Bugfix release for inclusion in Ansible 10.0.0rc1.
Minor Changes
-------------
-- Use offset-aware ``datetime.datetime`` objects (with timezone UTC) instead of offset-naive UTC timestamps, which are deprecated in Python 3.12 (https://github.com/ansible-collections/community.general/pull/8222).
-- apt_rpm - add new states ``latest`` and ``present_not_latest``. The value ``latest`` is equivalent to the current behavior of ``present``, which will upgrade a package if a newer version exists. ``present_not_latest`` does what most users would expect ``present`` to do: it does not upgrade if the package is already installed. The current behavior of ``present`` will be deprecated in a later version, and eventually changed to that of ``present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8247).
-- bitwarden lookup plugin - add support to filter by organization ID (https://github.com/ansible-collections/community.general/pull/8188).
-- filesystem - add bcachefs support (https://github.com/ansible-collections/community.general/pull/8126).
-- ini_file - add an optional parameter ``section_has_values``. If the target ini file contains more than one ``section``, use ``section_has_values`` to specify which one should be updated (https://github.com/ansible-collections/community.general/pull/7505).
-- java_cert - add ``cert_content`` argument (https://github.com/ansible-collections/community.general/pull/8153).
-- keycloak_client, keycloak_clientscope, keycloak_clienttemplate - added ``docker-v2`` protocol support, enhancing alignment with Keycloak's protocol options (https://github.com/ansible-collections/community.general/issues/8215, https://github.com/ansible-collections/community.general/pull/8216).
-- nmcli - adds OpenvSwitch support with new ``type`` values ``ovs-port``, ``ovs-interface``, and ``ovs-bridge``, and new ``slave_type`` value ``ovs-port`` (https://github.com/ansible-collections/community.general/pull/8154).
-- osx_defaults - add option ``check_types`` to enable changing the type of existing defaults on the fly (https://github.com/ansible-collections/community.general/pull/8173).
-- passwordstore lookup - add ``missing_subkey`` parameter defining the behavior of the lookup when a passwordstore subkey is missing (https://github.com/ansible-collections/community.general/pull/8166).
-- portage - adds the possibility to explicitely tell portage to write packages to world file (https://github.com/ansible-collections/community.general/issues/6226, https://github.com/ansible-collections/community.general/pull/8236).
-- redfish_command - add command ``ResetToDefaults`` to reset manager to default state (https://github.com/ansible-collections/community.general/issues/8163).
-- redfish_info - add boolean return value ``MultipartHttpPush`` to ``GetFirmwareUpdateCapabilities`` (https://github.com/ansible-collections/community.general/issues/8194, https://github.com/ansible-collections/community.general/pull/8195).
-- ssh_config - allow ``accept-new`` as valid value for ``strict_host_key_checking`` (https://github.com/ansible-collections/community.general/pull/8257).
-
-Deprecated Features
--------------------
-
-- hipchat callback plugin - the hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. The callback plugin is therefore deprecated and will be removed from community.general 10.0.0 if nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/issues/8184, https://github.com/ansible-collections/community.general/pull/8189).
-
-Bugfixes
---------
-
-- aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd`` (https://github.com/ansible-collections/community.general/issues/8151).
-- apt_rpm - when checking whether packages were installed after running ``apt-get -y install <packages>``, only the last package name was checked (https://github.com/ansible-collections/community.general/pull/8263).
-- bitwarden_secrets_manager lookup plugin - implements retry with exponential backoff to avoid lookup errors when Bitwardn's API rate limiting is encountered (https://github.com/ansible-collections/community.general/issues/8230, https://github.com/ansible-collections/community.general/pull/8238).
-- from_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183, https://github.com/ansible-collections/community.general/pull/8185).
-- gitlab_issue, gitlab_label, gitlab_milestone - avoid crash during version comparison when the python-gitlab Python module is not installed (https://github.com/ansible-collections/community.general/pull/8158).
-- haproxy - fix an issue where HAProxy could get stuck in DRAIN mode when the backend was unreachable (https://github.com/ansible-collections/community.general/issues/8092).
-- inventory plugins - add unsafe wrapper to avoid marking strings that do not contain ``{`` or ``}`` as unsafe, to work around a bug in AWX ((https://github.com/ansible-collections/community.general/issues/8212, https://github.com/ansible-collections/community.general/pull/8225).
-- ipa - fix get version regex in IPA module_utils (https://github.com/ansible-collections/community.general/pull/8175).
-- keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes`` to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
-- keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales`` (https://github.com/ansible-collections/community.general/pull/8224).
-- puppet - add option ``environment_lang`` to set the environment language encoding. Defaults to lang ``C``. It is recommended to set it to ``C.UTF-8`` or ``en_US.UTF-8`` depending on what is available on your system. (https://github.com/ansible-collections/community.general/issues/8000)
-- riak - support ``riak admin`` sub-command in newer Riak KV versions beside the legacy ``riak-admin`` main command (https://github.com/ansible-collections/community.general/pull/8211).
-- to_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183, https://github.com/ansible-collections/community.general/pull/8185).
-- xml - make module work with lxml 5.1.1, which removed some internals that the module was relying on (https://github.com/ansible-collections/community.general/pull/8169).
-
-New Modules
------------
-
-- keycloak_client_rolescope - Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications.
-
-v8.5.0
-======
-
-Release Summary
----------------
-
-Regular feature and bugfix release with security fixes.
-
-Minor Changes
--------------
-
-- bitwarden lookup plugin - allows to fetch all records of a given collection ID, by allowing to pass an empty value for ``search_value`` when ``collection_id`` is provided (https://github.com/ansible-collections/community.general/pull/8013).
-- icinga2 inventory plugin - adds new parameter ``group_by_hostgroups`` in order to make grouping by Icinga2 hostgroups optional (https://github.com/ansible-collections/community.general/pull/7998).
-- ini_file - support optional spaces between section names and their surrounding brackets (https://github.com/ansible-collections/community.general/pull/8075).
-- java_cert - enable ``owner``, ``group``, ``mode``, and other generic file arguments (https://github.com/ansible-collections/community.general/pull/8116).
-- ldap_attrs - module now supports diff mode, showing which attributes are changed within an operation (https://github.com/ansible-collections/community.general/pull/8073).
-- lxd_container - uses ``/1.0/instances`` API endpoint, if available. Falls back to ``/1.0/containers`` or ``/1.0/virtual-machines``. Fixes issue when using Incus or LXD 5.19 due to migrating to ``/1.0/instances`` endpoint (https://github.com/ansible-collections/community.general/pull/7980).
-- nmcli - allow setting ``MTU`` for ``bond-slave`` interface types (https://github.com/ansible-collections/community.general/pull/8118).
-- proxmox - adds ``startup`` parameters to configure startup order, startup delay and shutdown delay (https://github.com/ansible-collections/community.general/pull/8038).
-- revbitspss lookup plugin - removed a redundant unicode prefix. The prefix was not necessary for Python 3 and has been cleaned up to streamline the code (https://github.com/ansible-collections/community.general/pull/8087).
-
-Security Fixes
---------------
-
-- cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox, scaleway, stackpath_compute, virtualbox, and xen_orchestra inventory plugin - make sure all data received from the remote servers is marked as unsafe, so remote code execution by obtaining texts that can be evaluated as templates is not possible (https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/, https://github.com/ansible-collections/community.general/pull/8098).
+- ansible_galaxy_install - minor refactor in the module (https://github.com/ansible-collections/community.general/pull/8413).
Bugfixes
--------
-- aix_filesystem - fix issue with empty list items in crfs logic and option order (https://github.com/ansible-collections/community.general/pull/8052).
-- consul_token - fix token creation without ``accessor_id`` (https://github.com/ansible-collections/community.general/pull/8091).
-- homebrew - error returned from brew command was ignored and tried to parse empty JSON. Fix now checks for an error and raises it to give accurate error message to users (https://github.com/ansible-collections/community.general/issues/8047).
-- ipa_hbacrule - the module uses a string for ``ipaenabledflag`` for new FreeIPA versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
-- ipa_sudorule - the module uses a string for ``ipaenabledflag`` for new FreeIPA versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
-- iptables_state - fix idempotency issues when restoring incomplete iptables dumps (https://github.com/ansible-collections/community.general/issues/8029).
-- linode inventory plugin - add descriptive error message for linode inventory plugin (https://github.com/ansible-collections/community.general/pull/8133).
-- pacemaker_cluster - actually implement check mode, which the module claims to support. This means that until now the module also did changes in check mode (https://github.com/ansible-collections/community.general/pull/8081).
-- pam_limits - when the file does not exist, do not create it in check mode (https://github.com/ansible-collections/community.general/issues/8050, https://github.com/ansible-collections/community.general/pull/8057).
-- proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
-
-New Modules
------------
-
-- usb_facts - Allows listing information about USB devices
-
-v8.4.0
+- cpanm - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- django module utils - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- gconftool2_info - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- homebrew - do not fail when brew prints warnings (https://github.com/ansible-collections/community.general/pull/8406, https://github.com/ansible-collections/community.general/issues/7044).
+- hponcfg - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- kernel_blacklist - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- keycloak_client - fix TypeError when sanitizing the ``saml.signing.private.key`` attribute in the module's diff or state output. The ``sanitize_cr`` function expected a dict where in some cases a list might occur (https://github.com/ansible-collections/community.general/pull/8403).
+- locale_gen - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- mksysb - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- pipx_info - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- snap - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+- snap_alias - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410, https://github.com/ansible-collections/community.general/pull/8411).
+
+v9.0.0
======
Release Summary
---------------
-Regular bugfix and feature release.
+This is release 9.0.0 of ``community.general``, released on 2024-05-20.
Minor Changes
-------------
+- PythonRunner module utils - specialisation of ``CmdRunner`` to execute Python scripts (https://github.com/ansible-collections/community.general/pull/8289).
+- Use offset-aware ``datetime.datetime`` objects (with timezone UTC) instead of offset-naive UTC timestamps, which are deprecated in Python 3.12 (https://github.com/ansible-collections/community.general/pull/8222).
+- aix_lvol - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- apt_rpm - add new states ``latest`` and ``present_not_latest``. The value ``latest`` is equivalent to the current behavior of ``present``, which will upgrade a package if a newer version exists. ``present_not_latest`` does what most users would expect ``present`` to do: it does not upgrade if the package is already installed. The current behavior of ``present`` will be deprecated in a later version, and eventually changed to that of ``present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8247).
+- apt_rpm - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- bitwarden lookup plugin - add ``bw_session`` option, to pass session key instead of reading from env (https://github.com/ansible-collections/community.general/pull/7994).
-- gitlab_deploy_key, gitlab_group_members, gitlab_group_variable, gitlab_hook, gitlab_instance_variable, gitlab_project_badge, gitlab_project_variable, gitlab_user - improve API pagination and compatibility with different versions of ``python-gitlab`` (https://github.com/ansible-collections/community.general/pull/7790).
-- gitlab_hook - adds ``releases_events`` parameter for supporting Releases events triggers on GitLab hooks (https://github.com/ansible-collections/community.general/pull/7956).
-- icinga2 inventory plugin - add Jinja2 templating support to ``url``, ``user``, and ``password`` paramenters (https://github.com/ansible-collections/community.general/issues/7074, https://github.com/ansible-collections/community.general/pull/7996).
-- mssql_script - adds transactional (rollback/commit) support via optional boolean param ``transaction`` (https://github.com/ansible-collections/community.general/pull/7976).
-- proxmox_kvm - add parameter ``update_unsafe`` to avoid limitations when updating dangerous values (https://github.com/ansible-collections/community.general/pull/7843).
-- redfish_config - add command ``SetServiceIdentification`` to set service identification (https://github.com/ansible-collections/community.general/issues/7916).
-- sudoers - add support for the ``NOEXEC`` tag in sudoers rules (https://github.com/ansible-collections/community.general/pull/7983).
-- terraform - fix ``diff_mode`` in state ``absent`` and when terraform ``resource_changes`` does not exist (https://github.com/ansible-collections/community.general/pull/7963).
-
-Bugfixes
---------
-
-- cargo - fix idempotency issues when using a custom installation path for packages (using the ``--path`` parameter). The initial installation runs fine, but subsequent runs use the ``get_installed()`` function which did not check the given installation location, before running ``cargo install``. This resulted in a false ``changed`` state. Also the removal of packeges using ``state: absent`` failed, as the installation check did not use the given parameter (https://github.com/ansible-collections/community.general/pull/7970).
-- gitlab_issue - fix behavior to search GitLab issue, using ``search`` keyword instead of ``title`` (https://github.com/ansible-collections/community.general/issues/7846).
-- gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
-- keycloak_client - fixes issue when metadata is provided in desired state when task is in check mode (https://github.com/ansible-collections/community.general/issues/1226, https://github.com/ansible-collections/community.general/pull/7881).
-- modprobe - listing modules files or modprobe files could trigger a FileNotFoundError if ``/etc/modprobe.d`` or ``/etc/modules-load.d`` did not exist. Relevant functions now return empty lists if the directories do not exist to avoid crashing the module (https://github.com/ansible-collections/community.general/issues/7717).
-- onepassword lookup plugin - failed for fields that were in sections and had uppercase letters in the label/ID. Field lookups are now case insensitive in all cases (https://github.com/ansible-collections/community.general/pull/7919).
-- pkgin - pkgin (pkgsrc package manager used by SmartOS) raises erratic exceptions and spurious ``changed=true`` (https://github.com/ansible-collections/community.general/pull/7971).
-- redfish_info - allow for a GET operation invoked by ``GetUpdateStatus`` to allow for an empty response body for cases where a service returns 204 No Content (https://github.com/ansible-collections/community.general/issues/8003).
-- redfish_info - correct uncaught exception when attempting to retrieve ``Chassis`` information (https://github.com/ansible-collections/community.general/pull/7952).
-
-New Plugins
------------
-
-Callback
-~~~~~~~~
-
-- default_without_diff - The default ansible callback without diff output
-
-Filter
-~~~~~~
-
-- lists_difference - Difference of lists with a predictive order
-- lists_intersect - Intersection of lists with a predictive order
-- lists_symmetric_difference - Symmetric Difference of lists with a predictive order
-- lists_union - Union of lists with a predictive order
-
-New Modules
------------
-
-- gitlab_group_access_token - Manages GitLab group access tokens
-- gitlab_project_access_token - Manages GitLab project access tokens
-
-v8.3.0
-======
-
-Release Summary
----------------
-
-Regular bugfix and feature release.
-
-Minor Changes
--------------
-
+- bitwarden lookup plugin - add support to filter by organization ID (https://github.com/ansible-collections/community.general/pull/8188).
+- bitwarden lookup plugin - allows to fetch all records of a given collection ID, by allowing to pass an empty value for ``search_value`` when ``collection_id`` is provided (https://github.com/ansible-collections/community.general/pull/8013).
+- bitwarden lookup plugin - when looking for items using an item ID, the item is now accessed directly with ``bw get item`` instead of searching through all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
+- btrfs_subvolume - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- cmd_runner module_utils - add validation for minimum and maximum length in the value passed to ``cmd_runner_fmt.as_list()`` (https://github.com/ansible-collections/community.general/pull/8288).
- consul_auth_method, consul_binding_rule, consul_policy, consul_role, consul_session, consul_token - added action group ``community.general.consul`` (https://github.com/ansible-collections/community.general/pull/7897).
- consul_policy - added support for diff and check mode (https://github.com/ansible-collections/community.general/pull/7878).
- consul_policy, consul_role, consul_session - removed dependency on ``requests`` and factored out common parts (https://github.com/ansible-collections/community.general/pull/7826, https://github.com/ansible-collections/community.general/pull/7878).
@@ -179,532 +64,289 @@ Minor Changes
- consul_role - ``service_identities`` now expects a ``service_name`` option to match the Consul API, the old ``name`` is still supported as alias (https://github.com/ansible-collections/community.general/pull/7878).
- consul_role - added support for diff mode (https://github.com/ansible-collections/community.general/pull/7878).
- consul_role - added support for templated policies (https://github.com/ansible-collections/community.general/pull/7878).
-- redfish_info - add command ``GetServiceIdentification`` to get service identification (https://github.com/ansible-collections/community.general/issues/7882).
-- terraform - add support for ``diff_mode`` for terraform resource_changes (https://github.com/ansible-collections/community.general/pull/7896).
-
-Deprecated Features
--------------------
-
-- consul_acl - the module has been deprecated and will be removed in community.general 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901).
-
-Bugfixes
---------
-
-- homebrew - detect already installed formulae and casks using JSON output from ``brew info`` (https://github.com/ansible-collections/community.general/issues/864).
-- incus connection plugin - treats ``inventory_hostname`` as a variable instead of a literal in remote connections (https://github.com/ansible-collections/community.general/issues/7874).
-- ipa_otptoken - the module expect ``ipatokendisabled`` as string but the ``ipatokendisabled`` value is returned as a boolean (https://github.com/ansible-collections/community.general/pull/7795).
-- ldap - previously the order number (if present) was expected to follow an equals sign in the DN. This makes it so the order number string is identified correctly anywhere within the DN (https://github.com/ansible-collections/community.general/issues/7646).
-- mssql_script - make the module work with Python 2 (https://github.com/ansible-collections/community.general/issues/7818, https://github.com/ansible-collections/community.general/pull/7821).
-- nmcli - fix ``connection.slave-type`` wired to ``bond`` and not with parameter ``slave_type`` in case of connection type ``wifi`` (https://github.com/ansible-collections/community.general/issues/7389).
-- proxmox - fix updating a container config if the setting does not already exist (https://github.com/ansible-collections/community.general/pull/7872).
-
-New Modules
------------
-
-- consul_acl_bootstrap - Bootstrap ACLs in Consul
-- consul_auth_method - Manipulate Consul auth methods
-- consul_binding_rule - Manipulate Consul binding rules
-- consul_token - Manipulate Consul tokens
-- gitlab_label - Creates/updates/deletes GitLab Labels belonging to project or group.
-- gitlab_milestone - Creates/updates/deletes GitLab Milestones belonging to project or group
-
-v8.2.0
-======
-
-Release Summary
----------------
-
-Regular bugfix and feature release.
-
-Minor Changes
--------------
-
-- ipa_dnsrecord - adds ability to manage NS record types (https://github.com/ansible-collections/community.general/pull/7737).
-- ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
-- ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``, ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
-- keycloak_realm_key - the ``config.algorithm`` option now supports 8 additional key algorithms (https://github.com/ansible-collections/community.general/pull/7698).
-- keycloak_realm_key - the ``config.certificate`` option value is no longer defined with ``no_log=True`` (https://github.com/ansible-collections/community.general/pull/7698).
-- keycloak_realm_key - the ``provider_id`` option now supports RSA encryption key usage (value ``rsa-enc``) (https://github.com/ansible-collections/community.general/pull/7698).
-- keycloak_user_federation - allow custom user storage providers to be set through ``provider_id`` (https://github.com/ansible-collections/community.general/pull/7789).
-- mail - add ``Message-ID`` header; which is required by some mail servers (https://github.com/ansible-collections/community.general/pull/7740).
-- mail module, mail callback plugin - allow to configure the domain name of the Message-ID header with a new ``message_id_domain`` option (https://github.com/ansible-collections/community.general/pull/7765).
-- ssh_config - new feature to set ``AddKeysToAgent`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7703).
-- ssh_config - new feature to set ``IdentitiesOnly`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7704).
-- xcc_redfish_command - added support for raw POSTs (``command=PostResource`` in ``category=Raw``) without a specific action info (https://github.com/ansible-collections/community.general/pull/7746).
-
-Bugfixes
---------
-
-- keycloak_identity_provider - ``mappers`` processing was not idempotent if the mappers configuration list had not been sorted by name (in ascending order). Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state (https://github.com/ansible-collections/community.general/pull/7418).
-- keycloak_identity_provider - it was not possible to reconfigure (add, remove) ``mappers`` once they were created initially. Removal was ignored, adding new ones resulted in dropping the pre-existing unmodified mappers. Fix resolves the issue by supplying correct input to the internal update call (https://github.com/ansible-collections/community.general/pull/7418).
-- keycloak_user - when ``force`` is set, but user does not exist, do not try to delete it (https://github.com/ansible-collections/community.general/pull/7696).
-- proxmox_kvm - running ``state=template`` will first check whether VM is already a template (https://github.com/ansible-collections/community.general/pull/7792).
-- statusio_maintenance - fix error caused by incorrectly formed API data payload. Was raising "Failed to create maintenance HTTP Error 400 Bad Request" caused by bad data type for date/time and deprecated dict keys (https://github.com/ansible-collections/community.general/pull/7754).
-
-New Plugins
------------
-
-Connection
-~~~~~~~~~~
-
-- incus - Run tasks in Incus instances via the Incus CLI.
-
-Filter
-~~~~~~
-
-- from_ini - Converts INI text input into a dictionary
-- to_ini - Converts a dictionary to the INI file format
-
-Lookup
-~~~~~~
-
-- github_app_access_token - Obtain short-lived Github App Access tokens
-
-New Modules
------------
-
-- dnf_config_manager - Enable or disable dnf repositories using config-manager
-- keycloak_component_info - Retrive component info in Keycloak
-- keycloak_realm_rolemapping - Allows administration of Keycloak realm role mappings into groups with the Keycloak API
-- proxmox_node_info - Retrieve information about one or more Proxmox VE nodes
-- proxmox_storage_contents_info - List content from a Proxmox VE storage
-
-v8.1.0
-======
-
-Release Summary
----------------
-
-Regular bugfix and feature release.
-
-Minor Changes
--------------
-
-- bitwarden lookup plugin - when looking for items using an item ID, the item is now accessed directly with ``bw get item`` instead of searching through all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
- elastic callback plugin - close elastic client to not leak resources (https://github.com/ansible-collections/community.general/pull/7517).
+- filesystem - add bcachefs support (https://github.com/ansible-collections/community.general/pull/8126).
+- gandi_livedns - adds support for personal access tokens (https://github.com/ansible-collections/community.general/issues/7639, https://github.com/ansible-collections/community.general/pull/8337).
+- gconftool2 - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
- git_config - allow multiple git configs for the same name with the new ``add_mode`` option (https://github.com/ansible-collections/community.general/pull/7260).
- git_config - the ``after`` and ``before`` fields in the ``diff`` of the return value can be a list instead of a string in case more configs with the same key are affected (https://github.com/ansible-collections/community.general/pull/7260).
- git_config - when a value is unset, all configs with the same key are unset (https://github.com/ansible-collections/community.general/pull/7260).
- gitlab modules - add ``ca_path`` option (https://github.com/ansible-collections/community.general/pull/7472).
- gitlab modules - remove duplicate ``gitlab`` package check (https://github.com/ansible-collections/community.general/pull/7486).
+- gitlab_deploy_key, gitlab_group_members, gitlab_group_variable, gitlab_hook, gitlab_instance_variable, gitlab_project_badge, gitlab_project_variable, gitlab_user - improve API pagination and compatibility with different versions of ``python-gitlab`` (https://github.com/ansible-collections/community.general/pull/7790).
+- gitlab_hook - adds ``releases_events`` parameter for supporting Releases events triggers on GitLab hooks (https://github.com/ansible-collections/community.general/pull/7956).
- gitlab_runner - add support for new runner creation workflow (https://github.com/ansible-collections/community.general/pull/7199).
+- homebrew - adds ``force_formula`` parameter to disambiguate a formula from a cask of the same name (https://github.com/ansible-collections/community.general/issues/8274).
+- homebrew, homebrew_cask - refactor common argument validation logic into a dedicated ``homebrew`` module utils (https://github.com/ansible-collections/community.general/issues/8323, https://github.com/ansible-collections/community.general/pull/8324).
+- icinga2 inventory plugin - add Jinja2 templating support to ``url``, ``user``, and ``password`` paramenters (https://github.com/ansible-collections/community.general/issues/7074, https://github.com/ansible-collections/community.general/pull/7996).
+- icinga2 inventory plugin - adds new parameter ``group_by_hostgroups`` in order to make grouping by Icinga2 hostgroups optional (https://github.com/ansible-collections/community.general/pull/7998).
+- ini_file - add an optional parameter ``section_has_values``. If the target ini file contains more than one ``section``, use ``section_has_values`` to specify which one should be updated (https://github.com/ansible-collections/community.general/pull/7505).
+- ini_file - support optional spaces between section names and their surrounding brackets (https://github.com/ansible-collections/community.general/pull/8075).
+- installp - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- ipa_config - adds ``passkey`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7588).
+- ipa_dnsrecord - adds ability to manage NS record types (https://github.com/ansible-collections/community.general/pull/7737).
+- ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
+- ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``, ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
- ipa_sudorule - adds options to include denied commands or command groups (https://github.com/ansible-collections/community.general/pull/7415).
- ipa_user - adds ``idp`` and ``passkey`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7589).
- irc - add ``validate_certs`` option, and rename ``use_ssl`` to ``use_tls``, while keeping ``use_ssl`` as an alias. The default value for ``validate_certs`` is ``false`` for backwards compatibility. We recommend to every user of this module to explicitly set ``use_tls=true`` and `validate_certs=true`` whenever possible, especially when communicating to IRC servers over the internet (https://github.com/ansible-collections/community.general/pull/7550).
+- java_cert - add ``cert_content`` argument (https://github.com/ansible-collections/community.general/pull/8153).
+- java_cert - enable ``owner``, ``group``, ``mode``, and other generic file arguments (https://github.com/ansible-collections/community.general/pull/8116).
+- kernel_blacklist - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
- keycloak module utils - expose error message from Keycloak server for HTTP errors in some specific situations (https://github.com/ansible-collections/community.general/pull/7645).
+- keycloak_client, keycloak_clientscope, keycloak_clienttemplate - added ``docker-v2`` protocol support, enhancing alignment with Keycloak's protocol options (https://github.com/ansible-collections/community.general/issues/8215, https://github.com/ansible-collections/community.general/pull/8216).
+- keycloak_realm_key - the ``config.algorithm`` option now supports 8 additional key algorithms (https://github.com/ansible-collections/community.general/pull/7698).
+- keycloak_realm_key - the ``config.certificate`` option value is no longer defined with ``no_log=True`` (https://github.com/ansible-collections/community.general/pull/7698).
+- keycloak_realm_key - the ``provider_id`` option now supports RSA encryption key usage (value ``rsa-enc``) (https://github.com/ansible-collections/community.general/pull/7698).
- keycloak_user_federation - add option for ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/7538).
+- keycloak_user_federation - allow custom user storage providers to be set through ``provider_id`` (https://github.com/ansible-collections/community.general/pull/7789).
+- ldap_attrs - module now supports diff mode, showing which attributes are changed within an operation (https://github.com/ansible-collections/community.general/pull/8073).
+- lvg - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- lvol - change ``pvs`` argument type to list of strings (https://github.com/ansible-collections/community.general/pull/7676, https://github.com/ansible-collections/community.general/issues/7504).
+- lvol - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- lxd connection plugin - tighten the detection logic for lxd ``Instance not found`` errors, to avoid false detection on unrelated errors such as ``/usr/bin/python3: not found`` (https://github.com/ansible-collections/community.general/pull/7521).
+- lxd_container - uses ``/1.0/instances`` API endpoint, if available. Falls back to ``/1.0/containers`` or ``/1.0/virtual-machines``. Fixes issue when using Incus or LXD 5.19 due to migrating to ``/1.0/instances`` endpoint (https://github.com/ansible-collections/community.general/pull/7980).
+- macports - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- mail - add ``Message-ID`` header; which is required by some mail servers (https://github.com/ansible-collections/community.general/pull/7740).
+- mail module, mail callback plugin - allow to configure the domain name of the Message-ID header with a new ``message_id_domain`` option (https://github.com/ansible-collections/community.general/pull/7765).
+- mssql_script - adds transactional (rollback/commit) support via optional boolean param ``transaction`` (https://github.com/ansible-collections/community.general/pull/7976).
- netcup_dns - adds support for record types ``OPENPGPKEY``, ``SMIMEA``, and ``SSHFP`` (https://github.com/ansible-collections/community.general/pull/7489).
- nmcli - add support for new connection type ``loopback`` (https://github.com/ansible-collections/community.general/issues/6572).
+- nmcli - adds OpenvSwitch support with new ``type`` values ``ovs-port``, ``ovs-interface``, and ``ovs-bridge``, and new ``slave_type`` value ``ovs-port`` (https://github.com/ansible-collections/community.general/pull/8154).
- nmcli - allow for ``infiniband`` slaves of ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7569).
- nmcli - allow for the setting of ``MTU`` for ``infiniband`` and ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7499).
+- nmcli - allow setting ``MTU`` for ``bond-slave`` interface types (https://github.com/ansible-collections/community.general/pull/8118).
- onepassword lookup plugin - support 1Password Connect with the opv2 client by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116).
- onepassword_raw lookup plugin - support 1Password Connect with the opv2 client by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116)
+- opentelemetry - add support for HTTP trace_exporter and configures the behavior via ``OTEL_EXPORTER_OTLP_TRACES_PROTOCOL`` (https://github.com/ansible-collections/community.general/issues/7888, https://github.com/ansible-collections/community.general/pull/8321).
+- opentelemetry - add support for exporting spans in a file via ``ANSIBLE_OPENTELEMETRY_STORE_SPANS_IN_FILE`` (https://github.com/ansible-collections/community.general/issues/7888, https://github.com/ansible-collections/community.general/pull/8363).
+- opkg - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+- osx_defaults - add option ``check_types`` to enable changing the type of existing defaults on the fly (https://github.com/ansible-collections/community.general/pull/8173).
+- parted - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- passwordstore - adds ``timestamp`` and ``preserve`` parameters to modify the stored password format (https://github.com/ansible-collections/community.general/pull/7426).
+- passwordstore lookup - add ``missing_subkey`` parameter defining the behavior of the lookup when a passwordstore subkey is missing (https://github.com/ansible-collections/community.general/pull/8166).
+- pipx - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+- pkg5 - add support for non-silent execution (https://github.com/ansible-collections/community.general/issues/8379, https://github.com/ansible-collections/community.general/pull/8382).
+- pkgin - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- portage - adds the possibility to explicitely tell portage to write packages to world file (https://github.com/ansible-collections/community.general/issues/6226, https://github.com/ansible-collections/community.general/pull/8236).
+- portinstall - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- proxmox - adds ``startup`` parameters to configure startup order, startup delay and shutdown delay (https://github.com/ansible-collections/community.general/pull/8038).
- proxmox - adds ``template`` value to the ``state`` parameter, allowing conversion of container to a template (https://github.com/ansible-collections/community.general/pull/7143).
- proxmox - adds ``update`` parameter, allowing update of an already existing containers configuration (https://github.com/ansible-collections/community.general/pull/7540).
- proxmox inventory plugin - adds an option to exclude nodes from the dynamic inventory generation. The new setting is optional, not using this option will behave as usual (https://github.com/ansible-collections/community.general/issues/6714, https://github.com/ansible-collections/community.general/pull/7461).
+- proxmox* modules - there is now a ``community.general.proxmox`` module defaults group that can be used to set default options for all Proxmox modules (https://github.com/ansible-collections/community.general/pull/8334).
- proxmox_disk - add ability to manipulate CD-ROM drive (https://github.com/ansible-collections/community.general/pull/7495).
+- proxmox_kvm - add parameter ``update_unsafe`` to avoid limitations when updating dangerous values (https://github.com/ansible-collections/community.general/pull/7843).
- proxmox_kvm - adds ``template`` value to the ``state`` parameter, allowing conversion of a VM to a template (https://github.com/ansible-collections/community.general/pull/7143).
+- proxmox_kvm - adds``usb`` parameter for setting USB devices on proxmox KVM VMs (https://github.com/ansible-collections/community.general/pull/8199).
- proxmox_kvm - support the ``hookscript`` parameter (https://github.com/ansible-collections/community.general/issues/7600).
- proxmox_ostype - it is now possible to specify the ``ostype`` when creating an LXC container (https://github.com/ansible-collections/community.general/pull/7462).
- proxmox_vm_info - add ability to retrieve configuration info (https://github.com/ansible-collections/community.general/pull/7485).
+- puppet - new feature to set ``--waitforlock`` option (https://github.com/ansible-collections/community.general/pull/8282).
+- redfish_command - add command ``ResetToDefaults`` to reset manager to default state (https://github.com/ansible-collections/community.general/issues/8163).
+- redfish_config - add command ``SetServiceIdentification`` to set service identification (https://github.com/ansible-collections/community.general/issues/7916).
+- redfish_info - add boolean return value ``MultipartHttpPush`` to ``GetFirmwareUpdateCapabilities`` (https://github.com/ansible-collections/community.general/issues/8194, https://github.com/ansible-collections/community.general/pull/8195).
+- redfish_info - add command ``GetServiceIdentification`` to get service identification (https://github.com/ansible-collections/community.general/issues/7882).
- redfish_info - adding the ``BootProgress`` property when getting ``Systems`` info (https://github.com/ansible-collections/community.general/pull/7626).
+- revbitspss lookup plugin - removed a redundant unicode prefix. The prefix was not necessary for Python 3 and has been cleaned up to streamline the code (https://github.com/ansible-collections/community.general/pull/8087).
+- rundeck module utils - allow to pass ``Content-Type`` to API requests (https://github.com/ansible-collections/community.general/pull/7684).
+- slackpkg - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- ssh_config - adds ``controlmaster``, ``controlpath`` and ``controlpersist`` parameters (https://github.com/ansible-collections/community.general/pull/7456).
+- ssh_config - allow ``accept-new`` as valid value for ``strict_host_key_checking`` (https://github.com/ansible-collections/community.general/pull/8257).
+- ssh_config - new feature to set ``AddKeysToAgent`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7703).
+- ssh_config - new feature to set ``IdentitiesOnly`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7704).
+- sudoers - add support for the ``NOEXEC`` tag in sudoers rules (https://github.com/ansible-collections/community.general/pull/7983).
+- svr4pkg - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- swdepot - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+- terraform - add support for ``diff_mode`` for terraform resource_changes (https://github.com/ansible-collections/community.general/pull/7896).
+- terraform - fix ``diff_mode`` in state ``absent`` and when terraform ``resource_changes`` does not exist (https://github.com/ansible-collections/community.general/pull/7963).
+- xcc_redfish_command - added support for raw POSTs (``command=PostResource`` in ``category=Raw``) without a specific action info (https://github.com/ansible-collections/community.general/pull/7746).
+- xfconf - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+- xfconf_info - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- cpanm - the default of the ``mode`` option changed from ``compatibility`` to ``new`` (https://github.com/ansible-collections/community.general/pull/8198).
+- django_manage - the module now requires Django >= 4.1 (https://github.com/ansible-collections/community.general/pull/8198).
+- django_manage - the module will now fail if ``virtualenv`` is specified but no virtual environment exists at that location (https://github.com/ansible-collections/community.general/pull/8198).
+- redfish_command, redfish_config, redfish_info - change the default for ``timeout`` from 10 to 60 (https://github.com/ansible-collections/community.general/pull/8198).
+
+Deprecated Features
+-------------------
+
+- MH DependencyCtxMgr module_utils - deprecate ``module_utils.mh.mixin.deps.DependencyCtxMgr`` in favour of ``module_utils.deps`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.AnsibleModule`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.DependencyCtxMgr`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.StateMixin`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarDict,`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarMeta`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarsMixin`` (https://github.com/ansible-collections/community.general/pull/8280).
+- ModuleHelper module_utils - deprecate use of ``VarsMixin`` in favor of using the ``VardDict`` module_utils (https://github.com/ansible-collections/community.general/pull/8226).
+- ModuleHelper vars module_utils - bump deprecation of ``VarMeta``, ``VarDict`` and ``VarsMixin`` to version 11.0.0 (https://github.com/ansible-collections/community.general/pull/8226).
+- apt_rpm - the behavior of ``state=present`` and ``state=installed`` is deprecated and will change in community.general 11.0.0. Right now the module will upgrade a package to the latest version if one of these two states is used. You should explicitly use ``state=latest`` if you want this behavior, and switch to ``state=present_not_latest`` if you do not want to upgrade the package if it is already installed. In community.general 11.0.0 the behavior of ``state=present`` and ``state=installed`` will change to that of ``state=present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8285).
+- consul_acl - the module has been deprecated and will be removed in community.general 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901).
+- django_manage - the ``ack_venv_creation_deprecation`` option has no more effect and will be removed from community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8198).
+- gitlab modules - the basic auth method on GitLab API have been deprecated and will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/8383).
+- hipchat callback plugin - the hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. The callback plugin is therefore deprecated and will be removed from community.general 10.0.0 if nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/issues/8184, https://github.com/ansible-collections/community.general/pull/8189).
+- irc - the defaults ``false`` for ``use_tls`` and ``validate_certs`` have been deprecated and will change to ``true`` in community.general 10.0.0 to improve security. You can already improve security now by explicitly setting them to ``true``. Specifying values now disables the deprecation warning (https://github.com/ansible-collections/community.general/pull/7578).
+
+Removed Features (previously deprecated)
+----------------------------------------
+
+- The deprecated redirects for internal module names have been removed. These internal redirects were extra-long FQCNs like ``community.general.packaging.os.apt_rpm`` that redirect to the short FQCN ``community.general.apt_rpm``. They were originally needed to implement flatmapping; as various tooling started to recommend users to use the long names flatmapping was removed from the collection and redirects were added for users who already followed these incorrect recommendations (https://github.com/ansible-collections/community.general/pull/7835).
+- ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211`` options have been removed. They no longer had any effect (https://github.com/ansible-collections/community.general/pull/8198).
+- cloudflare_dns - remove support for SPF records. These are no longer supported by CloudFlare (https://github.com/ansible-collections/community.general/pull/7782).
+- django_manage - support for the ``command`` values ``cleanup``, ``syncdb``, and ``validate`` were removed. Use ``clearsessions``, ``migrate``, and ``check`` instead, respectively (https://github.com/ansible-collections/community.general/pull/8198).
+- flowdock - this module relied on HTTPS APIs that do not exist anymore and was thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+- mh.mixins.deps module utils - the ``DependencyMixin`` has been removed. Use the ``deps`` module utils instead (https://github.com/ansible-collections/community.general/pull/8198).
+- proxmox - the ``proxmox_default_behavior`` option has been removed (https://github.com/ansible-collections/community.general/pull/8198).
+- rax* modules, rax module utils, rax docs fragment - the Rackspace modules relied on the deprecated package ``pyrax`` and were thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+- redhat module utils - the classes ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` have been removed (https://github.com/ansible-collections/community.general/pull/8198).
+- redhat_subscription - the alias ``autosubscribe`` of the ``auto_attach`` option was removed (https://github.com/ansible-collections/community.general/pull/8198).
+- stackdriver - this module relied on HTTPS APIs that do not exist anymore and was thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+- webfaction_* modules - these modules relied on HTTPS APIs that do not exist anymore and were thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+
+Security Fixes
+--------------
+
+- cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox, scaleway, stackpath_compute, virtualbox, and xen_orchestra inventory plugin - make sure all data received from the remote servers is marked as unsafe, so remote code execution by obtaining texts that can be evaluated as templates is not possible (https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/, https://github.com/ansible-collections/community.general/pull/8098).
+- keycloak_identity_provider - the client secret was not correctly sanitized by the module. The return values ``proposed``, ``existing``, and ``end_state``, as well as the diff, did contain the client secret unmasked (https://github.com/ansible-collections/community.general/pull/8355).
Bugfixes
--------
+- aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd`` (https://github.com/ansible-collections/community.general/issues/8151).
+- aix_filesystem - fix issue with empty list items in crfs logic and option order (https://github.com/ansible-collections/community.general/pull/8052).
- apt-rpm - the module did not upgrade packages if a newer version exists. Now the package will be reinstalled if the candidate is newer than the installed version (https://github.com/ansible-collections/community.general/issues/7414).
+- apt_rpm - when checking whether packages were installed after running ``apt-get -y install <packages>``, only the last package name was checked (https://github.com/ansible-collections/community.general/pull/8263).
+- bitwarden_secrets_manager lookup plugin - implements retry with exponential backoff to avoid lookup errors when Bitwardn's API rate limiting is encountered (https://github.com/ansible-collections/community.general/issues/8230, https://github.com/ansible-collections/community.general/pull/8238).
+- cargo - fix idempotency issues when using a custom installation path for packages (using the ``--path`` parameter). The initial installation runs fine, but subsequent runs use the ``get_installed()`` function which did not check the given installation location, before running ``cargo install``. This resulted in a false ``changed`` state. Also the removal of packeges using ``state: absent`` failed, as the installation check did not use the given parameter (https://github.com/ansible-collections/community.general/pull/7970).
- cloudflare_dns - fix Cloudflare lookup of SHFP records (https://github.com/ansible-collections/community.general/issues/7652).
+- consul_token - fix token creation without ``accessor_id`` (https://github.com/ansible-collections/community.general/pull/8091).
+- from_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183, https://github.com/ansible-collections/community.general/pull/8185).
+- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
+- gitlab_issue - fix behavior to search GitLab issue, using ``search`` keyword instead of ``title`` (https://github.com/ansible-collections/community.general/issues/7846).
+- gitlab_issue, gitlab_label, gitlab_milestone - avoid crash during version comparison when the python-gitlab Python module is not installed (https://github.com/ansible-collections/community.general/pull/8158).
+- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
+- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches`` module (https://github.com/ansible-collections/community.general/issues/7467).
+- gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
+- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
+- haproxy - fix an issue where HAProxy could get stuck in DRAIN mode when the backend was unreachable (https://github.com/ansible-collections/community.general/issues/8092).
+- homebrew - detect already installed formulae and casks using JSON output from ``brew info`` (https://github.com/ansible-collections/community.general/issues/864).
+- homebrew - error returned from brew command was ignored and tried to parse empty JSON. Fix now checks for an error and raises it to give accurate error message to users (https://github.com/ansible-collections/community.general/issues/8047).
+- incus connection plugin - treats ``inventory_hostname`` as a variable instead of a literal in remote connections (https://github.com/ansible-collections/community.general/issues/7874).
- interface_files - also consider ``address_family`` when changing ``option=method`` (https://github.com/ansible-collections/community.general/issues/7610, https://github.com/ansible-collections/community.general/pull/7612).
+- inventory plugins - add unsafe wrapper to avoid marking strings that do not contain ``{`` or ``}`` as unsafe, to work around a bug in AWX ((https://github.com/ansible-collections/community.general/issues/8212, https://github.com/ansible-collections/community.general/pull/8225).
+- ipa - fix get version regex in IPA module_utils (https://github.com/ansible-collections/community.general/pull/8175).
+- ipa_hbacrule - the module uses a string for ``ipaenabledflag`` for new FreeIPA versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
+- ipa_otptoken - the module expect ``ipatokendisabled`` as string but the ``ipatokendisabled`` value is returned as a boolean (https://github.com/ansible-collections/community.general/pull/7795).
+- ipa_sudorule - the module uses a string for ``ipaenabledflag`` for new FreeIPA versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
+- iptables_state - fix idempotency issues when restoring incomplete iptables dumps (https://github.com/ansible-collections/community.general/issues/8029).
- irc - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
- keycloak_* - fix Keycloak API client to quote ``/`` properly (https://github.com/ansible-collections/community.general/pull/7641).
- keycloak_authz_permission - resource payload variable for scope-based permission was constructed as a string, when it needs to be a list, even for a single item (https://github.com/ansible-collections/community.general/issues/7151).
+- keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes`` to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
+- keycloak_client - fixes issue when metadata is provided in desired state when task is in check mode (https://github.com/ansible-collections/community.general/issues/1226, https://github.com/ansible-collections/community.general/pull/7881).
+- keycloak_identity_provider - ``mappers`` processing was not idempotent if the mappers configuration list had not been sorted by name (in ascending order). Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state (https://github.com/ansible-collections/community.general/pull/7418).
+- keycloak_identity_provider - it was not possible to reconfigure (add, remove) ``mappers`` once they were created initially. Removal was ignored, adding new ones resulted in dropping the pre-existing unmodified mappers. Fix resolves the issue by supplying correct input to the internal update call (https://github.com/ansible-collections/community.general/pull/7418).
+- keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales`` (https://github.com/ansible-collections/community.general/pull/8224).
+- keycloak_user - when ``force`` is set, but user does not exist, do not try to delete it (https://github.com/ansible-collections/community.general/pull/7696).
+- keycloak_user_federation - fix diff of empty ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/8320).
+- ldap - previously the order number (if present) was expected to follow an equals sign in the DN. This makes it so the order number string is identified correctly anywhere within the DN (https://github.com/ansible-collections/community.general/issues/7646).
+- linode inventory plugin - add descriptive error message for linode inventory plugin (https://github.com/ansible-collections/community.general/pull/8133).
- log_entries callback plugin - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
- lvol - test for output messages in both ``stdout`` and ``stderr`` (https://github.com/ansible-collections/community.general/pull/7601, https://github.com/ansible-collections/community.general/issues/7182).
+- merge_variables lookup plugin - fixing cross host merge: providing access to foreign hosts variables to the perspective of the host that is performing the merge (https://github.com/ansible-collections/community.general/pull/8303).
+- modprobe - listing modules files or modprobe files could trigger a FileNotFoundError if ``/etc/modprobe.d`` or ``/etc/modules-load.d`` did not exist. Relevant functions now return empty lists if the directories do not exist to avoid crashing the module (https://github.com/ansible-collections/community.general/issues/7717).
+- mssql_script - make the module work with Python 2 (https://github.com/ansible-collections/community.general/issues/7818, https://github.com/ansible-collections/community.general/pull/7821).
+- nmcli - fix ``connection.slave-type`` wired to ``bond`` and not with parameter ``slave_type`` in case of connection type ``wifi`` (https://github.com/ansible-collections/community.general/issues/7389).
+- ocapi_utils, oci_utils, redfish_utils module utils - replace ``type()`` calls with ``isinstance()`` calls (https://github.com/ansible-collections/community.general/pull/7501).
+- onepassword lookup plugin - failed for fields that were in sections and had uppercase letters in the label/ID. Field lookups are now case insensitive in all cases (https://github.com/ansible-collections/community.general/pull/7919).
- onepassword lookup plugin - field and section titles are now case insensitive when using op CLI version two or later. This matches the behavior of version one (https://github.com/ansible-collections/community.general/pull/7564).
+- opentelemetry callback plugin - close spans always (https://github.com/ansible-collections/community.general/pull/8367).
+- opentelemetry callback plugin - honour the ``disable_logs`` option to avoid storing task results since they are not used regardless (https://github.com/ansible-collections/community.general/pull/8373).
+- pacemaker_cluster - actually implement check mode, which the module claims to support. This means that until now the module also did changes in check mode (https://github.com/ansible-collections/community.general/pull/8081).
+- pam_limits - when the file does not exist, do not create it in check mode (https://github.com/ansible-collections/community.general/issues/8050, https://github.com/ansible-collections/community.general/pull/8057).
+- pipx module utils - change the CLI argument formatter for the ``pip_args`` parameter (https://github.com/ansible-collections/community.general/issues/7497, https://github.com/ansible-collections/community.general/pull/7506).
+- pkgin - pkgin (pkgsrc package manager used by SmartOS) raises erratic exceptions and spurious ``changed=true`` (https://github.com/ansible-collections/community.general/pull/7971).
+- proxmox - fix updating a container config if the setting does not already exist (https://github.com/ansible-collections/community.general/pull/7872).
+- proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
+- proxmox_kvm - running ``state=template`` will first check whether VM is already a template (https://github.com/ansible-collections/community.general/pull/7792).
+- proxmox_pool_member - absent state for type VM did not delete VMs from the pools (https://github.com/ansible-collections/community.general/pull/7464).
+- puppet - add option ``environment_lang`` to set the environment language encoding. Defaults to lang ``C``. It is recommended to set it to ``C.UTF-8`` or ``en_US.UTF-8`` depending on what is available on your system. (https://github.com/ansible-collections/community.general/issues/8000)
+- redfish_command - fix usage of message parsing in ``SimpleUpdate`` and ``MultipartHTTPPushUpdate`` commands to treat the lack of a ``MessageId`` as no message (https://github.com/ansible-collections/community.general/issues/7465, https://github.com/ansible-collections/community.general/pull/7471).
+- redfish_info - allow for a GET operation invoked by ``GetUpdateStatus`` to allow for an empty response body for cases where a service returns 204 No Content (https://github.com/ansible-collections/community.general/issues/8003).
+- redfish_info - correct uncaught exception when attempting to retrieve ``Chassis`` information (https://github.com/ansible-collections/community.general/pull/7952).
- redhat_subscription - use the D-Bus registration on RHEL 7 only on 7.4 and
greater; older versions of RHEL 7 do not have it
(https://github.com/ansible-collections/community.general/issues/7622,
https://github.com/ansible-collections/community.general/pull/7624).
+- riak - support ``riak admin`` sub-command in newer Riak KV versions beside the legacy ``riak-admin`` main command (https://github.com/ansible-collections/community.general/pull/8211).
+- statusio_maintenance - fix error caused by incorrectly formed API data payload. Was raising "Failed to create maintenance HTTP Error 400 Bad Request" caused by bad data type for date/time and deprecated dict keys (https://github.com/ansible-collections/community.general/pull/7754).
- terraform - fix multiline string handling in complex variables (https://github.com/ansible-collections/community.general/pull/7535).
+- to_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183, https://github.com/ansible-collections/community.general/pull/8185).
+- xml - make module work with lxml 5.1.1, which removed some internals that the module was relying on (https://github.com/ansible-collections/community.general/pull/8169).
New Plugins
-----------
-Lookup
+Become
~~~~~~
-- onepassword_doc - Fetch documents stored in 1Password
-
-Test
-~~~~
-
-- fqdn_valid - Validates fully-qualified domain names against RFC 1123
-
-New Modules
------------
-
-- git_config_info - Read git configuration
-- gitlab_issue - Create, update, or delete GitLab issues
-- nomad_token - Manage Nomad ACL tokens
-
-v8.0.2
-======
-
-Release Summary
----------------
-
-Bugfix release for inclusion in Ansible 9.0.0rc1.
-
-Bugfixes
---------
-
-- ocapi_utils, oci_utils, redfish_utils module utils - replace ``type()`` calls with ``isinstance()`` calls (https://github.com/ansible-collections/community.general/pull/7501).
-- pipx module utils - change the CLI argument formatter for the ``pip_args`` parameter (https://github.com/ansible-collections/community.general/issues/7497, https://github.com/ansible-collections/community.general/pull/7506).
+- community.general.run0 - Systemd's run0.
-v8.0.1
-======
-
-Release Summary
----------------
-
-Bugfix release for inclusion in Ansible 9.0.0b1.
-
-Bugfixes
---------
-
-- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
-- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
-- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches`` module (https://github.com/ansible-collections/community.general/issues/7467).
-- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
-- proxmox_pool_member - absent state for type VM did not delete VMs from the pools (https://github.com/ansible-collections/community.general/pull/7464).
-- redfish_command - fix usage of message parsing in ``SimpleUpdate`` and ``MultipartHTTPPushUpdate`` commands to treat the lack of a ``MessageId`` as no message (https://github.com/ansible-collections/community.general/issues/7465, https://github.com/ansible-collections/community.general/pull/7471).
-
-v8.0.0
-======
-
-Release Summary
----------------
-
-This is release 8.0.0 of ``community.general``, released on 2023-11-01.
-
-Minor Changes
--------------
-
-- The collection will start using semantic markup (https://github.com/ansible-collections/community.general/pull/6539).
-- VarDict module utils - add method ``VarDict.as_dict()`` to convert to a plain ``dict`` object (https://github.com/ansible-collections/community.general/pull/6602).
-- apt_rpm - extract package name from local ``.rpm`` path when verifying
- installation success. Allows installing packages from local ``.rpm`` files
- (https://github.com/ansible-collections/community.general/pull/7396).
-- cargo - add option ``executable``, which allows user to specify path to the cargo binary (https://github.com/ansible-collections/community.general/pull/7352).
-- cargo - add option ``locked`` which allows user to specify install the locked version of dependency instead of latest compatible version (https://github.com/ansible-collections/community.general/pull/6134).
-- chroot connection plugin - add ``disable_root_check`` option (https://github.com/ansible-collections/community.general/pull/7099).
-- cloudflare_dns - add CAA record support (https://github.com/ansible-collections/community.general/pull/7399).
-- cobbler inventory plugin - add ``exclude_mgmt_classes`` and ``include_mgmt_classes`` options to exclude or include hosts based on management classes (https://github.com/ansible-collections/community.general/pull/7184).
-- cobbler inventory plugin - add ``inventory_hostname`` option to allow using the system name for the inventory hostname (https://github.com/ansible-collections/community.general/pull/6502).
-- cobbler inventory plugin - add ``want_ip_addresses`` option to collect all interface DNS name to IP address mapping (https://github.com/ansible-collections/community.general/pull/6711).
-- cobbler inventory plugin - add primary IP addess to ``cobbler_ipv4_address`` and IPv6 address to ``cobbler_ipv6_address`` host variable (https://github.com/ansible-collections/community.general/pull/6711).
-- cobbler inventory plugin - add warning for systems with empty profiles (https://github.com/ansible-collections/community.general/pull/6502).
-- cobbler inventory plugin - convert Ansible unicode strings to native Python unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
-- consul_session - drops requirement for the ``python-consul`` library to communicate with the Consul API, instead relying on the existing ``requests`` library requirement (https://github.com/ansible-collections/community.general/pull/6755).
-- copr - respawn module to use the system python interpreter when the ``dnf`` python module is not available in ``ansible_python_interpreter`` (https://github.com/ansible-collections/community.general/pull/6522).
-- cpanm - minor refactor when creating the ``CmdRunner`` object (https://github.com/ansible-collections/community.general/pull/7231).
-- datadog_monitor - adds ``notification_preset_name``, ``renotify_occurrences`` and ``renotify_statuses`` parameters (https://github.com/ansible-collections/community.general/issues/6521,https://github.com/ansible-collections/community.general/issues/5823).
-- dig lookup plugin - add TCP option to enable the use of TCP connection during DNS lookup (https://github.com/ansible-collections/community.general/pull/7343).
-- ejabberd_user - module now using ``CmdRunner`` to execute external command (https://github.com/ansible-collections/community.general/pull/7075).
-- filesystem - add ``uuid`` parameter for UUID change feature (https://github.com/ansible-collections/community.general/pull/6680).
-- gitlab_group - add option ``force_delete`` (default: false) which allows delete group even if projects exists in it (https://github.com/ansible-collections/community.general/pull/7364).
-- gitlab_group_variable - add support for ``raw`` variables suboption (https://github.com/ansible-collections/community.general/pull/7132).
-- gitlab_project_variable - add support for ``raw`` variables suboption (https://github.com/ansible-collections/community.general/pull/7132).
-- gitlab_project_variable - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
-- gitlab_runner - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
-- htpasswd - minor code improvements in the module (https://github.com/ansible-collections/community.general/pull/6901).
-- htpasswd - the parameter ``crypt_scheme`` is being renamed as ``hash_scheme`` and added as an alias to it (https://github.com/ansible-collections/community.general/pull/6841).
-- icinga2_host - the ``ip`` option is no longer required, since Icinga 2 allows for an empty address attribute (https://github.com/ansible-collections/community.general/pull/7452).
-- ini_file - add ``ignore_spaces`` option (https://github.com/ansible-collections/community.general/pull/7273).
-- ini_file - add ``modify_inactive_option`` option (https://github.com/ansible-collections/community.general/pull/7401).
-- ipa_config - add module parameters to manage FreeIPA user and group objectclasses (https://github.com/ansible-collections/community.general/pull/7019).
-- ipa_config - adds ``idp`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7051).
-- jenkins_build - add new ``detach`` option, which allows the module to exit successfully as long as the build is created (default functionality is still waiting for the build to end before exiting) (https://github.com/ansible-collections/community.general/pull/7204).
-- jenkins_build - add new ``time_between_checks`` option, which allows to configure the wait time between requests to the Jenkins server (https://github.com/ansible-collections/community.general/pull/7204).
-- keycloak_authentication - added provider ID choices, since Keycloak supports only those two specific ones (https://github.com/ansible-collections/community.general/pull/6763).
-- keycloak_client_rolemapping - adds support for subgroups with additional parameter ``parents`` (https://github.com/ansible-collections/community.general/pull/6687).
-- keycloak_role - add composite roles support for realm and client roles (https://github.com/ansible-collections/community.general/pull/6469).
-- keyring - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
-- ldap_* - add new arguments ``client_cert`` and ``client_key`` to the LDAP modules in order to allow certificate authentication (https://github.com/ansible-collections/community.general/pull/6668).
-- ldap_search - add a new ``page_size`` option to enable paged searches (https://github.com/ansible-collections/community.general/pull/6648).
-- locale_gen - module has been refactored to use ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/6903).
-- locale_gen - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6820).
-- lvg - add ``active`` and ``inactive`` values to the ``state`` option for active state management feature (https://github.com/ansible-collections/community.general/pull/6682).
-- lvg - add ``reset_vg_uuid``, ``reset_pv_uuid`` options for UUID reset feature (https://github.com/ansible-collections/community.general/pull/6682).
-- lxc connection plugin - properly handle a change of the ``remote_addr`` option (https://github.com/ansible-collections/community.general/pull/7373).
-- lxd connection plugin - automatically translate ``remote_addr`` from FQDN to (short) hostname (https://github.com/ansible-collections/community.general/pull/7360).
-- lxd connection plugin - update error parsing to work with newer messages mentioning instances (https://github.com/ansible-collections/community.general/pull/7360).
-- lxd inventory plugin - add ``server_cert`` option for trust anchor to use for TLS verification of server certificates (https://github.com/ansible-collections/community.general/pull/7392).
-- lxd inventory plugin - add ``server_check_hostname`` option to disable hostname verification of server certificates (https://github.com/ansible-collections/community.general/pull/7392).
-- make - add new ``targets`` parameter allowing multiple targets to be used with ``make`` (https://github.com/ansible-collections/community.general/pull/6882, https://github.com/ansible-collections/community.general/issues/4919).
-- make - allows ``params`` to be used without value (https://github.com/ansible-collections/community.general/pull/7180).
-- mas - disable sign-in check for macOS 12+ as ``mas account`` is non-functional (https://github.com/ansible-collections/community.general/pull/6520).
-- newrelic_deployment - add option ``app_name_exact_match``, which filters results for the exact app_name provided (https://github.com/ansible-collections/community.general/pull/7355).
-- nmap inventory plugin - now has a ``use_arp_ping`` option to allow the user to disable the default ARP ping query for a more reliable form (https://github.com/ansible-collections/community.general/pull/7119).
-- nmcli - add support for ``ipv4.dns-options`` and ``ipv6.dns-options`` (https://github.com/ansible-collections/community.general/pull/6902).
-- nomad_job, nomad_job_info - add ``port`` parameter (https://github.com/ansible-collections/community.general/pull/7412).
-- npm - minor improvement on parameter validation (https://github.com/ansible-collections/community.general/pull/6848).
-- npm - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6989).
-- onepassword lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635, https://github.com/ansible-collections/community.general/pull/6660).
-- onepassword lookup plugin - introduce ``account_id`` option which allows specifying which account to use (https://github.com/ansible-collections/community.general/pull/7308).
-- onepassword_raw lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635, https://github.com/ansible-collections/community.general/pull/6660).
-- onepassword_raw lookup plugin - introduce ``account_id`` option which allows specifying which account to use (https://github.com/ansible-collections/community.general/pull/7308).
-- opentelemetry callback plugin - add span attributes in the span event (https://github.com/ansible-collections/community.general/pull/6531).
-- opkg - add ``executable`` parameter allowing to specify the path of the ``opkg`` command (https://github.com/ansible-collections/community.general/pull/6862).
-- opkg - remove default value ``""`` for parameter ``force`` as it causes the same behaviour of not having that parameter (https://github.com/ansible-collections/community.general/pull/6513).
-- pagerduty - adds in option to use v2 API for creating pagerduty incidents (https://github.com/ansible-collections/community.general/issues/6151)
-- parted - on resize, use ``--fix`` option if available (https://github.com/ansible-collections/community.general/pull/7304).
-- pnpm - set correct version when state is latest or version is not mentioned. Resolves previous idempotency problem (https://github.com/ansible-collections/community.general/pull/7339).
-- pritunl module utils - ensure ``validate_certs`` parameter is honoured in all methods (https://github.com/ansible-collections/community.general/pull/7156).
-- proxmox - add ``vmid`` (and ``taskid`` when possible) to return values (https://github.com/ansible-collections/community.general/pull/7263).
-- proxmox - support ``timezone`` parameter at container creation (https://github.com/ansible-collections/community.general/pull/6510).
-- proxmox inventory plugin - add composite variables support for Proxmox nodes (https://github.com/ansible-collections/community.general/issues/6640).
-- proxmox_kvm - added support for ``tpmstate0`` parameter to configure TPM (Trusted Platform Module) disk. TPM is required for Windows 11 installations (https://github.com/ansible-collections/community.general/pull/6533).
-- proxmox_kvm - enabled force restart of VM, bringing the ``force`` parameter functionality in line with what is described in the docs (https://github.com/ansible-collections/community.general/pull/6914).
-- proxmox_kvm - re-use ``timeout`` module param to forcefully shutdown a virtual machine when ``state`` is ``stopped`` (https://github.com/ansible-collections/community.general/issues/6257).
-- proxmox_snap - add ``retention`` parameter to delete old snapshots (https://github.com/ansible-collections/community.general/pull/6576).
-- proxmox_vm_info - ``node`` parameter is no longer required. Information can be obtained for the whole cluster (https://github.com/ansible-collections/community.general/pull/6976).
-- proxmox_vm_info - non-existing provided by name/vmid VM would return empty results instead of failing (https://github.com/ansible-collections/community.general/pull/7049).
-- pubnub_blocks - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
-- random_string - added new ``ignore_similar_chars`` and ``similar_chars`` option to ignore certain chars (https://github.com/ansible-collections/community.general/pull/7242).
-- redfish_command - add ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/6471, https://github.com/ansible-collections/community.general/pull/6612).
-- redfish_command - add ``account_types`` and ``oem_account_types`` as optional inputs to ``AddUser`` (https://github.com/ansible-collections/community.general/issues/6823, https://github.com/ansible-collections/community.general/pull/6871).
-- redfish_command - add new option ``update_oem_params`` for the ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/7331).
-- redfish_config - add ``CreateVolume`` command to allow creation of volumes on servers (https://github.com/ansible-collections/community.general/pull/6813).
-- redfish_config - add ``DeleteAllVolumes`` command to allow deletion of all volumes on servers (https://github.com/ansible-collections/community.general/pull/6814).
-- redfish_config - adding ``SetSecureBoot`` command (https://github.com/ansible-collections/community.general/pull/7129).
-- redfish_info - add ``AccountTypes`` and ``OEMAccountTypes`` to the output of ``ListUsers`` (https://github.com/ansible-collections/community.general/issues/6823, https://github.com/ansible-collections/community.general/pull/6871).
-- redfish_info - add support for ``GetBiosRegistries`` command (https://github.com/ansible-collections/community.general/pull/7144).
-- redfish_info - adds ``LinkStatus`` to NIC inventory (https://github.com/ansible-collections/community.general/pull/7318).
-- redfish_info - adds ``ProcessorArchitecture`` to CPU inventory (https://github.com/ansible-collections/community.general/pull/6864).
-- redfish_info - fix for ``GetVolumeInventory``, Controller name was getting populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
-- redfish_info - report ``Id`` in the output of ``GetManagerInventory`` (https://github.com/ansible-collections/community.general/pull/7140).
-- redfish_utils - use ``Controllers`` key in redfish data to obtain Storage controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
-- redfish_utils module utils - add support for ``PowerCycle`` reset type for ``redfish_command`` responses feature (https://github.com/ansible-collections/community.general/issues/7083).
-- redfish_utils module utils - add support for following ``@odata.nextLink`` pagination in ``software_inventory`` responses feature (https://github.com/ansible-collections/community.general/pull/7020).
-- redfish_utils module utils - support ``Volumes`` in response for ``GetDiskInventory`` (https://github.com/ansible-collections/community.general/pull/6819).
-- redhat_subscription - the internal ``RegistrationBase`` class was folded
- into the other internal ``Rhsm`` class, as the separation had no purpose
- anymore
- (https://github.com/ansible-collections/community.general/pull/6658).
-- redis_info - refactor the redis_info module to use the redis module_utils enabling to pass TLS parameters to the Redis client (https://github.com/ansible-collections/community.general/pull/7267).
-- rhsm_release - improve/harden the way ``subscription-manager`` is run;
- no behaviour change is expected
- (https://github.com/ansible-collections/community.general/pull/6669).
-- rhsm_repository - the interaction with ``subscription-manager`` was
- refactored by grouping things together, removing unused bits, and hardening
- the way it is run; also, the parsing of ``subscription-manager repos --list``
- was improved and made slightly faster; no behaviour change is expected
- (https://github.com/ansible-collections/community.general/pull/6783,
- https://github.com/ansible-collections/community.general/pull/6837).
-- scaleway_security_group_rule - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
-- shutdown - use ``shutdown -p ...`` with FreeBSD to halt and power off machine (https://github.com/ansible-collections/community.general/pull/7102).
-- snap - add option ``dangerous`` to the module, that will map into the command line argument ``--dangerous``, allowing unsigned snap files to be installed (https://github.com/ansible-collections/community.general/pull/6908, https://github.com/ansible-collections/community.general/issues/5715).
-- snap - module is now aware of channel when deciding whether to install or refresh the snap (https://github.com/ansible-collections/community.general/pull/6435, https://github.com/ansible-collections/community.general/issues/1606).
-- sorcery - add grimoire (repository) management support (https://github.com/ansible-collections/community.general/pull/7012).
-- sorcery - minor refactor (https://github.com/ansible-collections/community.general/pull/6525).
-- supervisorctl - allow to stop matching running processes before removing them with ``stop_before_removing=true`` (https://github.com/ansible-collections/community.general/pull/7284).
-- tss lookup plugin - allow to fetch secret IDs which are in a folder based on folder ID. Previously, we could not fetch secrets based on folder ID but now use ``fetch_secret_ids_from_folder`` option to indicate to fetch secret IDs based on folder ID (https://github.com/ansible-collections/community.general/issues/6223).
-- tss lookup plugin - allow to fetch secret by path. Previously, we could not fetch secret by path but now use ``secret_path`` option to indicate to fetch secret by secret path (https://github.com/ansible-collections/community.general/pull/6881).
-- unixy callback plugin - add support for ``check_mode_markers`` option (https://github.com/ansible-collections/community.general/pull/7179).
-- vardict module utils - added convenience methods to ``VarDict`` (https://github.com/ansible-collections/community.general/pull/6647).
-- xenserver_guest_info - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
-- xenserver_guest_powerstate - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
-- yum_versionlock - add support to pin specific package versions instead of only the package itself (https://github.com/ansible-collections/community.general/pull/6861, https://github.com/ansible-collections/community.general/issues/4470).
-
-Breaking Changes / Porting Guide
---------------------------------
-
-- collection_version lookup plugin - remove compatibility code for ansible-base 2.10 and ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/7269).
-- gitlab_project - add ``default_branch`` support for project update. If you used the module so far with ``default_branch`` to update a project, the value of ``default_branch`` was ignored. Make sure that you either do not pass a value if you are not sure whether it is the one you want to have to avoid unexpected breaking changes (https://github.com/ansible-collections/community.general/pull/7158).
-- selective callback plugin - remove compatibility code for Ansible 2.9 and ansible-core 2.10 (https://github.com/ansible-collections/community.general/pull/7269).
-- vardict module utils - ``VarDict`` will no longer accept variables named ``_var``, ``get_meta``, and ``as_dict`` (https://github.com/ansible-collections/community.general/pull/6647).
-- version module util - remove fallback for ansible-core 2.11. All modules and plugins that do version collections no longer work with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/7269).
-
-Deprecated Features
--------------------
-
-- CmdRunner module utils - deprecate ``cmd_runner_fmt.as_default_type()`` formatter (https://github.com/ansible-collections/community.general/pull/6601).
-- MH VarsMixin module utils - deprecates ``VarsMixin`` and supporting classes in favor of plain ``vardict`` module util (https://github.com/ansible-collections/community.general/pull/6649).
-- ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211`` options have been deprecated and will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/7358).
-- consul - the ``ack_params_state_absent`` option has been deprecated and will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/7358).
-- cpanm - value ``compatibility`` is deprecated as default for parameter ``mode`` (https://github.com/ansible-collections/community.general/pull/6512).
-- ejabberd_user - deprecate the parameter ``logging`` in favour of producing more detailed information in the module output (https://github.com/ansible-collections/community.general/pull/7043).
-- flowdock - module relies entirely on no longer responsive API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6930).
-- proxmox - old feature flag ``proxmox_default_behavior`` will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/6836).
-- proxmox_kvm - deprecate the option ``proxmox_default_behavior`` (https://github.com/ansible-collections/community.general/pull/7377).
-- redfish_info, redfish_config, redfish_command - the default value ``10`` for the ``timeout`` option is deprecated and will change to ``60`` in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/7295).
-- redhat module utils - the ``module_utils.redhat`` module is deprecated, as
- effectively unused: the ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` classes
- will be removed in community.general 9.0.0; the ``RegistrationBase`` class
- will be removed in community.general 10.0.0 together with the
- ``rhn_register`` module, as it is the only user of this class; this means
- that the whole ``module_utils.redhat`` module will be dropped in
- community.general 10.0.0, so importing it without even using anything of it
- will fail
- (https://github.com/ansible-collections/community.general/pull/6663).
-- redhat_subscription - the ``autosubscribe`` alias for the ``auto_attach`` option has been
- deprecated for many years, although only in the documentation. Officially mark this alias
- as deprecated, and it will be removed in community.general 9.0.0
- (https://github.com/ansible-collections/community.general/pull/6646).
-- redhat_subscription - the ``pool`` option is deprecated in favour of the
- more precise and flexible ``pool_ids`` option
- (https://github.com/ansible-collections/community.general/pull/6650).
-- rhsm_repository - ``state=present`` has not been working as expected for many years,
- and it seems it was not noticed so far; also, "presence" is not really a valid concept
- for subscription repositories, which can only be enabled or disabled. Hence, mark the
- ``present`` and ``absent`` values of the ``state`` option as deprecated, slating them
- for removal in community.general 10.0.0
- (https://github.com/ansible-collections/community.general/pull/6673).
-- stackdriver - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6887).
-- webfaction_app - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
-- webfaction_db - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
-- webfaction_domain - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
-- webfaction_mailbox - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
-- webfaction_site - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
+Callback
+~~~~~~~~
-Removed Features (previously deprecated)
-----------------------------------------
+- community.general.default_without_diff - The default ansible callback without diff output.
+- community.general.timestamp - Adds simple timestamp for each header.
-- The collection no longer supports ansible-core 2.11 and ansible-core 2.12. Parts of the collection might still work on these ansible-core versions, but others might not (https://github.com/ansible-collections/community.general/pull/7269).
-- ansible_galaxy_install - support for Ansible 2.9 and ansible-base 2.10 has been removed (https://github.com/ansible-collections/community.general/pull/7358).
-- consul - when ``state=absent``, the options ``script``, ``ttl``, ``tcp``, ``http``, and ``interval`` can no longer be specified (https://github.com/ansible-collections/community.general/pull/7358).
-- gconftool2 - ``state=get`` has been removed. Use the module ``community.general.gconftool2_info`` instead (https://github.com/ansible-collections/community.general/pull/7358).
-- gitlab_runner - remove the default value for the ``access_level`` option. To restore the previous behavior, explicitly set it to ``ref_protected`` (https://github.com/ansible-collections/community.general/pull/7358).
-- htpasswd - removed code for passlib <1.6 (https://github.com/ansible-collections/community.general/pull/6901).
-- manageiq_polices - ``state=list`` has been removed. Use the module ``community.general.manageiq_policies_info`` instead (https://github.com/ansible-collections/community.general/pull/7358).
-- manageiq_tags - ``state=list`` has been removed. Use the module ``community.general.manageiq_tags_info`` instead (https://github.com/ansible-collections/community.general/pull/7358).
-- mh.mixins.cmd module utils - the ``ArgFormat`` class has been removed (https://github.com/ansible-collections/community.general/pull/7358).
-- mh.mixins.cmd module utils - the ``CmdMixin`` mixin has been removed. Use ``community.general.plugins.module_utils.cmd_runner.CmdRunner`` instead (https://github.com/ansible-collections/community.general/pull/7358).
-- mh.mixins.cmd module utils - the mh.mixins.cmd module utils has been removed after all its contents were removed (https://github.com/ansible-collections/community.general/pull/7358).
-- mh.module_helper module utils - the ``CmdModuleHelper`` and ``CmdStateModuleHelper`` classes have been removed. Use ``community.general.plugins.module_utils.cmd_runner.CmdRunner`` instead (https://github.com/ansible-collections/community.general/pull/7358).
-- proxmox module utils - removed unused imports (https://github.com/ansible-collections/community.general/pull/6873).
-- xfconf - the deprecated ``disable_facts`` option was removed (https://github.com/ansible-collections/community.general/pull/7358).
+Connection
+~~~~~~~~~~
-Bugfixes
---------
+- community.general.incus - Run tasks in Incus instances via the Incus CLI.
-- CmdRunner module utils - does not attempt to resolve path if executable is a relative or absolute path (https://github.com/ansible-collections/community.general/pull/7200).
-- MH DependencyMixin module utils - deprecation notice was popping up for modules not using dependencies (https://github.com/ansible-collections/community.general/pull/6644, https://github.com/ansible-collections/community.general/issues/6639).
-- bitwarden lookup plugin - the plugin made assumptions about the structure of a Bitwarden JSON object which may have been broken by an update in the Bitwarden API. Remove assumptions, and allow queries for general fields such as ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
-- cmd_runner module utils - when a parameter in ``argument_spec`` has no type, meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
-- cobbler inventory plugin - fix calculation of cobbler_ipv4/6_address (https://github.com/ansible-collections/community.general/pull/6925).
-- composer - fix impossible to run ``working_dir`` dependent commands. The module was throwing an error when trying to run a ``working_dir`` dependent command, because it tried to get the command help without passing the ``working_dir`` (https://github.com/ansible-collections/community.general/issues/3787).
-- csv module utils - detects and remove unicode BOM markers from incoming CSV content (https://github.com/ansible-collections/community.general/pull/6662).
-- datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
-- ejabberd_user - module was failing to detect whether user was already created and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
-- ejabberd_user - provide meaningful error message when the ``ejabberdctl`` command is not found (https://github.com/ansible-collections/community.general/pull/7028, https://github.com/ansible-collections/community.general/issues/6949).
-- github_deploy_key - fix pagination behaviour causing a crash when only a single page of deploy keys exist (https://github.com/ansible-collections/community.general/pull/7375).
-- gitlab_group - the module passed parameters to the API call even when not set. The module is now filtering out ``None`` values to remediate this (https://github.com/ansible-collections/community.general/pull/6712).
-- gitlab_group_variable - deleted all variables when used with ``purge=true`` due to missing ``raw`` property in KNOWN attributes (https://github.com/ansible-collections/community.general/issues/7250).
-- gitlab_project_variable - deleted all variables when used with ``purge=true`` due to missing ``raw`` property in KNOWN attributes (https://github.com/ansible-collections/community.general/issues/7250).
-- icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
-- ini_file - add the ``follow`` paramter to follow the symlinks instead of replacing them (https://github.com/ansible-collections/community.general/pull/6546).
-- ini_file - fix a bug where the inactive options were not used when possible (https://github.com/ansible-collections/community.general/pull/6575).
-- ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906, https://github.com/ansible-collections/community.general/issues/6905).
-- kernel_blacklist - simplified the mechanism to update the file, fixing the error (https://github.com/ansible-collections/community.general/pull/7382, https://github.com/ansible-collections/community.general/issues/7362).
-- keycloak module util - fix missing ``http_agent``, ``timeout``, and ``validate_certs`` ``open_url()`` parameters (https://github.com/ansible-collections/community.general/pull/7067).
-- keycloak module utils - fix ``is_struct_included`` handling of lists of lists/dictionaries (https://github.com/ansible-collections/community.general/pull/6688).
-- keycloak module utils - the function ``get_user_by_username`` now return the user representation or ``None`` as stated in the documentation (https://github.com/ansible-collections/community.general/pull/6758).
-- keycloak_authentication - fix Keycloak authentication flow (step or sub-flow) indexing during update, if not specified by the user (https://github.com/ansible-collections/community.general/pull/6734).
-- keycloak_client inventory plugin - fix missing client secret (https://github.com/ansible-collections/community.general/pull/6931).
-- ldap_search - fix string normalization and the ``base64_attributes`` option on Python 3 (https://github.com/ansible-collections/community.general/issues/5704, https://github.com/ansible-collections/community.general/pull/7264).
-- locale_gen - now works for locales without the underscore character such as ``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774, https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
-- lvol - add support for percentage of origin size specification when creating snapshot volumes (https://github.com/ansible-collections/community.general/issues/1630, https://github.com/ansible-collections/community.general/pull/7053).
-- lxc connection plugin - now handles ``remote_addr`` defaulting to ``inventory_hostname`` correctly (https://github.com/ansible-collections/community.general/pull/7104).
-- lxc connection plugin - properly evaluate options (https://github.com/ansible-collections/community.general/pull/7369).
-- machinectl become plugin - mark plugin as ``require_tty`` to automatically disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932, https://github.com/ansible-collections/community.general/pull/6935).
-- mail - skip headers containing equals characters due to missing ``maxsplit`` on header key/value parsing (https://github.com/ansible-collections/community.general/pull/7303).
-- memset module utils - make compatible with ansible-core 2.17 (https://github.com/ansible-collections/community.general/pull/7379).
-- nmap inventory plugin - fix ``get_option`` calls (https://github.com/ansible-collections/community.general/pull/7323).
-- nmap inventory plugin - now uses ``get_option`` in all cases to get its configuration information (https://github.com/ansible-collections/community.general/pull/7119).
-- nmcli - fix bond option ``xmit_hash_policy`` (https://github.com/ansible-collections/community.general/pull/6527).
-- nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
-- nsupdate - fix a possible ``list index out of range`` exception (https://github.com/ansible-collections/community.general/issues/836).
-- oci_utils module util - fix inappropriate logical comparison expressions and makes them simpler. The previous checks had logical short circuits (https://github.com/ansible-collections/community.general/pull/7125).
-- oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
-- onepassword - fix KeyError exception when trying to access value of a field that is not filled out in OnePassword item (https://github.com/ansible-collections/community.general/pull/7241).
-- openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
-- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
-- portage - fix ``changed_use`` and ``newuse`` not triggering rebuilds (https://github.com/ansible-collections/community.general/issues/6008, https://github.com/ansible-collections/community.general/pull/6548).
-- pritunl module utils - fix incorrect URL parameter for orgnization add method (https://github.com/ansible-collections/community.general/pull/7161).
-- proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838, https://github.com/ansible-collections/community.general/issues/5372).
-- proxmox module utils - add logic to detect whether an old Promoxer complains about the ``token_name`` and ``token_value`` parameters and provide a better error message when that happens (https://github.com/ansible-collections/community.general/pull/6839, https://github.com/ansible-collections/community.general/issues/5371).
-- proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974, https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
-- proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always being appended (https://github.com/ansible-collections/community.general/pull/6770).
-- proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
-- proxmox_kvm - ``restarted`` state did not actually restart a VM in some VM configurations. The state now uses the Proxmox reboot endpoint instead of calling the ``stop_vm`` and ``start_vm`` functions (https://github.com/ansible-collections/community.general/pull/6773).
-- proxmox_kvm - allow creation of VM with existing name but new vmid (https://github.com/ansible-collections/community.general/issues/6155, https://github.com/ansible-collections/community.general/pull/6709).
-- proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911, https://github.com/ansible-collections/community.general/pull/6981).
-- proxmox_tasks_info - remove ``api_user`` + ``api_password`` constraint from ``required_together`` as it causes to require ``api_password`` even when API token param is used (https://github.com/ansible-collections/community.general/issues/6201).
-- proxmox_template - require ``requests_toolbelt`` module to fix issue with uploading large templates (https://github.com/ansible-collections/community.general/issues/5579, https://github.com/ansible-collections/community.general/pull/6757).
-- proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
-- redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771, https://github.com/ansible-collections/community.general/pull/6772).
-- redhat_subscription - use the right D-Bus options for the consumer type when
- registering a RHEL system older than 9 or a RHEL 9 system older than 9.2
- and using ``consumer_type``
- (https://github.com/ansible-collections/community.general/pull/7378).
-- refish_utils module utils - changing variable names to avoid issues occuring when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
-- rhsm_repository - when using the ``purge`` option, the ``repositories``
- dictionary element in the returned JSON is now properly updated according
- to the pruning operation
- (https://github.com/ansible-collections/community.general/pull/6676).
-- rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
-- selective callback plugin - fix length of task name lines in output always being 3 characters longer than desired (https://github.com/ansible-collections/community.general/pull/7374).
-- snap - an exception was being raised when snap list was empty (https://github.com/ansible-collections/community.general/pull/7124, https://github.com/ansible-collections/community.general/issues/7120).
-- snap - assume default track ``latest`` in parameter ``channel`` when not specified (https://github.com/ansible-collections/community.general/pull/6835, https://github.com/ansible-collections/community.general/issues/6821).
-- snap - change the change detection mechanism from "parsing installation" to "comparing end state with initial state" (https://github.com/ansible-collections/community.general/pull/7340, https://github.com/ansible-collections/community.general/issues/7265).
-- snap - fix crash when multiple snaps are specified and one has ``---`` in its description (https://github.com/ansible-collections/community.general/pull/7046).
-- snap - fix the processing of the commands' output, stripping spaces and newlines from it (https://github.com/ansible-collections/community.general/pull/6826, https://github.com/ansible-collections/community.general/issues/6803).
-- sorcery - fix interruption of the multi-stage process (https://github.com/ansible-collections/community.general/pull/7012).
-- sorcery - fix queue generation before the whole system rebuild (https://github.com/ansible-collections/community.general/pull/7012).
-- sorcery - latest state no longer triggers update_cache (https://github.com/ansible-collections/community.general/pull/7012).
-- terraform - prevents ``-backend-config`` option double encapsulating with ``shlex_quote`` function. (https://github.com/ansible-collections/community.general/pull/7301).
-- tss lookup plugin - fix multiple issues when using ``fetch_attachments=true`` (https://github.com/ansible-collections/community.general/pull/6720).
-- zypper - added handling of zypper exitcode 102. Changed state is set correctly now and rc 102 is still preserved to be evaluated by the playbook (https://github.com/ansible-collections/community.general/pull/6534).
-
-Known Issues
-------------
-
-- Ansible markup will show up in raw form on ansible-doc text output for ansible-core before 2.15. If you have trouble deciphering the documentation markup, please upgrade to ansible-core 2.15 (or newer), or read the HTML documentation on https://docs.ansible.com/ansible/devel/collections/community/general/ (https://github.com/ansible-collections/community.general/pull/6539).
+Filter
+~~~~~~
-New Plugins
------------
+- community.general.from_ini - Converts INI text input into a dictionary.
+- community.general.lists_difference - Difference of lists with a predictive order.
+- community.general.lists_intersect - Intersection of lists with a predictive order.
+- community.general.lists_symmetric_difference - Symmetric Difference of lists with a predictive order.
+- community.general.lists_union - Union of lists with a predictive order.
+- community.general.to_ini - Converts a dictionary to the INI file format.
Lookup
~~~~~~
-- bitwarden_secrets_manager - Retrieve secrets from Bitwarden Secrets Manager
+- community.general.github_app_access_token - Obtain short-lived Github App Access tokens.
+- community.general.onepassword_doc - Fetch documents stored in 1Password.
+
+Test
+~~~~
+
+- community.general.fqdn_valid - Validates fully-qualified domain names against RFC 1123.
New Modules
-----------
-- consul_policy - Manipulate Consul policies
-- consul_role - Manipulate Consul roles
-- facter_facts - Runs the discovery program C(facter) on the remote system and return Ansible facts
-- gio_mime - Set default handler for MIME type, for applications using Gnome GIO
-- gitlab_instance_variable - Creates, updates, or deletes GitLab instance variables
-- gitlab_merge_request - Create, update, or delete GitLab merge requests
-- jenkins_build_info - Get information about Jenkins builds
-- keycloak_authentication_required_actions - Allows administration of Keycloak authentication required actions
-- keycloak_authz_custom_policy - Allows administration of Keycloak client custom Javascript policies via Keycloak API
-- keycloak_authz_permission - Allows administration of Keycloak client authorization permissions via Keycloak API
-- keycloak_authz_permission_info - Query Keycloak client authorization permissions information
-- keycloak_realm_key - Allows administration of Keycloak realm keys via Keycloak API
-- keycloak_user - Create and configure a user in Keycloak
-- lvg_rename - Renames LVM volume groups
-- pnpm - Manage node.js packages with pnpm
-- proxmox_pool - Pool management for Proxmox VE cluster
-- proxmox_pool_member - Add or delete members from Proxmox VE cluster pools
-- proxmox_vm_info - Retrieve information about one or more Proxmox VE virtual machines
-- simpleinit_msb - Manage services on Source Mage GNU/Linux
+- community.general.consul_acl_bootstrap - Bootstrap ACLs in Consul.
+- community.general.consul_auth_method - Manipulate Consul auth methods.
+- community.general.consul_binding_rule - Manipulate Consul binding rules.
+- community.general.consul_token - Manipulate Consul tokens.
+- community.general.django_command - Run Django admin commands.
+- community.general.dnf_config_manager - Enable or disable dnf repositories using config-manager.
+- community.general.git_config_info - Read git configuration.
+- community.general.gitlab_group_access_token - Manages GitLab group access tokens.
+- community.general.gitlab_issue - Create, update, or delete GitLab issues.
+- community.general.gitlab_label - Creates/updates/deletes GitLab Labels belonging to project or group.
+- community.general.gitlab_milestone - Creates/updates/deletes GitLab Milestones belonging to project or group.
+- community.general.gitlab_project_access_token - Manages GitLab project access tokens.
+- community.general.keycloak_client_rolescope - Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications.
+- community.general.keycloak_component_info - Retrive component info in Keycloak.
+- community.general.keycloak_realm_rolemapping - Allows administration of Keycloak realm role mappings into groups with the Keycloak API.
+- community.general.nomad_token - Manage Nomad ACL tokens.
+- community.general.proxmox_node_info - Retrieve information about one or more Proxmox VE nodes.
+- community.general.proxmox_storage_contents_info - List content from a Proxmox VE storage.
+- community.general.usb_facts - Allows listing information about USB devices.
diff --git a/ansible_collections/community/general/CONTRIBUTING.md b/ansible_collections/community/general/CONTRIBUTING.md
index 199e90c5b..5363b4dac 100644
--- a/ansible_collections/community/general/CONTRIBUTING.md
+++ b/ansible_collections/community/general/CONTRIBUTING.md
@@ -31,7 +31,9 @@ Also, consider taking up a valuable, reviewed, but abandoned pull request which
* Try committing your changes with an informative but short commit message.
* Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge.
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout.
-* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#creating-changelog-fragments). (You must not include a fragment for new modules or new plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
+* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/collection_development_process.html#creating-a-changelog-fragment).
+ * You must not include a fragment for new modules or new plugins. Also you shouldn't include one for docs-only changes. (If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
+ * Please always include a link to the pull request itself, and if the PR is about an issue, also a link to the issue. Also make sure the fragment ends with a period, and begins with a lower-case letter after `-`. (Again, if you don't do this, we'll add suggestions to fix it, so don't worry too much :) )
* Avoid reformatting unrelated parts of the codebase in your PR. These types of changes will likely be requested for reversion, create additional work for reviewers, and may cause approval to be delayed.
You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst).
diff --git a/ansible_collections/community/general/FILES.json b/ansible_collections/community/general/FILES.json
index cbe1d8808..87fdd5c9a 100644
--- a/ansible_collections/community/general/FILES.json
+++ b/ansible_collections/community/general/FILES.json
@@ -109,7 +109,7 @@
"name": ".azure-pipelines/azure-pipelines.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "370fe873607691433d32772c07c53712f66f3745026442838d9d7ca9af953e48",
+ "chksum_sha256": "48eb26e372a37363159b6a17ba403c830d01c2cb29c106bfa8e9748ad534ff50",
"format": 1
},
{
@@ -165,7 +165,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ef0a066aa753e5667b6b1d4e2887f13add9b692f6373bbac695bcbe43e73e73f",
+ "chksum_sha256": "80d4eb6531dc8ba6970eb580ad0f0778f91177d100a99ebf29c93b09795338a1",
"format": 1
},
{
@@ -193,7 +193,7 @@
"name": ".github/BOTMETA.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5d44cab4aa242ff60409d95adf43c4be0bc3d4eace180b0f04da04bcf2d0e119",
+ "chksum_sha256": "95b932042b339875673fcbe218094b962576d3900511a041b9b7fb91a858e68c",
"format": 1
},
{
@@ -312,7 +312,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cc2e8e92892d291b60d26135122e9017acb600db7f386a6ccd71d77846436776",
+ "chksum_sha256": "0014fa74832def0e1d47b994b7aee9fbe393a30553ac051acc1f9a2ac886be6a",
"format": 1
},
{
@@ -326,7 +326,7 @@
"name": "changelogs/config.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e207e9de9d07482a7e441694cf7228b7032639e7c85c56d5d9af454d3bf4e86f",
+ "chksum_sha256": "f2506c25332d5cf5120aa3ca826b2943747cf9d3d8848b7d1f26065f0ee84661",
"format": 1
},
{
@@ -802,7 +802,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7aed4acf161705fece142c2d79ed08c7a5fdf3239644406203cb494b2e74c7a2",
+ "chksum_sha256": "bdd7473e27902ea009dac03f604dd957a93413ee0275b561aff956ff26caf391",
"format": 1
},
{
@@ -865,7 +865,7 @@
"name": "plugins/become/machinectl.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ec9263bc03779820095278c25e9ecbf9a0b8eaefbc8b3372d2f24750a6dd0169",
+ "chksum_sha256": "067c3f6db30dc27550874acab3dd46dcd7151d128a6902806d12febb582a9c0a",
"format": 1
},
{
@@ -890,6 +890,13 @@
"format": 1
},
{
+ "name": "plugins/become/run0.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "427a697d7ac599466ff675649f806c33a06fe94979dda516e27e3ebdbb454302",
+ "format": 1
+ },
+ {
"name": "plugins/become/sesu.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -1068,7 +1075,7 @@
"name": "plugins/callback/opentelemetry.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "06ee85c4b296298fc04a5c1fc85408761c5e6c2c2be40fa1302a5148be6aaac4",
+ "chksum_sha256": "6eb005c02c46afa1b07d7d7861b54496d30ced27113f10b156719b3f151b3014",
"format": 1
},
{
@@ -1114,6 +1121,13 @@
"format": 1
},
{
+ "name": "plugins/callback/timestamp.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3c39c34c1071b004138605f290b4cd4da7a34023a6b551dcad2098f9da7deaa5",
+ "format": 1
+ },
+ {
"name": "plugins/callback/unixy.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -1124,7 +1138,7 @@
"name": "plugins/callback/yaml.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "55f2e5bcd2ef0216231384b40ee1024cc827a71e1d79da82cf42208c5a94fa98",
+ "chksum_sha256": "1e51212b04fd709f1a7ad42c73757d8a68dd670a6d9bcc001faefc6cc83d7059",
"format": 1
},
{
@@ -1243,7 +1257,7 @@
"name": "plugins/doc_fragments/consul.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "16c9b8dc132b77db794a3a96cb75b44900671648edf7962e64f49f65b5b263f3",
+ "chksum_sha256": "04a5d36742f2d94f8e956eff66e36e9a50f915c9a03ae6e24b0a7a1ca8fb873c",
"format": 1
},
{
@@ -1261,6 +1275,13 @@
"format": 1
},
{
+ "name": "plugins/doc_fragments/django.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0836d2f746a8b62a1408455fdd54bcbd8f41342eb2f07a681b378b0efef5f3c8",
+ "format": 1
+ },
+ {
"name": "plugins/doc_fragments/emc.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -1432,7 +1453,7 @@
"name": "plugins/doc_fragments/proxmox.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "37b7c45f450b785105492a38def5db93c9f37b75b00a0c0bc3c0cc6319e8e6bf",
+ "chksum_sha256": "daa7d15e8a1ffc6e4c539712099537ab9c0f667684d2bcf4ba89e196caf9e460",
"format": 1
},
{
@@ -1443,13 +1464,6 @@
"format": 1
},
{
- "name": "plugins/doc_fragments/rackspace.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "cfca4c2528ec42c0f1c6ae9a67f6f4f76887dbbd44db5f5f1688ee49be5bdbe0",
- "format": 1
- },
- {
"name": "plugins/doc_fragments/redis.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -1992,7 +2006,7 @@
"name": "plugins/lookup/merge_variables.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ad758294be13db2a7cf07d9fae8fb187e87f0875360d5c61d909f99d18f707f9",
+ "chksum_sha256": "51f19a61631b9c6932c81608694e5a0a044f7a9d953bda2c60aa7bbc74630eca",
"format": 1
},
{
@@ -2132,7 +2146,7 @@
"name": "plugins/module_utils/mh/mixins/deps.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3aaf0f3bee07c87b4e9108cb474bcb96b715bbad0e77f578987d71ce7fe8dbdf",
+ "chksum_sha256": "bdf853ce77b23f077e4db35e1db8a9f3698c8daa28f39703704e161ffeba1d8c",
"format": 1
},
{
@@ -2146,7 +2160,7 @@
"name": "plugins/module_utils/mh/mixins/vars.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a34c555587e819fa58b076b872b7d7ae05e129818a98b259ead8c4f1a2fbc733",
+ "chksum_sha256": "7bfa206ebd47e9170e6d445f2f4eb6158b4d671b9df038916a06515d97ca68fb",
"format": 1
},
{
@@ -2174,7 +2188,7 @@
"name": "plugins/module_utils/mh/module_helper.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f5070037ffb959097becab8baac019d21ee6fbb305f46f687977500fbcd5fa5f",
+ "chksum_sha256": "7cfecdcceb7062f7f4fec2037ac3cf1c25e1f102b58b5c14a48c281be46ef4d4",
"format": 1
},
{
@@ -2328,7 +2342,7 @@
"name": "plugins/module_utils/cmd_runner.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "62306950ca87a1a83c8e7bb6e3072609181175687ac02e4ad30de2481112b5e4",
+ "chksum_sha256": "9b9f5d0e0ed818b1bdc80e8a6a4a858ba23f92bcaf6d5b224073b4e4a5de1e4c",
"format": 1
},
{
@@ -2374,10 +2388,17 @@
"format": 1
},
{
+ "name": "plugins/module_utils/django.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "78e63b0a1b6304d42171f878bcb50bfd1ff96bfead0ba41220c0b43b6ad1f7cb",
+ "format": 1
+ },
+ {
"name": "plugins/module_utils/gandi_livedns_api.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "77ca8211234201bd301a6728b0e7943ddba5e1c946f8b4c603a1035527fc8ff9",
+ "chksum_sha256": "dd137070737fc1a2da7e03195defcc4a89f8ddb2bb774b7428ba495154ca880b",
"format": 1
},
{
@@ -2398,7 +2419,7 @@
"name": "plugins/module_utils/gitlab.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f0edcbd8ae4a68f9c003e48360e3c4247768a801e34580ed035d04f15d6857a4",
+ "chksum_sha256": "8fc9d765547b03fd9a9902aea741cb6e093f9e31ef621136da55ea5d5218e5ce",
"format": 1
},
{
@@ -2409,6 +2430,13 @@
"format": 1
},
{
+ "name": "plugins/module_utils/homebrew.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4b44f82f141fcc6094b883a2837acb107ba9bf1712c8bf9ec1058f8da65ac888",
+ "format": 1
+ },
+ {
"name": "plugins/module_utils/hwc_utils.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -2503,7 +2531,7 @@
"name": "plugins/module_utils/module_helper.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7eb6f642db5f83ec87a06e04f8d62436a9eec0058cff531cdebf20865c571b09",
+ "chksum_sha256": "cf731e21c346c5c06726b4610c8c55c5833c92491f8659dab7515b267291a901",
"format": 1
},
{
@@ -2566,7 +2594,7 @@
"name": "plugins/module_utils/puppet.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d0c7e2106d6247342b11f2de422240b828a122acd98d9c4ffe5b91899b8893ff",
+ "chksum_sha256": "6d7a9eff010096b299b458427dc2e20a6c0be50527a1f32b9f7ba621e16134da",
"format": 1
},
{
@@ -2577,10 +2605,10 @@
"format": 1
},
{
- "name": "plugins/module_utils/rax.py",
+ "name": "plugins/module_utils/python_runner.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "80bd4c38be7acfedc8542a541c753c87753b249419e06eb20c13884e643408b3",
+ "chksum_sha256": "17e95f6bb431a79a1383d0e29d14cf11a1a4e18ef32af51fb62e62b5831fb4db",
"format": 1
},
{
@@ -2594,7 +2622,7 @@
"name": "plugins/module_utils/redhat.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "43b96c1bce480ed6f9ed9d2a9aafed370295838ed6e5c235e0b7ca3381baf5aa",
+ "chksum_sha256": "29dd2363092ce6ae24719c3c1b442012ea9b75fb07b1dcc099b71aff1467cd7f",
"format": 1
},
{
@@ -2608,7 +2636,7 @@
"name": "plugins/module_utils/rundeck.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0718e463e10a42f9ded1851f689829e05f101ed42888f1abb5c058a90a52fe7e",
+ "chksum_sha256": "f783c1667e85f96c15841bebca24d26da30fc4e31ba647ba8235da209f7bf27b",
"format": 1
},
{
@@ -2657,7 +2685,7 @@
"name": "plugins/module_utils/vardict.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d784bdbf44eb700303730e03a0c0082dcdd52c65c076bbdb5088eb79d556c4a2",
+ "chksum_sha256": "18eca4737619cdceeca1743bb2b0df8d350484fbec5c45decd5bbd5a1bff005e",
"format": 1
},
{
@@ -2748,7 +2776,7 @@
"name": "plugins/modules/aix_lvol.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0e9cb99ceb284742b25feb71e5a105881cf8a31d5601e09dc7666106337b5449",
+ "chksum_sha256": "bbedcb9530c08fc7f9e7fd2e3344da447c1ed3268e6ad9a0aed8da88372b5f85",
"format": 1
},
{
@@ -2783,7 +2811,7 @@
"name": "plugins/modules/ansible_galaxy_install.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b69574b683937c5b7dbc4d541886fb370d8942f0d37c26bfee469456414d8022",
+ "chksum_sha256": "7d6e02e1a7306d048c97e5e9f2e5553fe8ece50ded61a39f014af2fecd51da2a",
"format": 1
},
{
@@ -2818,7 +2846,7 @@
"name": "plugins/modules/apt_rpm.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f0570e79b53c66ebfb69e175ff0edb87f3ea9c10ce4efc791ed0720644459350",
+ "chksum_sha256": "87b7c57c6799012635a126204e30cb04d843d6ee13a5c73e2e4ae2d4bbb78bc3",
"format": 1
},
{
@@ -2923,7 +2951,7 @@
"name": "plugins/modules/btrfs_subvolume.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ef8b5869c7b17e906409346ace86ccba1686bccea5f4f7ae90c7d40744b9fcce",
+ "chksum_sha256": "e3453e87bb110f6d223d4fc3e1603707d6be96e29436274d09b44b0466a81e5b",
"format": 1
},
{
@@ -3063,7 +3091,7 @@
"name": "plugins/modules/cloudflare_dns.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bfe75b2d6815280e55121b0958c219cca514b7d2498ad38b0bafd1ff3581dde1",
+ "chksum_sha256": "b31a62d880737f33437b2dbbc57286a9603ef9771fcdf1e7ec55ff8f6ede6baf",
"format": 1
},
{
@@ -3133,28 +3161,28 @@
"name": "plugins/modules/consul_policy.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9fde6fe3a216b54e45b2946d83bb3d377ad73c094ef0f11ae374b240272b36b2",
+ "chksum_sha256": "05fcd6bd9085bb781d7f9bdc8a808f1e63f493d018299ce3dcb6a8c7f89ae729",
"format": 1
},
{
"name": "plugins/modules/consul_role.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c4f9290e7af434c6f9431da4ebae95a5acf1857fcffe99340737e2748f3ebde2",
+ "chksum_sha256": "f18b68eab0c232b18fefe5d66164dfa49e4e9c11396616200e23b0774c98c5ae",
"format": 1
},
{
"name": "plugins/modules/consul_session.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bf47bd1c93f8b046b6b744eae2972a221f74b4c3ff79c3c9557c243ab1de8ce3",
+ "chksum_sha256": "81d9abf14083b0a074f1eb49bab6783a58c3b204260a93f4ca374557efc4b6d5",
"format": 1
},
{
"name": "plugins/modules/consul_token.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "209599b1c6016b6758413d349c547b3483d6adee030c39824e3fbb23753fdf20",
+ "chksum_sha256": "8572e2337ce15303534844ed997859fc6e26b3b5537ea80fbea280f1bfa17419",
"format": 1
},
{
@@ -3168,7 +3196,7 @@
"name": "plugins/modules/cpanm.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "876e283af86e02ac15cd33a266827b173a6537807fe0c1f7f6ae7c47f04a2f63",
+ "chksum_sha256": "6cdbd7b1b70e4313064f5a409c989c8a45eb43c91b8cc4413ef47d08c289238a",
"format": 1
},
{
@@ -3242,10 +3270,17 @@
"format": 1
},
{
+ "name": "plugins/modules/django_command.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2d3a5411d94f19ca456b07b87d15855f5f5a7e4f9689c26281dca8723f079c89",
+ "format": 1
+ },
+ {
"name": "plugins/modules/django_manage.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f4bb7005611249c174550fa37b5f889c610b2c9b43a91357a549212983518ed4",
+ "chksum_sha256": "de348d4b89f74e04e326b92e81679553f8cf4ae497af025cd7f986dca12af459",
"format": 1
},
{
@@ -3368,31 +3403,24 @@
"format": 1
},
{
- "name": "plugins/modules/flowdock.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "10c9409960f0d5596746d6452e62cc8e9061be52746eca51eded7acf4675c299",
- "format": 1
- },
- {
"name": "plugins/modules/gandi_livedns.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3f2c3fb34518d6c96b87de85eed6fe35dedd51f7a4296b92c0e900c216a5611d",
+ "chksum_sha256": "1fce07336b93fd15824223254e8728602ceb0767463fa1048f035d797373f396",
"format": 1
},
{
"name": "plugins/modules/gconftool2.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ec975973c83bd7130c8fcf2b4176a9b28017e43448852a8b61464f1278f0dcab",
+ "chksum_sha256": "962a743f1dd645556dabba645f4471dc0327aa841576f814c1ee7c86a42d713b",
"format": 1
},
{
"name": "plugins/modules/gconftool2_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d720513958b1ce71503a8826fdd50e81c19c1fbbc19ac20f9164fe0841dcf212",
+ "chksum_sha256": "4665218f56e9722f3929c75b21ef668502a2521204e8b2684709838b425b1f6e",
"format": 1
},
{
@@ -3602,7 +3630,7 @@
"name": "plugins/modules/gitlab_runner.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "53194f5b56d5cf12630f312b1d8af77dd883d1910a50ae91577f5857e2de6f9c",
+ "chksum_sha256": "c5fd5ab6207b5b061fe8fee6d33db0f676590bae7b31e55bf45902b2cddb117a",
"format": 1
},
{
@@ -3658,14 +3686,14 @@
"name": "plugins/modules/homebrew.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "daf7098503d9cc6414a32fe5bf895506264c1dcb9bdd008842e111de5b0279d2",
+ "chksum_sha256": "98ae30cdc14eedb6c381c081a98dbb6ffc6ba2829f37d3315cb7c352c2607b37",
"format": 1
},
{
"name": "plugins/modules/homebrew_cask.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6f5750acbb0afa275d2564e270c28f6afe1202e337e50a0ea0403fafc5cbedfe",
+ "chksum_sha256": "d998aab283569425e1c9da2b2189808b7910da211508b3dda08aed5c7941b33f",
"format": 1
},
{
@@ -3707,7 +3735,7 @@
"name": "plugins/modules/hponcfg.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b8e6e150c96dad033824e7157cd1a31e079064f8e712af23815455e6377cfd61",
+ "chksum_sha256": "9063370c9a8f82e3b9d53519a01277cee764f057932c0fefa5da8ed35860f2bd",
"format": 1
},
{
@@ -3966,7 +3994,7 @@
"name": "plugins/modules/installp.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8c8d4f1272851b63589575bb29db5dca18627fab5f04c26e3917a14960ac2224",
+ "chksum_sha256": "fc3cabbbd25dd3bf4192b82391df7354146b5aadb199b3cf18c07c4a9c3c1613",
"format": 1
},
{
@@ -4162,7 +4190,7 @@
"name": "plugins/modules/irc.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "baf14942dc3f145739b1c8a666e9eb876d33eabfa552455a450c64e891a5f4fc",
+ "chksum_sha256": "f92ac90d9bbb3afe6eae306a71f32b618c42e254dabfa58b5f18a62701607f78",
"format": 1
},
{
@@ -4274,7 +4302,7 @@
"name": "plugins/modules/kernel_blacklist.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "587992974b9adf733a25ee79241b68786b1425efa422ad6d4cd6d75e4c3b3a2a",
+ "chksum_sha256": "b66b3cf5de6d10848b783e0df64104798ae86bf0ca8a307c86e8d71d02a4c50c",
"format": 1
},
{
@@ -4323,7 +4351,7 @@
"name": "plugins/modules/keycloak_client.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9065934124dc12b01077cd9c2caea2640c2f76a5d00541af2a1b1500cbbcba57",
+ "chksum_sha256": "7870103accbfbd0204f1b7adeee0e20b9a6b8cddad0edda0bd31ec252572f186",
"format": 1
},
{
@@ -4393,7 +4421,7 @@
"name": "plugins/modules/keycloak_identity_provider.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fdcb1beb383507dad083dd2ee7ede5f0fc1df884f8ae5548a0740b0cc4fdf5c2",
+ "chksum_sha256": "05f1030efe66d6f0a18689d63b22295169c31ab9a469b87088ef664706ea91cf",
"format": 1
},
{
@@ -4442,7 +4470,7 @@
"name": "plugins/modules/keycloak_user_federation.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1c7c871ab324312ba3730df9a30bd017220a89a09282d465ee6dbc234402181f",
+ "chksum_sha256": "935a9ded4d3ae8651ff215f28aa0d9e420a1643081b2c7d3e0fa6332b83eae84",
"format": 1
},
{
@@ -4519,7 +4547,7 @@
"name": "plugins/modules/ldap_search.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6d79f510a11d341738466cfbf4f59a6bda3d5bd4df45f3692b0653ab37d81946",
+ "chksum_sha256": "d4389e9402a1d367a1069c81319bbb6864f23cc9a6388922f04365eaeb002ce2",
"format": 1
},
{
@@ -4561,7 +4589,7 @@
"name": "plugins/modules/locale_gen.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "871d02439c640ec2f3ad62cae96a6093ffbb27d87bf80bb4638bdb2688fb32e6",
+ "chksum_sha256": "66fcfb84b3417d52cb1fc54cd6fde1bfa3d0ecdc6d4b9664b7a94099585e5976",
"format": 1
},
{
@@ -4589,7 +4617,7 @@
"name": "plugins/modules/lvg.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2b6d4d2fcc2a1b942dd81c4527ae89eef09e955f5f7dac84080741e3629c54a0",
+ "chksum_sha256": "8b55f99113f59765dc7d6a43eda0aca5f22190e4cf0d9685f705c1ea913441e5",
"format": 1
},
{
@@ -4603,7 +4631,7 @@
"name": "plugins/modules/lvol.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c1009f4bb6c0c892f867827fd64ac299c644b634ec838d9c52f2a9be0e0ab71d",
+ "chksum_sha256": "7c931526bbd16c65fe786369e791dfcbe453fdc581acd5da194385e2ec908586",
"format": 1
},
{
@@ -4631,7 +4659,7 @@
"name": "plugins/modules/lxd_container.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3421f907d434f83dd6a346507a607c5ad7cc0b727673b74badf5003841974b4d",
+ "chksum_sha256": "7291ced8278ab06dabee884b06aa37846ec6032bc1d45d00bf7e55e397ac513e",
"format": 1
},
{
@@ -4652,7 +4680,7 @@
"name": "plugins/modules/macports.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "488f95a9d1944fd4aab3aa6cbd32adb06d3727d01c371c9f5d7de00a47ad8fd2",
+ "chksum_sha256": "f40102fb67c8a753de76477793cab247c16e462533b35cba5641ffe1bab6c64d",
"format": 1
},
{
@@ -4813,7 +4841,7 @@
"name": "plugins/modules/mksysb.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "411a53424247600bae0a604ae3fecec02afb97d91283cd389e44310ab8a8d977",
+ "chksum_sha256": "53c173b29bdd8e2ef4ffc2d446a2330b7b20bb7ff0bce830892a3e778347705b",
"format": 1
},
{
@@ -5226,7 +5254,7 @@
"name": "plugins/modules/opkg.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6fafc31bdc0f356419069a1b9f7c4f56d7ea2ba5059eecf3ebda5989b314f8a3",
+ "chksum_sha256": "b30c69db03c0ee20399e242e050b00f90a2d80ba31ad0d20ced0ea15ce1870a7",
"format": 1
},
{
@@ -5366,7 +5394,7 @@
"name": "plugins/modules/parted.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d7a222fa387aae5a78895f665d587f84416ad11f90b049a6d08b4ad8eca1886a",
+ "chksum_sha256": "fcb7ec22fb13a7c15738a296120581204f2ead2fa63ab1736ef3938d74b932c3",
"format": 1
},
{
@@ -5401,21 +5429,21 @@
"name": "plugins/modules/pipx.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4c808a7b43647413be9b220f668517b0a0c263038c5c61e757af52b989942760",
+ "chksum_sha256": "e569818bfa803569a24e9a97033f369486f3119a84ce09343e59127729aa3c1c",
"format": 1
},
{
"name": "plugins/modules/pipx_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "85e936162c11a4fd2736b26644903c3533842d31d92c3a6161dc29ef0f36f3ed",
+ "chksum_sha256": "f92a24ebc20accf94de8b1b5dab13dc4387a71901fcf751dd48a6068bffd28b6",
"format": 1
},
{
"name": "plugins/modules/pkg5.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "64feebf19704a6c42841471d1b0cf4f398f7410361541c91d274a35d01813d43",
+ "chksum_sha256": "e6ad2a1d12ddb2f615609d086765f61a1b575ead60739434fc89477e8688ac87",
"format": 1
},
{
@@ -5429,7 +5457,7 @@
"name": "plugins/modules/pkgin.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1cf640944de02dc6028c8a0130bff6a3de7ee26a2dc6045b45950514e0bf8812",
+ "chksum_sha256": "243f01c0ed2ef3648375458f7949874ecb4ab89bd0ad824c84eff543ce5219e3",
"format": 1
},
{
@@ -5471,7 +5499,7 @@
"name": "plugins/modules/portinstall.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d0fff5d00287f10a07a7108260e747d3ea02eb79f3f56eba22bb382d9657f5fd",
+ "chksum_sha256": "542489c4dd465b6322717c244bce1d85819bdfc882176cd388ef5b5defae377f",
"format": 1
},
{
@@ -5541,112 +5569,112 @@
"name": "plugins/modules/proxmox.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cbaf13c0a56641888d956a3f66827656027362667c00a5da98cfd9fb9c53709c",
+ "chksum_sha256": "62c447303cb615080f4286576bc232c4afe5b20076efe92e9c2760d0fac13364",
"format": 1
},
{
"name": "plugins/modules/proxmox_disk.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7eaf98c0876bdf7959cf06e68dbe617c86dd61c45dd1614d86ced3a3b00c8a6e",
+ "chksum_sha256": "fa088e1c9c1b25860531667e2f7cb9b408fe605bc7cb4969d4c741ac6e1f41f7",
"format": 1
},
{
"name": "plugins/modules/proxmox_domain_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8c15c31af9b758101cd6598e626cc8245d01998205e24a36037e71ba212fbbb1",
+ "chksum_sha256": "74f66feaa8dae01d745fe0edc17bffe2d62f28007f93a738bdd6e877c46e3584",
"format": 1
},
{
"name": "plugins/modules/proxmox_group_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "35430f3908046b38ff12572e85bd305b0d477bbde47066fb522ee8984b3dafe4",
+ "chksum_sha256": "6a4ce8142e20132aae5b1eccda03bfbb5a059f783a9c8164161173890e4581db",
"format": 1
},
{
"name": "plugins/modules/proxmox_kvm.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c148eb6fca047327772da3210a9fe947c4a14fda1405836f0f4c3ffa58da5385",
+ "chksum_sha256": "030cd0ca64eb1eac59e15bd62ce58239e6466b01391a6abc314feff1c8a32614",
"format": 1
},
{
"name": "plugins/modules/proxmox_nic.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "52492a58319b75a634c109c5951be0f9fd1bfced0ac6ee97d00b103ab76087ff",
+ "chksum_sha256": "b65d963ab60b4ed6e0ac0e991c30b6e71fea0847a10e0e53e46e28d93b246f65",
"format": 1
},
{
"name": "plugins/modules/proxmox_node_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3f7053d278a05a60894b5cddb8091e09a27f6d6070b1f41282259cabb41960a1",
+ "chksum_sha256": "55d4166c1f372896d375efed2e0fdbaa415b9a5e410bb1b5db80816a6917ffeb",
"format": 1
},
{
"name": "plugins/modules/proxmox_pool.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "83e86f259c2483e804efbe2966ead9e2eb38b3e1007ff6420e647eb57c6e4e17",
+ "chksum_sha256": "199414912145e8ba5020db36acd042f619a3d313642f05bc30407f280d5c731f",
"format": 1
},
{
"name": "plugins/modules/proxmox_pool_member.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "77fdae49fd415dc3a8f88139a023bb2c2180d5d60f7b493aba9ddd25b3e6fb52",
+ "chksum_sha256": "d1c49690874a6774181bae82fbe9cbf34bfcdd9e71046db98e1dbccdc719c00e",
"format": 1
},
{
"name": "plugins/modules/proxmox_snap.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a79a064dc6522db3c959e678ae66e54e8fe113fa6cca38c379824f429a9230c2",
+ "chksum_sha256": "a1973a4724bff339c462cea5349ea7b8a5c191577cf2d18bbb6c3c19d022cf60",
"format": 1
},
{
"name": "plugins/modules/proxmox_storage_contents_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "207afdc6920a8da3a49b025dade19f6da69bccecee48ef4c1e8508c3baa3a509",
+ "chksum_sha256": "00e2d01f956ca77f3dfc9e5da347406feb15e05d634001972a16fb026263bf5c",
"format": 1
},
{
"name": "plugins/modules/proxmox_storage_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d860af5716ba13e1c0260dba4bcfb4e31d33c9c667063860565166d0ea766d72",
+ "chksum_sha256": "5f98b53b27f0b83b1a4752508981405948da2523892e150051e6fddeec9a09ee",
"format": 1
},
{
"name": "plugins/modules/proxmox_tasks_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "781bdf531b30904b52fde1a5da54433b2c812b6efed34ead3733149f7b16dfbf",
+ "chksum_sha256": "5df3ecdf411646f553a391b3e6c7ab0f4049fd13f96214451c6817c90b0daf23",
"format": 1
},
{
"name": "plugins/modules/proxmox_template.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9c24e106b6dbcfb6a8d5830b7240c6c39bf6959f56591d8ad21cf4023a3cedd6",
+ "chksum_sha256": "112bfc675f756efcca0e21ef96d1d6669e5bdfb31b44108d6f916bc6e19fd190",
"format": 1
},
{
"name": "plugins/modules/proxmox_user_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "085403351a23432173b41649b7bedd8653d48a4f690b427751f4ab09a99195d5",
+ "chksum_sha256": "ade5222d85a933e7cf8e26d08a5c51285b697aec7a83402f1e69ade3efbd7fc8",
"format": 1
},
{
"name": "plugins/modules/proxmox_vm_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4850ad8b78e13bee186bcb49d2e9682723b86ca3fbf4dfba67d4760fc14fdfca",
+ "chksum_sha256": "9bb1491ad5da16bd483f659726e5d99a29ac784a23f615244165ad4d9bde0120",
"format": 1
},
{
@@ -5667,7 +5695,7 @@
"name": "plugins/modules/puppet.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2e8fa36104ad52a85bcbfffadfe873b1dadf91eb5e9f5e1fe843e712ec972708",
+ "chksum_sha256": "4910c9548d2727ddeb25caf1c90a94a7bc99c98877d3042a00394ab59bf8351c",
"format": 1
},
{
@@ -5692,188 +5720,6 @@
"format": 1
},
{
- "name": "plugins/modules/rax.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d5d71364c01d578d124b4f7064cb0850562144e68bb8f8a62000132703cf2776",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_cbs.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "be5f3f94c241633837d888da6abb20f1c54d204f0077147efba813a56f835906",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_cbs_attachments.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "bb83467fd0fdaf72e0ecdb7ccfe67e73b365edeee122cb339f06718364ea1a50",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_cdb.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "1a761ea8d19fb0492b758b4408be987712f64078f367ad9fd1e00d434aaa5bc0",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_cdb_database.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "83ad50782f35ed29183048e2e16655f14fa5178bef73537b5a08c641b4df9e15",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_cdb_user.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "50013e448f5b9136937d1cb028de27da11b6e4a68621b3c10be61f0614f7fce6",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_clb.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "da925aea1e07ae825b7bc40cc2e76feba747bfd173c3c6308c4a169b6a2f4230",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_clb_nodes.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "4a3dd3afe7a509edf5b1caedc8cb047c3b7493d5b3624a64735054df080c715c",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_clb_ssl.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "3832d09feaac166d5c2d13e974bef481a931398a016f492637036ce7eac1a4e8",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_dns.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "2538f8f54a408dd0874028a7af529c3405b537341e5b12cf813ad9c3ae3922fd",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_dns_record.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "36e1fd0124f8aef93f7cff308588a7c3e31f13485ccc06a97a7a29b23e9d2f67",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_facts.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "ef7335464fa3a7419b240dfe9e686e2ef4492c066638afe2bec23f196deff45b",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_files.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "ea66624516f6e40f8e5325587ce6adfd5a7eed178d458952078fbc298e92191a",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_files_objects.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "52860b588511beb773f68c0986529ab633a7480dc93ecb5e72db9d319b9f22e8",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_identity.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "6056f23c9de97fc542dd9a3d34153cb19bae33aa4b2748122efc19b091151e70",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_keypair.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8ddbde316caea7e8d4471de2f0cf977b9a5095731f6904347fe254b97c8cdee8",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_meta.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "096049737ae955b66423fd4b3d106c744002e83868dbe94ca5eb38f43cde5d78",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_mon_alarm.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8faccb337eb09e5dd3d179227a4f21701fa3ffce159ce1398a65e49cc2f949ab",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_mon_check.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "966510c6e07ecdc533ae86afe9aaa973f11554a0568766c158c5f77e118d7193",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_mon_entity.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "f64424b7cd32fafcafaeb1b4c04b33462c50131758d0a94feddee8b30e55c908",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_mon_notification.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "b4d41086547e52926f63bef2cf657e39bfe7a18609721e6ebb43f11fff33e5fa",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_mon_notification_plan.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "626442facabc3ed149f70be592093e36c3e347ddf49a6c77b61316253a271b5a",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_network.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "66f617814f7229b709e6cd393a18ff0c5e295b95e16395134b689b543bfe051b",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_queue.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "5d47ee58bb21549c6cf732396adca95150332637ddccbd647b6ef3a0804b80b3",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_scaling_group.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8cb942ee1f1ea3ea1b45f3699ba09f3fb7827c1376fefefc6f6cd03635c42f64",
- "format": 1
- },
- {
- "name": "plugins/modules/rax_scaling_policy.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "ee634c11356221ce4ee2b1f65b0d3b4b1faf5f7b4df612df10efd0c525053da6",
- "format": 1
- },
- {
"name": "plugins/modules/read_csv.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -5884,28 +5730,28 @@
"name": "plugins/modules/redfish_command.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "38a449fe1a3ce5e62028e851bece4137f2f919f2ab6869f0fc23dc09dfd735f2",
+ "chksum_sha256": "3a06abd918e13f440dcd7bd66a1eae9d77a414aa80dc231eba9ddad2c3fc16d7",
"format": 1
},
{
"name": "plugins/modules/redfish_config.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dc243175c35ab4ffa2d385a92972533c5e1d8ab24060d991a4f9a0b8e850133b",
+ "chksum_sha256": "2a0bad42f9e2ab902beadeb55a1ad309c5e0c1c3f714e6d8f4d483b02d962090",
"format": 1
},
{
"name": "plugins/modules/redfish_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bf2d8f80cadc119e53e6b2626d515a09799e4931d0bfc6d39c39020b65b8bf46",
+ "chksum_sha256": "3f14d5645eb692b829ab83dac5e38eac9ea9fc7bae38f87ffd532ad2e8d49de5",
"format": 1
},
{
"name": "plugins/modules/redhat_subscription.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f6de85514d4fd75fa4ce6d76ad7889008d67a5625c3d7e20b62ace3e0df76f57",
+ "chksum_sha256": "c528d69c6db58dffd6888f30234ab7022f88c2936538fe57ca71da779883240b",
"format": 1
},
{
@@ -6353,7 +6199,7 @@
"name": "plugins/modules/slackpkg.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bbe9e23ec032f7a25bdb7b0fd8f20811d08b058d1976def4b5011851229f4d88",
+ "chksum_sha256": "1ca50585df5578e45594cbfedc789b2b5f12063fa34cad44851bb16fc1c7b471",
"format": 1
},
{
@@ -6367,14 +6213,14 @@
"name": "plugins/modules/snap.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6d0a8e28420c83431d829397011eab016d1e2dd482632e43cb00967db7bfdb7c",
+ "chksum_sha256": "139806babe00b6836e0f630fdcfedf37960b9b29d4c8d4865c91d1a77887528c",
"format": 1
},
{
"name": "plugins/modules/snap_alias.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b588f7b2969ce34f0071ab4a8c4a58a883eb165c3f4696c3ed91f3a95d287a0d",
+ "chksum_sha256": "889e1ff4d1da8e29c100d47a3a82be7d27c098b717e7de76332acbbf051c7d6d",
"format": 1
},
{
@@ -6434,13 +6280,6 @@
"format": 1
},
{
- "name": "plugins/modules/stackdriver.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "260859e428425f3c3ac4bb559a3d4c82273e87301894ac350d8cdf2e193200ab",
- "format": 1
- },
- {
"name": "plugins/modules/stacki_host.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -6486,14 +6325,14 @@
"name": "plugins/modules/svr4pkg.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8194a64057dee3897d1d5c74d4dc557128183315f34bb102dbb47f9bdc8de1c4",
+ "chksum_sha256": "56c3ac1ff64c9da6252c4e749385c6782d1fde4d02df152f9315547e06ec6840",
"format": 1
},
{
"name": "plugins/modules/swdepot.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "548386259af581cf1c3ded8d4ea2ad595e3cedb5c6c7df3533c59d608161712b",
+ "chksum_sha256": "76bd0f44688dd5c7e1cc9b932b12c1e3c8a402991044e4d8c34ac136df9574c4",
"format": 1
},
{
@@ -6812,41 +6651,6 @@
"format": 1
},
{
- "name": "plugins/modules/webfaction_app.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "6883576548556701abe0dae9e225b8cfd752d0f228fb9357db083b0ebe26b4a4",
- "format": 1
- },
- {
- "name": "plugins/modules/webfaction_db.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "40b0caf3268e4866ca3adbd73e29f3f340648eaa267dc52467b36b3215ba9bef",
- "format": 1
- },
- {
- "name": "plugins/modules/webfaction_domain.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d46377b3af3d19a097ced017bebe348c843bf715397e18ef5f5d27803f0e696a",
- "format": 1
- },
- {
- "name": "plugins/modules/webfaction_mailbox.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "966032efd5039669f873f8a33d85573ca7536a261ea3b2eb11e7a1c00978365e",
- "format": 1
- },
- {
- "name": "plugins/modules/webfaction_site.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "1715e8e46b23d2cacda5560e722957ff3440e1f3800461c94c27c13c0582e325",
- "format": 1
- },
- {
"name": "plugins/modules/xattr.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -6899,14 +6703,14 @@
"name": "plugins/modules/xfconf.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dfde9c9bb1f06fc648e437411d5036530781b9753e939a04c2aee066883868b5",
+ "chksum_sha256": "e39ad342c6eb276e06a4f5f96355962d3bf1ee65919306b4a4ebe0cfdcbb8b5c",
"format": 1
},
{
"name": "plugins/modules/xfconf_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fe226ac61a1a542d0a68fedbfa614b92953e557a35bc33daa85238f8579200fa",
+ "chksum_sha256": "8298c11a2fa145f8a1774d08178aaf0470f140074bbacd92143dcada1520bfc2",
"format": 1
},
{
@@ -7771,6 +7575,34 @@
"format": 1
},
{
+ "name": "tests/integration/targets/callback_timestamp",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/callback_timestamp/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/callback_timestamp/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "59fb52bebe9fcf0239c444a3102565e0951c17b66e804b4f00027661545849e7",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/callback_timestamp/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d40d8366b202f652a10750cf49c0db353a8e9f87994196e3415bba3fc231acf4",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/callback_yaml",
"ftype": "dir",
"chksum_type": null,
@@ -8376,7 +8208,7 @@
"name": "tests/integration/targets/cpanm/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "653dbd5100adc070f54638e9c11add3e9b1164d35754d1309a2057fc4f78e2ee",
+ "chksum_sha256": "faa6f84aefea52ab8b9e6508716ffa25fedd4f0f3d1440b1d1afc0b5ebfb45b6",
"format": 1
},
{
@@ -8670,7 +8502,7 @@
"name": "tests/integration/targets/django_manage/tasks/main.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "acf2895219fc5b757396f9d77d4c878c5b36a574043dd9fbb847937d412725ca",
+ "chksum_sha256": "e438e0c590ab3275c054f5478d058d45d84766d160a34d1c3036d6197b76c345",
"format": 1
},
{
@@ -8831,7 +8663,7 @@
"name": "tests/integration/targets/ejabberd_user/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "947101155a8d19ee0d8bf4d74cd963d80ec75d6bd6b7fee8241631f2cf044583",
+ "chksum_sha256": "cf30d0191fdbcdea15cb4fed557820bc300f423103a460cf45a0329d9cc7be4c",
"format": 1
},
{
@@ -9937,7 +9769,7 @@
"name": "tests/integration/targets/gandi_livedns/tasks/create_record.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "446bc960f355726f7738046f5265c5a7d6414157a548f6f7f4c5d59ae8220830",
+ "chksum_sha256": "17221c4ffbf3d7d0fca39430b16cf2af45cd4b592c3614bb8de377b5535e9a15",
"format": 1
},
{
@@ -9965,7 +9797,7 @@
"name": "tests/integration/targets/gandi_livedns/tasks/update_record.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8a72b53a9dfd67149da89b1f827a0a922fa09fb56835a6b87da00010fc1c40ff",
+ "chksum_sha256": "a9c91a60c39152d32812fa5009cae494b88f7e6f899c3108d9376363628c4fc0",
"format": 1
},
{
@@ -11257,6 +11089,20 @@
"format": 1
},
{
+ "name": "tests/integration/targets/homebrew/handlers",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/homebrew/handlers/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "fc600871f7f35c7a11dcd66037c79ea9d6269cfc5d0fc788eb8e481531bdd9b3",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/homebrew/tasks",
"ftype": "dir",
"chksum_type": null,
@@ -11267,21 +11113,28 @@
"name": "tests/integration/targets/homebrew/tasks/casks.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6dea53684420b39d7e51987f3cb6b74e57a7eec45999c4963d9b9208a518b887",
+ "chksum_sha256": "494edfbdfb54e5b0a6bce7fb9df26d3d782781f778108c3aef8b779070540f36",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/homebrew/tasks/docker.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0d278d82d50c06804ac32c230d915a94b5f48f4ffd69dda3a349b89a03b12238",
"format": 1
},
{
"name": "tests/integration/targets/homebrew/tasks/formulae.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f3b0ace4227b32e8e9a7c3a35da793720787e2617f21621f8836d88f5d356b80",
+ "chksum_sha256": "10fcd06a88646913b4c26d724d749f414e36852a44c9f01913ecfc45079427db",
"format": 1
},
{
"name": "tests/integration/targets/homebrew/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "63b4898f3fec452093d5f26f0d0d2ea42365739d61bbb92ef4973c3115d636f9",
+ "chksum_sha256": "365fe427f14e14e94b5aacdc0d391ab1a42e75839b081862784f053d5fbacb3c",
"format": 1
},
{
@@ -13556,7 +13409,7 @@
"name": "tests/integration/targets/keycloak_identity_provider/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "32177a1221cd9929bb79d40beed27c7ec9ac6a21f35767e6e467b6b40594d27f",
+ "chksum_sha256": "1e540794e75ec59a5f755e39525df423fbd1d5fd55eed5d24d553a532bb05017",
"format": 1
},
{
@@ -14662,7 +14515,7 @@
"name": "tests/integration/targets/lookup_merge_variables/runme.sh",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7e7ed20f6d74549dffd00a8f003cfab56317142535b49ff647ec90c0ce8c844e",
+ "chksum_sha256": "d6c4c416f684874bf12d7c11cdec5e2b259a1bbf057a62a9726fde8a46ef2ae1",
"format": 1
},
{
@@ -14680,6 +14533,20 @@
"format": 1
},
{
+ "name": "tests/integration/targets/lookup_merge_variables/test_cross_host_merge_inventory.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3a64a4122077842c8d48942132c3675e4a6070168f996e13f43c04a740948917",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/lookup_merge_variables/test_cross_host_merge_play.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b5de72989e9b21f89f2b7cbbacbfa50df800bfad9c996b81cab5ad0522feed5e",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/lookup_merge_variables/test_inventory_all_hosts.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -15621,7 +15488,7 @@
"name": "tests/integration/targets/module_helper/library/mdepfail.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6ccb5898901617cf6976b660ed6025f61d0ae4c73b01beddf1f6946b88c5643c",
+ "chksum_sha256": "70d8bfa27cad12848db324ae66a12de86abceb01bf06f0fe0fa93b884be2ff62",
"format": 1
},
{
@@ -15642,7 +15509,7 @@
"name": "tests/integration/targets/module_helper/library/mstate.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "feaf0076b48a59004d93f7e9d18b13b919d2a35b3e4d8ede711f9f3ff9c7a510",
+ "chksum_sha256": "5903e88c5a2a5904402d121c151d0448f4afdb9dfb648f55335a91d5400ffef3",
"format": 1
},
{
@@ -20255,7 +20122,7 @@
"name": "tests/integration/targets/snap/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f8e05e7aa1de2b74a9aab47cbdac6f6053fd59d6113d1e968521544a5b9b8285",
+ "chksum_sha256": "73e25e2cdcd2e177465f1ac043858749ecabb7cc1b3158e985de0f7767ee7155",
"format": 1
},
{
@@ -20276,7 +20143,7 @@
"name": "tests/integration/targets/snap/tasks/test_channel.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "06b6a509058dca27433debe5f007f8ea36f69a53ba25ca0f1d5d0bf71ab751ab",
+ "chksum_sha256": "1b44aa52796d0622449e4dacdc2c3385c34a848d200f1ad6372620656ac4a15c",
"format": 1
},
{
@@ -22432,7 +22299,7 @@
"name": "tests/sanity/ignore-2.13.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "96fb0c5067f95b7ce1398bd26cc039eedf03fd8309844d7e59dec097ec594a2c",
+ "chksum_sha256": "b44fa4121d447d611e4099c62f163fa83f7983bbd8a271ddefd8e2c05ff61205",
"format": 1
},
{
@@ -22446,7 +22313,7 @@
"name": "tests/sanity/ignore-2.14.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f1746096cd6755590272792fff8aa9884bde3a011fc8c71e24d9d43e6e847e4b",
+ "chksum_sha256": "0b2cdc0de13edb8c6a5a1dc241f58cadc89ca1bd7378217d3c4116140bcd7704",
"format": 1
},
{
@@ -22460,7 +22327,7 @@
"name": "tests/sanity/ignore-2.15.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1960b0bd13753051ea1250ed6b1de8eb19b8f9e57901350c044d9cd884dc66a6",
+ "chksum_sha256": "df47d504ef24f7ccf8e645e2a330c86642201d942eab2df12a52b584f236eb5e",
"format": 1
},
{
@@ -22474,7 +22341,7 @@
"name": "tests/sanity/ignore-2.16.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b49ac32679f36df6f32acffd654013de426897c51bb40e2024c1baa9b6044ae1",
+ "chksum_sha256": "e549ec441d29f3908b8210c52903dc1db711dc5a16928787e4527706013d3a5a",
"format": 1
},
{
@@ -22488,7 +22355,7 @@
"name": "tests/sanity/ignore-2.17.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4aa6d180dd919a19b80a38b282923231f636556e4bf343b2cf36527d999b2124",
+ "chksum_sha256": "1f44f41aa9a1e5198129a18be0aed641e3859e196aaca08c3cff2d8813ff5490",
"format": 1
},
{
@@ -22502,7 +22369,7 @@
"name": "tests/sanity/ignore-2.18.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4aa6d180dd919a19b80a38b282923231f636556e4bf343b2cf36527d999b2124",
+ "chksum_sha256": "1f44f41aa9a1e5198129a18be0aed641e3859e196aaca08c3cff2d8813ff5490",
"format": 1
},
{
@@ -22660,6 +22527,13 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/become/test_run0.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8c8701c9a8050a55b6ce76546768f86e600f52aaafab02acd9d1c34c051feecf",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/become/test_sudosu.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -23048,7 +22922,7 @@
"name": "tests/unit/plugins/lookup/test_merge_variables.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "96beb7ae4b4dc2eed0102f7f08d298ba619d167356771e4d4f2aa00b9507b18c",
+ "chksum_sha256": "92466922629e3e6beae89f5ca814c538ff85f527897b5c749ff50b1955ea214f",
"format": 1
},
{
@@ -23363,7 +23237,7 @@
"name": "tests/unit/plugins/module_utils/test_cmd_runner.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fc1a28545ad32bc5c937219a3188ea421f7b177bf7c412b64c2081f3dffaaf58",
+ "chksum_sha256": "5e44ed79ba57b534227340b6e97849f84d20811597aaed62aa697d09ab6243f6",
"format": 1
},
{
@@ -23416,6 +23290,13 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/module_utils/test_python_runner.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "63da895b9259d9db9650e5d7b1b998dc546a15c083e61becc9527cc145028015",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/module_utils/test_saslprep.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -26513,7 +26394,7 @@
"name": "tests/unit/plugins/modules/helper.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d92529c5e737c7a3b5aa3d9100502ea7b875f233d86f435c2453f9c77ae012f7",
+ "chksum_sha256": "304e697c86b572f7ec8711a75eb120dd7f013ceff5405ee987af887bd35895f1",
"format": 1
},
{
@@ -26632,7 +26513,7 @@
"name": "tests/unit/plugins/modules/test_cpanm.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9f34f3edb8ae8ba4e017eab4740265089a1986d55066b8e6c70759604cc018b0",
+ "chksum_sha256": "e602576120a85701ecd7af5845fb5944f7f1b134d3f80b14f8934f835cd3485f",
"format": 1
},
{
@@ -26657,6 +26538,20 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/modules/test_django_command.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1507459a2607edf5c63f2f3d171457e869019bf33e95066c365d9eba0942aa87",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/modules/test_django_command.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c5e03ba9fde5c84f8f11a85870829f5c530a29c2c44fbb551df62263202546eb",
+ "format": 1
+ },
+ {
"name": "tests/unit/plugins/modules/test_dnf_config_manager.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -26814,7 +26709,7 @@
"name": "tests/unit/plugins/modules/test_homebrew.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e69d96b396482e1418d7159092f4985ed1eb5ecf4370e9ee1efabb0b7e970398",
+ "chksum_sha256": "fe49d9f40e41b14a956d090b955a7270609439e91118fa1eaee33bbf325d4ec0",
"format": 1
},
{
@@ -27332,7 +27227,7 @@
"name": "tests/unit/plugins/modules/test_puppet.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fd0aef324a3206562948e4dc8c7e756a2adaf9f43a7a0447c80f941c3d4ce153",
+ "chksum_sha256": "bd699d9b1ed9c6e8d0f4e9f7ad57e170e4c4207fdf3eeba04f6359910b4e7e66",
"format": 1
},
{
@@ -27574,6 +27469,20 @@
"format": 1
},
{
+ "name": "tests/unit/plugins/plugin_utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/unit/plugins/plugin_utils/test_unsafe.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "9f8bcb10a66f8398da56f6508697a0d199f0f77f6c0484a64fbecb10997bcdfc",
+ "format": 1
+ },
+ {
"name": "tests/unit/requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
@@ -27738,14 +27647,14 @@
"name": ".gitignore",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6aef8926f289080d8a3ab9cbf9dddcd411a1e2d2e4ccd2c138aa056805ebfb77",
+ "chksum_sha256": "b3e3a5980835432f1db97655c0d123de6e06a98065a19b6453cbf778456c0006",
"format": 1
},
{
"name": "CHANGELOG.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "aa9310c1dd52b555a85d449e50a3ba1bc9de9e5a3474c66e156488463be1cc36",
+ "chksum_sha256": "2fc9c5d7b462624c77da1320ae1acaa13e7e4f765f0fe3393278146104281693",
"format": 1
},
{
@@ -27759,7 +27668,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7192b128389810ee514466d24b34c430fd3e044eafc1db4c3b092a3a630d9985",
+ "chksum_sha256": "28d86e5061f86ee8a49776681a2f660ee38c29d057b9c23c6d2ab473c0f218a5",
"format": 1
},
{
@@ -27773,7 +27682,7 @@
"name": "CONTRIBUTING.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2b729d659927dbf2ef866dc1160a32a704123c9e2be3fe1c1c8d2daa053a83ae",
+ "chksum_sha256": "a7b150aea1da9c4c36ba4e4f8ce7fc40cab2aad7ad0505c3429540fe94270bf9",
"format": 1
},
{
@@ -27787,7 +27696,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "980347a93d90e0b8f8507f59be3be73f0f3026521be645861f2b30880c7ee9fe",
+ "chksum_sha256": "e773d31d8a52af357cddde045bc0682c1f14432496f72b4bd71b76556af876dc",
"format": 1
},
{
diff --git a/ansible_collections/community/general/MANIFEST.json b/ansible_collections/community/general/MANIFEST.json
index 4d700a4c7..ffbae1e0e 100644
--- a/ansible_collections/community/general/MANIFEST.json
+++ b/ansible_collections/community/general/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "general",
- "version": "8.6.0",
+ "version": "9.0.1",
"authors": [
"Ansible (https://github.com/ansible)"
],
@@ -23,7 +23,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "42be361f601f0df607b62621323c3fb70f485cd57cd2d7eecca85d6590836b01",
+ "chksum_sha256": "be2f78923401a69f1bb6105804257106a4092634b2fa6a02058fea1e14de1bff",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/general/README.md b/ansible_collections/community/general/README.md
index 162cc06b0..fb95bf0c7 100644
--- a/ansible_collections/community/general/README.md
+++ b/ansible_collections/community/general/README.md
@@ -6,9 +6,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
# Community General Collection
-[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-8)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
+[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-9)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![EOL CI](https://github.com/ansible-collections/community.general/workflows/EOL%20CI/badge.svg?event=push)](https://github.com/ansible-collections/community.general/actions)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general)
+[![REUSE status](https://api.reuse.software/badge/github.com/ansible-collections/community.general)](https://api.reuse.software/info/github.com/ansible-collections/community.general)
This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
@@ -115,7 +116,7 @@ See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/ma
## Release notes
-See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-8/CHANGELOG.md).
+See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-9/CHANGELOG.md).
## Roadmap
@@ -134,8 +135,8 @@ See [this issue](https://github.com/ansible-collections/community.general/issues
This collection is primarily licensed and distributed as a whole under the GNU General Public License v3.0 or later.
-See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/main/COPYING) for the full text.
+See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-9/COPYING) for the full text.
-Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/PSF-2.0.txt).
+Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/PSF-2.0.txt).
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `.reuse/dep5`. This conforms to the [REUSE specification](https://reuse.software/spec/).
diff --git a/ansible_collections/community/general/changelogs/changelog.yaml b/ansible_collections/community/general/changelogs/changelog.yaml
index b45d41276..6215a89ce 100644
--- a/ansible_collections/community/general/changelogs/changelog.yaml
+++ b/ansible_collections/community/general/changelogs/changelog.yaml
@@ -1,850 +1,158 @@
-ancestor: 7.0.0
+ancestor: 8.0.0
releases:
- 8.0.0:
+ 9.0.0:
changes:
breaking_changes:
- - collection_version lookup plugin - remove compatibility code for ansible-base
- 2.10 and ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/7269).
- - gitlab_project - add ``default_branch`` support for project update. If you
- used the module so far with ``default_branch`` to update a project, the value
- of ``default_branch`` was ignored. Make sure that you either do not pass a
- value if you are not sure whether it is the one you want to have to avoid
- unexpected breaking changes (https://github.com/ansible-collections/community.general/pull/7158).
- - selective callback plugin - remove compatibility code for Ansible 2.9 and
- ansible-core 2.10 (https://github.com/ansible-collections/community.general/pull/7269).
- - vardict module utils - ``VarDict`` will no longer accept variables named ``_var``,
- ``get_meta``, and ``as_dict`` (https://github.com/ansible-collections/community.general/pull/6647).
- - version module util - remove fallback for ansible-core 2.11. All modules and
- plugins that do version collections no longer work with ansible-core 2.11
- (https://github.com/ansible-collections/community.general/pull/7269).
- bugfixes:
- - CmdRunner module utils - does not attempt to resolve path if executable is
- a relative or absolute path (https://github.com/ansible-collections/community.general/pull/7200).
- - MH DependencyMixin module utils - deprecation notice was popping up for modules
- not using dependencies (https://github.com/ansible-collections/community.general/pull/6644,
- https://github.com/ansible-collections/community.general/issues/6639).
- - bitwarden lookup plugin - the plugin made assumptions about the structure
- of a Bitwarden JSON object which may have been broken by an update in the
- Bitwarden API. Remove assumptions, and allow queries for general fields such
- as ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
- - cmd_runner module utils - when a parameter in ``argument_spec`` has no type,
- meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find
- the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
- - cobbler inventory plugin - fix calculation of cobbler_ipv4/6_address (https://github.com/ansible-collections/community.general/pull/6925).
- - composer - fix impossible to run ``working_dir`` dependent commands. The module
- was throwing an error when trying to run a ``working_dir`` dependent command,
- because it tried to get the command help without passing the ``working_dir``
- (https://github.com/ansible-collections/community.general/issues/3787).
- - csv module utils - detects and remove unicode BOM markers from incoming CSV
- content (https://github.com/ansible-collections/community.general/pull/6662).
- - datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning
- Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
- - ejabberd_user - module was failing to detect whether user was already created
- and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
- - ejabberd_user - provide meaningful error message when the ``ejabberdctl``
- command is not found (https://github.com/ansible-collections/community.general/pull/7028,
- https://github.com/ansible-collections/community.general/issues/6949).
- - github_deploy_key - fix pagination behaviour causing a crash when only a single
- page of deploy keys exist (https://github.com/ansible-collections/community.general/pull/7375).
- - gitlab_group - the module passed parameters to the API call even when not
- set. The module is now filtering out ``None`` values to remediate this (https://github.com/ansible-collections/community.general/pull/6712).
- - gitlab_group_variable - deleted all variables when used with ``purge=true``
- due to missing ``raw`` property in KNOWN attributes (https://github.com/ansible-collections/community.general/issues/7250).
- - gitlab_project_variable - deleted all variables when used with ``purge=true``
- due to missing ``raw`` property in KNOWN attributes (https://github.com/ansible-collections/community.general/issues/7250).
- - icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
- - ini_file - add the ``follow`` paramter to follow the symlinks instead of replacing
- them (https://github.com/ansible-collections/community.general/pull/6546).
- - ini_file - fix a bug where the inactive options were not used when possible
- (https://github.com/ansible-collections/community.general/pull/6575).
- - ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906,
- https://github.com/ansible-collections/community.general/issues/6905).
- - kernel_blacklist - simplified the mechanism to update the file, fixing the
- error (https://github.com/ansible-collections/community.general/pull/7382,
- https://github.com/ansible-collections/community.general/issues/7362).
- - keycloak module util - fix missing ``http_agent``, ``timeout``, and ``validate_certs``
- ``open_url()`` parameters (https://github.com/ansible-collections/community.general/pull/7067).
- - keycloak module utils - fix ``is_struct_included`` handling of lists of lists/dictionaries
- (https://github.com/ansible-collections/community.general/pull/6688).
- - keycloak module utils - the function ``get_user_by_username`` now return the
- user representation or ``None`` as stated in the documentation (https://github.com/ansible-collections/community.general/pull/6758).
- - keycloak_authentication - fix Keycloak authentication flow (step or sub-flow)
- indexing during update, if not specified by the user (https://github.com/ansible-collections/community.general/pull/6734).
- - keycloak_client inventory plugin - fix missing client secret (https://github.com/ansible-collections/community.general/pull/6931).
- - ldap_search - fix string normalization and the ``base64_attributes`` option
- on Python 3 (https://github.com/ansible-collections/community.general/issues/5704,
- https://github.com/ansible-collections/community.general/pull/7264).
- - locale_gen - now works for locales without the underscore character such as
- ``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774,
- https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
- - lvol - add support for percentage of origin size specification when creating
- snapshot volumes (https://github.com/ansible-collections/community.general/issues/1630,
- https://github.com/ansible-collections/community.general/pull/7053).
- - lxc connection plugin - now handles ``remote_addr`` defaulting to ``inventory_hostname``
- correctly (https://github.com/ansible-collections/community.general/pull/7104).
- - lxc connection plugin - properly evaluate options (https://github.com/ansible-collections/community.general/pull/7369).
- - machinectl become plugin - mark plugin as ``require_tty`` to automatically
- disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932,
- https://github.com/ansible-collections/community.general/pull/6935).
- - mail - skip headers containing equals characters due to missing ``maxsplit``
- on header key/value parsing (https://github.com/ansible-collections/community.general/pull/7303).
- - memset module utils - make compatible with ansible-core 2.17 (https://github.com/ansible-collections/community.general/pull/7379).
- - nmap inventory plugin - fix ``get_option`` calls (https://github.com/ansible-collections/community.general/pull/7323).
- - nmap inventory plugin - now uses ``get_option`` in all cases to get its configuration
- information (https://github.com/ansible-collections/community.general/pull/7119).
- - nmcli - fix bond option ``xmit_hash_policy`` (https://github.com/ansible-collections/community.general/pull/6527).
- - nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
- - nsupdate - fix a possible ``list index out of range`` exception (https://github.com/ansible-collections/community.general/issues/836).
- - oci_utils module util - fix inappropriate logical comparison expressions and
- makes them simpler. The previous checks had logical short circuits (https://github.com/ansible-collections/community.general/pull/7125).
- - oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
- - onepassword - fix KeyError exception when trying to access value of a field
- that is not filled out in OnePassword item (https://github.com/ansible-collections/community.general/pull/7241).
- - openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error
- message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
- - pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
- - portage - fix ``changed_use`` and ``newuse`` not triggering rebuilds (https://github.com/ansible-collections/community.general/issues/6008,
- https://github.com/ansible-collections/community.general/pull/6548).
- - pritunl module utils - fix incorrect URL parameter for orgnization add method
- (https://github.com/ansible-collections/community.general/pull/7161).
- - proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838,
- https://github.com/ansible-collections/community.general/issues/5372).
- - proxmox module utils - add logic to detect whether an old Promoxer complains
- about the ``token_name`` and ``token_value`` parameters and provide a better
- error message when that happens (https://github.com/ansible-collections/community.general/pull/6839,
- https://github.com/ansible-collections/community.general/issues/5371).
- - proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974,
- https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
- - proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always
- being appended (https://github.com/ansible-collections/community.general/pull/6770).
- - proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the
- VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
- - proxmox_kvm - ``restarted`` state did not actually restart a VM in some VM
- configurations. The state now uses the Proxmox reboot endpoint instead of
- calling the ``stop_vm`` and ``start_vm`` functions (https://github.com/ansible-collections/community.general/pull/6773).
- - proxmox_kvm - allow creation of VM with existing name but new vmid (https://github.com/ansible-collections/community.general/issues/6155,
- https://github.com/ansible-collections/community.general/pull/6709).
- - proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with
- that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911,
- https://github.com/ansible-collections/community.general/pull/6981).
- - proxmox_tasks_info - remove ``api_user`` + ``api_password`` constraint from
- ``required_together`` as it causes to require ``api_password`` even when API
- token param is used (https://github.com/ansible-collections/community.general/issues/6201).
- - proxmox_template - require ``requests_toolbelt`` module to fix issue with
- uploading large templates (https://github.com/ansible-collections/community.general/issues/5579,
- https://github.com/ansible-collections/community.general/pull/6757).
- - proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
- - redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771,
- https://github.com/ansible-collections/community.general/pull/6772).
- - 'redhat_subscription - use the right D-Bus options for the consumer type when
-
- registering a RHEL system older than 9 or a RHEL 9 system older than 9.2
-
- and using ``consumer_type``
-
- (https://github.com/ansible-collections/community.general/pull/7378).
-
- '
- - refish_utils module utils - changing variable names to avoid issues occuring
- when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
- - 'rhsm_repository - when using the ``purge`` option, the ``repositories``
-
- dictionary element in the returned JSON is now properly updated according
-
- to the pruning operation
-
- (https://github.com/ansible-collections/community.general/pull/6676).
-
- '
- - rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
- - selective callback plugin - fix length of task name lines in output always
- being 3 characters longer than desired (https://github.com/ansible-collections/community.general/pull/7374).
- - snap - an exception was being raised when snap list was empty (https://github.com/ansible-collections/community.general/pull/7124,
- https://github.com/ansible-collections/community.general/issues/7120).
- - snap - assume default track ``latest`` in parameter ``channel`` when not specified
- (https://github.com/ansible-collections/community.general/pull/6835, https://github.com/ansible-collections/community.general/issues/6821).
- - snap - change the change detection mechanism from "parsing installation" to
- "comparing end state with initial state" (https://github.com/ansible-collections/community.general/pull/7340,
- https://github.com/ansible-collections/community.general/issues/7265).
- - snap - fix crash when multiple snaps are specified and one has ``---`` in
- its description (https://github.com/ansible-collections/community.general/pull/7046).
- - snap - fix the processing of the commands' output, stripping spaces and newlines
- from it (https://github.com/ansible-collections/community.general/pull/6826,
- https://github.com/ansible-collections/community.general/issues/6803).
- - sorcery - fix interruption of the multi-stage process (https://github.com/ansible-collections/community.general/pull/7012).
- - sorcery - fix queue generation before the whole system rebuild (https://github.com/ansible-collections/community.general/pull/7012).
- - sorcery - latest state no longer triggers update_cache (https://github.com/ansible-collections/community.general/pull/7012).
- - terraform - prevents ``-backend-config`` option double encapsulating with
- ``shlex_quote`` function. (https://github.com/ansible-collections/community.general/pull/7301).
- - tss lookup plugin - fix multiple issues when using ``fetch_attachments=true``
- (https://github.com/ansible-collections/community.general/pull/6720).
- - zypper - added handling of zypper exitcode 102. Changed state is set correctly
- now and rc 102 is still preserved to be evaluated by the playbook (https://github.com/ansible-collections/community.general/pull/6534).
- deprecated_features:
- - CmdRunner module utils - deprecate ``cmd_runner_fmt.as_default_type()`` formatter
- (https://github.com/ansible-collections/community.general/pull/6601).
- - MH VarsMixin module utils - deprecates ``VarsMixin`` and supporting classes
- in favor of plain ``vardict`` module util (https://github.com/ansible-collections/community.general/pull/6649).
- - ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211``
- options have been deprecated and will be removed in community.general 9.0.0
- (https://github.com/ansible-collections/community.general/pull/7358).
- - consul - the ``ack_params_state_absent`` option has been deprecated and will
- be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/7358).
- - cpanm - value ``compatibility`` is deprecated as default for parameter ``mode``
- (https://github.com/ansible-collections/community.general/pull/6512).
- - ejabberd_user - deprecate the parameter ``logging`` in favour of producing
- more detailed information in the module output (https://github.com/ansible-collections/community.general/pull/7043).
- - flowdock - module relies entirely on no longer responsive API endpoints, and
- it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6930).
- - proxmox - old feature flag ``proxmox_default_behavior`` will be removed in
- community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/6836).
- - proxmox_kvm - deprecate the option ``proxmox_default_behavior`` (https://github.com/ansible-collections/community.general/pull/7377).
- - redfish_info, redfish_config, redfish_command - the default value ``10`` for
- the ``timeout`` option is deprecated and will change to ``60`` in community.general
- 9.0.0 (https://github.com/ansible-collections/community.general/pull/7295).
- - 'redhat module utils - the ``module_utils.redhat`` module is deprecated, as
-
- effectively unused: the ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` classes
-
- will be removed in community.general 9.0.0; the ``RegistrationBase`` class
-
- will be removed in community.general 10.0.0 together with the
-
- ``rhn_register`` module, as it is the only user of this class; this means
-
- that the whole ``module_utils.redhat`` module will be dropped in
-
- community.general 10.0.0, so importing it without even using anything of it
-
- will fail
-
- (https://github.com/ansible-collections/community.general/pull/6663).
-
- '
- - 'redhat_subscription - the ``autosubscribe`` alias for the ``auto_attach``
- option has been
-
- deprecated for many years, although only in the documentation. Officially
- mark this alias
-
- as deprecated, and it will be removed in community.general 9.0.0
-
- (https://github.com/ansible-collections/community.general/pull/6646).
-
- '
- - 'redhat_subscription - the ``pool`` option is deprecated in favour of the
-
- more precise and flexible ``pool_ids`` option
-
- (https://github.com/ansible-collections/community.general/pull/6650).
-
- '
- - 'rhsm_repository - ``state=present`` has not been working as expected for
- many years,
-
- and it seems it was not noticed so far; also, "presence" is not really a valid
- concept
-
- for subscription repositories, which can only be enabled or disabled. Hence,
- mark the
-
- ``present`` and ``absent`` values of the ``state`` option as deprecated, slating
- them
-
- for removal in community.general 10.0.0
-
- (https://github.com/ansible-collections/community.general/pull/6673).
-
- '
- - stackdriver - module relies entirely on no longer existent API endpoints,
- and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6887).
- - webfaction_app - module relies entirely on no longer existent API endpoints,
- and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
- - webfaction_db - module relies entirely on no longer existent API endpoints,
- and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
- - webfaction_domain - module relies entirely on no longer existent API endpoints,
- and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
- - webfaction_mailbox - module relies entirely on no longer existent API endpoints,
- and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
- - webfaction_site - module relies entirely on no longer existent API endpoints,
- and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
- known_issues:
- - Ansible markup will show up in raw form on ansible-doc text output for ansible-core
- before 2.15. If you have trouble deciphering the documentation markup, please
- upgrade to ansible-core 2.15 (or newer), or read the HTML documentation on
- https://docs.ansible.com/ansible/devel/collections/community/general/ (https://github.com/ansible-collections/community.general/pull/6539).
- minor_changes:
- - The collection will start using semantic markup (https://github.com/ansible-collections/community.general/pull/6539).
- - VarDict module utils - add method ``VarDict.as_dict()`` to convert to a plain
- ``dict`` object (https://github.com/ansible-collections/community.general/pull/6602).
- - 'apt_rpm - extract package name from local ``.rpm`` path when verifying
-
- installation success. Allows installing packages from local ``.rpm`` files
-
- (https://github.com/ansible-collections/community.general/pull/7396).
-
- '
- - cargo - add option ``executable``, which allows user to specify path to the
- cargo binary (https://github.com/ansible-collections/community.general/pull/7352).
- - cargo - add option ``locked`` which allows user to specify install the locked
- version of dependency instead of latest compatible version (https://github.com/ansible-collections/community.general/pull/6134).
- - chroot connection plugin - add ``disable_root_check`` option (https://github.com/ansible-collections/community.general/pull/7099).
- - cloudflare_dns - add CAA record support (https://github.com/ansible-collections/community.general/pull/7399).
- - cobbler inventory plugin - add ``exclude_mgmt_classes`` and ``include_mgmt_classes``
- options to exclude or include hosts based on management classes (https://github.com/ansible-collections/community.general/pull/7184).
- - cobbler inventory plugin - add ``inventory_hostname`` option to allow using
- the system name for the inventory hostname (https://github.com/ansible-collections/community.general/pull/6502).
- - cobbler inventory plugin - add ``want_ip_addresses`` option to collect all
- interface DNS name to IP address mapping (https://github.com/ansible-collections/community.general/pull/6711).
- - cobbler inventory plugin - add primary IP addess to ``cobbler_ipv4_address``
- and IPv6 address to ``cobbler_ipv6_address`` host variable (https://github.com/ansible-collections/community.general/pull/6711).
- - cobbler inventory plugin - add warning for systems with empty profiles (https://github.com/ansible-collections/community.general/pull/6502).
- - cobbler inventory plugin - convert Ansible unicode strings to native Python
- unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
- - consul_session - drops requirement for the ``python-consul`` library to communicate
- with the Consul API, instead relying on the existing ``requests`` library
- requirement (https://github.com/ansible-collections/community.general/pull/6755).
- - copr - respawn module to use the system python interpreter when the ``dnf``
- python module is not available in ``ansible_python_interpreter`` (https://github.com/ansible-collections/community.general/pull/6522).
- - cpanm - minor refactor when creating the ``CmdRunner`` object (https://github.com/ansible-collections/community.general/pull/7231).
- - datadog_monitor - adds ``notification_preset_name``, ``renotify_occurrences``
- and ``renotify_statuses`` parameters (https://github.com/ansible-collections/community.general/issues/6521,https://github.com/ansible-collections/community.general/issues/5823).
- - dig lookup plugin - add TCP option to enable the use of TCP connection during
- DNS lookup (https://github.com/ansible-collections/community.general/pull/7343).
- - ejabberd_user - module now using ``CmdRunner`` to execute external command
- (https://github.com/ansible-collections/community.general/pull/7075).
- - filesystem - add ``uuid`` parameter for UUID change feature (https://github.com/ansible-collections/community.general/pull/6680).
- - 'gitlab_group - add option ``force_delete`` (default: false) which allows
- delete group even if projects exists in it (https://github.com/ansible-collections/community.general/pull/7364).'
- - gitlab_group_variable - add support for ``raw`` variables suboption (https://github.com/ansible-collections/community.general/pull/7132).
- - gitlab_project_variable - add support for ``raw`` variables suboption (https://github.com/ansible-collections/community.general/pull/7132).
- - gitlab_project_variable - minor refactor removing unnecessary code statements
- (https://github.com/ansible-collections/community.general/pull/6928).
- - gitlab_runner - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
- - htpasswd - minor code improvements in the module (https://github.com/ansible-collections/community.general/pull/6901).
- - htpasswd - the parameter ``crypt_scheme`` is being renamed as ``hash_scheme``
- and added as an alias to it (https://github.com/ansible-collections/community.general/pull/6841).
- - icinga2_host - the ``ip`` option is no longer required, since Icinga 2 allows
- for an empty address attribute (https://github.com/ansible-collections/community.general/pull/7452).
- - ini_file - add ``ignore_spaces`` option (https://github.com/ansible-collections/community.general/pull/7273).
- - ini_file - add ``modify_inactive_option`` option (https://github.com/ansible-collections/community.general/pull/7401).
- - ipa_config - add module parameters to manage FreeIPA user and group objectclasses
- (https://github.com/ansible-collections/community.general/pull/7019).
- - ipa_config - adds ``idp`` choice to ``ipauserauthtype`` parameter's choices
- (https://github.com/ansible-collections/community.general/pull/7051).
- - jenkins_build - add new ``detach`` option, which allows the module to exit
- successfully as long as the build is created (default functionality is still
- waiting for the build to end before exiting) (https://github.com/ansible-collections/community.general/pull/7204).
- - jenkins_build - add new ``time_between_checks`` option, which allows to configure
- the wait time between requests to the Jenkins server (https://github.com/ansible-collections/community.general/pull/7204).
- - keycloak_authentication - added provider ID choices, since Keycloak supports
- only those two specific ones (https://github.com/ansible-collections/community.general/pull/6763).
- - keycloak_client_rolemapping - adds support for subgroups with additional parameter
- ``parents`` (https://github.com/ansible-collections/community.general/pull/6687).
- - keycloak_role - add composite roles support for realm and client roles (https://github.com/ansible-collections/community.general/pull/6469).
- - keyring - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
- - ldap_* - add new arguments ``client_cert`` and ``client_key`` to the LDAP
- modules in order to allow certificate authentication (https://github.com/ansible-collections/community.general/pull/6668).
- - ldap_search - add a new ``page_size`` option to enable paged searches (https://github.com/ansible-collections/community.general/pull/6648).
- - locale_gen - module has been refactored to use ``ModuleHelper`` and ``CmdRunner``
- (https://github.com/ansible-collections/community.general/pull/6903).
- - locale_gen - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6820).
- - lvg - add ``active`` and ``inactive`` values to the ``state`` option for active
- state management feature (https://github.com/ansible-collections/community.general/pull/6682).
- - lvg - add ``reset_vg_uuid``, ``reset_pv_uuid`` options for UUID reset feature
- (https://github.com/ansible-collections/community.general/pull/6682).
- - lxc connection plugin - properly handle a change of the ``remote_addr`` option
- (https://github.com/ansible-collections/community.general/pull/7373).
- - lxd connection plugin - automatically translate ``remote_addr`` from FQDN
- to (short) hostname (https://github.com/ansible-collections/community.general/pull/7360).
- - lxd connection plugin - update error parsing to work with newer messages mentioning
- instances (https://github.com/ansible-collections/community.general/pull/7360).
- - lxd inventory plugin - add ``server_cert`` option for trust anchor to use
- for TLS verification of server certificates (https://github.com/ansible-collections/community.general/pull/7392).
- - lxd inventory plugin - add ``server_check_hostname`` option to disable hostname
- verification of server certificates (https://github.com/ansible-collections/community.general/pull/7392).
- - make - add new ``targets`` parameter allowing multiple targets to be used
- with ``make`` (https://github.com/ansible-collections/community.general/pull/6882,
- https://github.com/ansible-collections/community.general/issues/4919).
- - make - allows ``params`` to be used without value (https://github.com/ansible-collections/community.general/pull/7180).
- - mas - disable sign-in check for macOS 12+ as ``mas account`` is non-functional
- (https://github.com/ansible-collections/community.general/pull/6520).
- - newrelic_deployment - add option ``app_name_exact_match``, which filters results
- for the exact app_name provided (https://github.com/ansible-collections/community.general/pull/7355).
- - nmap inventory plugin - now has a ``use_arp_ping`` option to allow the user
- to disable the default ARP ping query for a more reliable form (https://github.com/ansible-collections/community.general/pull/7119).
- - nmcli - add support for ``ipv4.dns-options`` and ``ipv6.dns-options`` (https://github.com/ansible-collections/community.general/pull/6902).
- - nomad_job, nomad_job_info - add ``port`` parameter (https://github.com/ansible-collections/community.general/pull/7412).
- - npm - minor improvement on parameter validation (https://github.com/ansible-collections/community.general/pull/6848).
- - npm - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6989).
- - onepassword lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635,
- https://github.com/ansible-collections/community.general/pull/6660).
- - onepassword lookup plugin - introduce ``account_id`` option which allows specifying
- which account to use (https://github.com/ansible-collections/community.general/pull/7308).
- - onepassword_raw lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635,
- https://github.com/ansible-collections/community.general/pull/6660).
- - onepassword_raw lookup plugin - introduce ``account_id`` option which allows
- specifying which account to use (https://github.com/ansible-collections/community.general/pull/7308).
- - opentelemetry callback plugin - add span attributes in the span event (https://github.com/ansible-collections/community.general/pull/6531).
- - opkg - add ``executable`` parameter allowing to specify the path of the ``opkg``
- command (https://github.com/ansible-collections/community.general/pull/6862).
- - opkg - remove default value ``""`` for parameter ``force`` as it causes the
- same behaviour of not having that parameter (https://github.com/ansible-collections/community.general/pull/6513).
- - pagerduty - adds in option to use v2 API for creating pagerduty incidents
- (https://github.com/ansible-collections/community.general/issues/6151)
- - parted - on resize, use ``--fix`` option if available (https://github.com/ansible-collections/community.general/pull/7304).
- - pnpm - set correct version when state is latest or version is not mentioned.
- Resolves previous idempotency problem (https://github.com/ansible-collections/community.general/pull/7339).
- - pritunl module utils - ensure ``validate_certs`` parameter is honoured in
- all methods (https://github.com/ansible-collections/community.general/pull/7156).
- - proxmox - add ``vmid`` (and ``taskid`` when possible) to return values (https://github.com/ansible-collections/community.general/pull/7263).
- - proxmox - support ``timezone`` parameter at container creation (https://github.com/ansible-collections/community.general/pull/6510).
- - proxmox inventory plugin - add composite variables support for Proxmox nodes
- (https://github.com/ansible-collections/community.general/issues/6640).
- - proxmox_kvm - added support for ``tpmstate0`` parameter to configure TPM (Trusted
- Platform Module) disk. TPM is required for Windows 11 installations (https://github.com/ansible-collections/community.general/pull/6533).
- - proxmox_kvm - enabled force restart of VM, bringing the ``force`` parameter
- functionality in line with what is described in the docs (https://github.com/ansible-collections/community.general/pull/6914).
- - proxmox_kvm - re-use ``timeout`` module param to forcefully shutdown a virtual
- machine when ``state`` is ``stopped`` (https://github.com/ansible-collections/community.general/issues/6257).
- - proxmox_snap - add ``retention`` parameter to delete old snapshots (https://github.com/ansible-collections/community.general/pull/6576).
- - proxmox_vm_info - ``node`` parameter is no longer required. Information can
- be obtained for the whole cluster (https://github.com/ansible-collections/community.general/pull/6976).
- - proxmox_vm_info - non-existing provided by name/vmid VM would return empty
- results instead of failing (https://github.com/ansible-collections/community.general/pull/7049).
- - pubnub_blocks - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
- - random_string - added new ``ignore_similar_chars`` and ``similar_chars`` option
- to ignore certain chars (https://github.com/ansible-collections/community.general/pull/7242).
- - redfish_command - add ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/6471,
- https://github.com/ansible-collections/community.general/pull/6612).
- - redfish_command - add ``account_types`` and ``oem_account_types`` as optional
- inputs to ``AddUser`` (https://github.com/ansible-collections/community.general/issues/6823,
- https://github.com/ansible-collections/community.general/pull/6871).
- - redfish_command - add new option ``update_oem_params`` for the ``MultipartHTTPPushUpdate``
- command (https://github.com/ansible-collections/community.general/issues/7331).
- - redfish_config - add ``CreateVolume`` command to allow creation of volumes
- on servers (https://github.com/ansible-collections/community.general/pull/6813).
- - redfish_config - add ``DeleteAllVolumes`` command to allow deletion of all
- volumes on servers (https://github.com/ansible-collections/community.general/pull/6814).
- - redfish_config - adding ``SetSecureBoot`` command (https://github.com/ansible-collections/community.general/pull/7129).
- - redfish_info - add ``AccountTypes`` and ``OEMAccountTypes`` to the output
- of ``ListUsers`` (https://github.com/ansible-collections/community.general/issues/6823,
- https://github.com/ansible-collections/community.general/pull/6871).
- - redfish_info - add support for ``GetBiosRegistries`` command (https://github.com/ansible-collections/community.general/pull/7144).
- - redfish_info - adds ``LinkStatus`` to NIC inventory (https://github.com/ansible-collections/community.general/pull/7318).
- - redfish_info - adds ``ProcessorArchitecture`` to CPU inventory (https://github.com/ansible-collections/community.general/pull/6864).
- - redfish_info - fix for ``GetVolumeInventory``, Controller name was getting
- populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
- - redfish_info - report ``Id`` in the output of ``GetManagerInventory`` (https://github.com/ansible-collections/community.general/pull/7140).
- - redfish_utils - use ``Controllers`` key in redfish data to obtain Storage
- controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
- - redfish_utils module utils - add support for ``PowerCycle`` reset type for
- ``redfish_command`` responses feature (https://github.com/ansible-collections/community.general/issues/7083).
- - redfish_utils module utils - add support for following ``@odata.nextLink``
- pagination in ``software_inventory`` responses feature (https://github.com/ansible-collections/community.general/pull/7020).
- - redfish_utils module utils - support ``Volumes`` in response for ``GetDiskInventory``
- (https://github.com/ansible-collections/community.general/pull/6819).
- - 'redhat_subscription - the internal ``RegistrationBase`` class was folded
-
- into the other internal ``Rhsm`` class, as the separation had no purpose
-
- anymore
-
- (https://github.com/ansible-collections/community.general/pull/6658).
-
- '
- - redis_info - refactor the redis_info module to use the redis module_utils
- enabling to pass TLS parameters to the Redis client (https://github.com/ansible-collections/community.general/pull/7267).
- - 'rhsm_release - improve/harden the way ``subscription-manager`` is run;
-
- no behaviour change is expected
-
- (https://github.com/ansible-collections/community.general/pull/6669).
-
- '
- - 'rhsm_repository - the interaction with ``subscription-manager`` was
-
- refactored by grouping things together, removing unused bits, and hardening
-
- the way it is run; also, the parsing of ``subscription-manager repos --list``
-
- was improved and made slightly faster; no behaviour change is expected
-
- (https://github.com/ansible-collections/community.general/pull/6783,
-
- https://github.com/ansible-collections/community.general/pull/6837).
-
- '
- - scaleway_security_group_rule - minor refactor removing unnecessary code statements
- (https://github.com/ansible-collections/community.general/pull/6928).
- - shutdown - use ``shutdown -p ...`` with FreeBSD to halt and power off machine
- (https://github.com/ansible-collections/community.general/pull/7102).
- - snap - add option ``dangerous`` to the module, that will map into the command
- line argument ``--dangerous``, allowing unsigned snap files to be installed
- (https://github.com/ansible-collections/community.general/pull/6908, https://github.com/ansible-collections/community.general/issues/5715).
- - snap - module is now aware of channel when deciding whether to install or
- refresh the snap (https://github.com/ansible-collections/community.general/pull/6435,
- https://github.com/ansible-collections/community.general/issues/1606).
- - sorcery - add grimoire (repository) management support (https://github.com/ansible-collections/community.general/pull/7012).
- - sorcery - minor refactor (https://github.com/ansible-collections/community.general/pull/6525).
- - supervisorctl - allow to stop matching running processes before removing them
- with ``stop_before_removing=true`` (https://github.com/ansible-collections/community.general/pull/7284).
- - tss lookup plugin - allow to fetch secret IDs which are in a folder based
- on folder ID. Previously, we could not fetch secrets based on folder ID but
- now use ``fetch_secret_ids_from_folder`` option to indicate to fetch secret
- IDs based on folder ID (https://github.com/ansible-collections/community.general/issues/6223).
- - tss lookup plugin - allow to fetch secret by path. Previously, we could not
- fetch secret by path but now use ``secret_path`` option to indicate to fetch
- secret by secret path (https://github.com/ansible-collections/community.general/pull/6881).
- - unixy callback plugin - add support for ``check_mode_markers`` option (https://github.com/ansible-collections/community.general/pull/7179).
- - vardict module utils - added convenience methods to ``VarDict`` (https://github.com/ansible-collections/community.general/pull/6647).
- - xenserver_guest_info - minor refactor removing unnecessary code statements
- (https://github.com/ansible-collections/community.general/pull/6928).
- - xenserver_guest_powerstate - minor refactor removing unnecessary code statements
- (https://github.com/ansible-collections/community.general/pull/6928).
- - yum_versionlock - add support to pin specific package versions instead of
- only the package itself (https://github.com/ansible-collections/community.general/pull/6861,
- https://github.com/ansible-collections/community.general/issues/4470).
- release_summary: This is release 8.0.0 of ``community.general``, released on
- 2023-11-01.
- removed_features:
- - The collection no longer supports ansible-core 2.11 and ansible-core 2.12.
- Parts of the collection might still work on these ansible-core versions, but
- others might not (https://github.com/ansible-collections/community.general/pull/7269).
- - ansible_galaxy_install - support for Ansible 2.9 and ansible-base 2.10 has
- been removed (https://github.com/ansible-collections/community.general/pull/7358).
- - consul - when ``state=absent``, the options ``script``, ``ttl``, ``tcp``,
- ``http``, and ``interval`` can no longer be specified (https://github.com/ansible-collections/community.general/pull/7358).
- - gconftool2 - ``state=get`` has been removed. Use the module ``community.general.gconftool2_info``
- instead (https://github.com/ansible-collections/community.general/pull/7358).
- - gitlab_runner - remove the default value for the ``access_level`` option.
- To restore the previous behavior, explicitly set it to ``ref_protected`` (https://github.com/ansible-collections/community.general/pull/7358).
- - htpasswd - removed code for passlib <1.6 (https://github.com/ansible-collections/community.general/pull/6901).
- - manageiq_polices - ``state=list`` has been removed. Use the module ``community.general.manageiq_policies_info``
- instead (https://github.com/ansible-collections/community.general/pull/7358).
- - manageiq_tags - ``state=list`` has been removed. Use the module ``community.general.manageiq_tags_info``
- instead (https://github.com/ansible-collections/community.general/pull/7358).
- - mh.mixins.cmd module utils - the ``ArgFormat`` class has been removed (https://github.com/ansible-collections/community.general/pull/7358).
- - mh.mixins.cmd module utils - the ``CmdMixin`` mixin has been removed. Use
- ``community.general.plugins.module_utils.cmd_runner.CmdRunner`` instead (https://github.com/ansible-collections/community.general/pull/7358).
- - mh.mixins.cmd module utils - the mh.mixins.cmd module utils has been removed
- after all its contents were removed (https://github.com/ansible-collections/community.general/pull/7358).
- - mh.module_helper module utils - the ``CmdModuleHelper`` and ``CmdStateModuleHelper``
- classes have been removed. Use ``community.general.plugins.module_utils.cmd_runner.CmdRunner``
- instead (https://github.com/ansible-collections/community.general/pull/7358).
- - proxmox module utils - removed unused imports (https://github.com/ansible-collections/community.general/pull/6873).
- - xfconf - the deprecated ``disable_facts`` option was removed (https://github.com/ansible-collections/community.general/pull/7358).
- fragments:
- - 3787-pass-composer-working-dir.yml
- - 6134-add-locked-option-for-cargo.yml
- - 6223-get-secret-ids-by-folderid.yml
- - 6435-snap-channel-aware.yml
- - 6469-add-composites-support-for-keycloak-role.yml
- - 6471-redfish-add-multipart-http-push-command.yml
- - 6502-cobbler-inventory_hostname.yml
- - 6510-proxmox-create-support_timezone.yaml
- - 6512-cpanm-default-mode.yml
- - 6513-opkg-default-force.yml
- - 6520-mas-disable-signin.yaml
- - 6522-copr-respawn.yaml
- - 6523-datadog-monitor-notification-preset-name-and-renotify.yaml
- - 6525-sorcery-import.yaml
- - 6527-nmcli-bond-fix-xmit_hash_policy.yml
- - 6531-opentelemetry-add-event-attributes.yml
- - 6533-proxmox_kvm-tpmstate0-support.yaml
- - 6534-zypper-exitcode-102-handled.yaml
- - 6539-semantic-markup.yml
- - 6548-portage-changed_use-newuse.yml
- - 6554-proxmox-tasks-info-fix-required-password.yaml
- - 6568-fix-get-user-by-username-in-keycloak-module-utils.yml
- - 6570-handle-shutdown-timeout.yaml
- - 6576-proxmox-snap-allow-to-remove-old-snapshots.yml
- - 6601-cmdrunner-deprecate-default-type.yml
- - 6602-vardict-as-dict.yml
- - 6640-proxmox-composite-variables-support.yml
- - 6644-dependencymixin-fix.yml
- - 6646-redhat_subscription-deprecate-autosubscribe.yml
- - 6647-vardict-methods.yml
- - 6648_ldap_search_page_size.yml
- - 6649-varsmixin-deprecation.yml
- - 6650-redhat_subscription-deprecate-pool.yml
- - 6658-redhat_subscription-internal-rhsm-refactor.yml
- - 6660-onepassword-lookup-service-account.yaml
- - 6662-csv-bom.yml
- - 6663-deprecate-module_utils-redhat.yml
- - 6668-ldap-client-cert.yml
- - 6669-rhsm_release-internal-sub-man-exec.yml
- - 6673-rhsm_repository-deprecate-present-absent.yml
- - 6676-rhsm_repository-fix-returned-repositories-with-purge.yml
- - 6680-filesystem-uuid-change.yml
- - 6682-lvg-clonesupport.yml
- - 6687-support-subgroups-for-keycloak-client-rolemapping.yml
- - 6688-is-struct-included-bug-in-keycloak-py.yml
- - 6709-proxmox-create-vm-with-existing-name.yml
- - 6711-cobbler-ip-address.yml
- - 6712-gitlab_group-filtered-for-none-values.yml
- - 6713-yay-become.yml
- - 6719-redfish-utils-fix-for-get-volume-inventory.yml
- - 6720-tss-fix-fetch-attachments.yml
- - 6734-keycloak-auth-management-indexing.yml
- - 6748-icinga2_host-datafix.yml
- - 6755-refactor-consul-session-to-use-requests-lib-instead-of-consul.yml
- - 6757-proxmox-template-fix-upload-error.yml
- - 6763-keycloak-auth-provider-choices.yml
- - 6769-nmcli-fix-empty-list.yml
- - 6770-proxmox_disk_create_cdrom.yml
- - 6771-redfish-filter-empty-account-slots.yml
- - 6773-proxmox_kvm-restarted-state-bug-fix.yaml
- - 6774-locale-gen-fix.yml
- - 6783-6837-rhsm_repository-internal-refactor.yml
- - 6785-openbsd_pkg_pkg_info_handling.yml
- - 6811-datadog-downtime-rrule-type.yaml
- - 6813-redfish-config-add-create-volume.yml
- - 6814-redfish-config-add-delete-all-volumes.yml
- - 6819-redfish-utils-add-links-parameter-for-get_disk_inventory.yml
- - 6820-locale-gen-cmdrunner.yml
- - 6823-redfish-add-account-type-management.yml
- - 6826-snap-out-strip.yml
- - 6827-proxmox_kvm-force-delete-bug-fix.yaml
- - 6835-snap-missing-track.yml
- - 6836-proxmox-deprecate-compatibility.yml
- - 6838-proxmox-dict-template.yml
- - 6839-promoxer-tokens.yml
- - 6841-htpasswd-crypt-scheme.yml
- - 6848-npm-required-if.yml
- - 6861-yum_versionlock_minor_change_add-pinning-specific-versions.yml
- - 6862-opkg-exec.yml
- - 6864-redfish-utils-fix-for-processorarchitecture-in-cpu-inventory.yaml
- - 6873-proxmox-imports.yml
- - 6882-make-multiple-targets.yml
- - 6883-redfish-utils-changing-variable-names-in-get-volume-inventory.yml
- - 6887-deprecate-stackdrive.yml
- - 6901-htpasswd-refactor.yml
- - 6902-added-support-in-nmcli-for-ipvx-dns-options.yml
- - 6903-locale-gen-refactor.yml
- - 6905-ipa_dnszone-key-error-fix.yml
- - 6908-snap-dangerous.yml
- - 6909-deprecate-webfaction.yml
- - 6914-proxmox_kvm-enable-force-restart.yml
- - 6923-cobbler-inventory_unicode.yml
- - 6925-cobbler-inventory-bugfix.yml
- - 6927-pylint-comments.yml
- - 6928-noqa-comments.yml
- - 6930-deprecate-flowdock.yml
- - 6931-keycloak_client-inventory-bugfix.yml
- - 6935-machinectl-become.yml
- - 6949-ejabberdctl-error.yml
- - 6968-cmdrunner-implicit-type.yml
- - 6976-proxmox-vm-info-not-require-node.yml
- - 6980-proxmox-fix-token-auth.yml
- - 6981-proxmox-fix-vm-creation-when-only-name-provided.yml
- - 6983-rundeck-fix-typerrror-on-404-api-response.yml
- - 6989-npm-cmdrunner.yml
- - 7012-sorcery-grimoire-mgmt.yml
- - 7019-ipa_config-user-and-group-objectclasses.yml
- - 7020-redfish-utils-pagination.yml
- - 7033-ejabberd-user-bugs.yml
- - 7043-ejabberd-user-deprecate-logging.yml
- - 7046-snap-newline-before-separator.yml
- - 7049-proxmox-vm-info-empty-results.yml
- - 7051-ipa-config-new-choice-idp-to-ipauserauthtype.yml
- - 7061-fix-bitwarden-get_field.yml
- - 7067-keycloak-api-paramerter-fix.yml
- - 7075-ejabberd-user-cmdrunner.yml
- - 7081-redfish-utils-fix-for-storagecontrollers-deprecated-key.yaml
- - 7085-sanity.yml
- - 7099-chroot-disable-root-check-option.yml
- - 7102-freebsd-shutdown-p.yml
- - 7104_fix_lxc_remoteaddr_default.yml
- - 7113-redfish-utils-power-cycle.yml
- - 7118-nmap_inv_plugin_no_arp_option.yml
- - 7124-snap-empty-list.yml
- - 7125-fix-inappropriate-comparison.yml
- - 7129-adding_set_secure_boot_command_to_redfish_config.yml
- - 7132-gitlab-raw-variables.yml
- - 7140-id-getmanagerinv-output.yml
- - 7144-add-getbiosregistry-command-to-redfish-info.yml
- - 7156-ensure-validate-certs-parameter-is-honoured.yml
- - 7158-gitlab-project-default-branch-update.yml
- - 7161-fix-incorrect-post-parameter.yml
- - 7179-unixy-support-checkmode-markers.yml
- - 7180-make_params_without_value.yml
- - 7184-cobbler-mgmt-classes.yml
- - 7200-cmd-runner-abs-path.yml
- - 7219-fix-nsupdate-cname.yaml
- - 7231-cpanm-adjustments.yml
- - 7241-prevent-key-error-when-value-does-not-exist.yml
- - 7242_ignore_similar_chars.yml
- - 7251-gitlab-variables-deleteing-all-variables.yml
- - 7263-proxmox-return-vmid-and-taskid.yaml
- - 7264-ldap_search-strings.yml
- - 7267-redis_info.yml
- - 7273-ini_file_ignore_spaces.yml
- - 7284-supervisorctl-stop-before-remove.yaml
- - 7295-adding_deprecation_for_timeout_in_redfish_info_config_command.yml
- - 7301-fix-backend-config-string-encapsulation.yml
- - 7303-mail-incorrect-header-parsing.yml
- - 7304-prevent-parted-warnings.yml
- - 7308-onepassword-multi-acc.yml
- - 7318-add-linkstatus-attribute-to-nic-inventory.yml
- - 7323-nmap.yml
- - 7330-redfish-utils-oem-params.yml
- - 7339-pnpm-correct-version-when-state-latest.yml
- - 7340-snap-fix.yml
- - 7343-dig-tcp-option.yml
- - 7352-add-executable-option-for-cargo.yml
- - 7355-newrelic-deployment-add-exact-name.yml
- - 7360-lxd-remote-addr-host.yml
- - 7364-add-option-force-gitlab-group.yml
- - 7369-fix-lxc-options.yml
- - 7373-lxc-remote-addr-change.yml
- - 7374-fix-selective-callback-taskname-length.yml
- - 7375-fix-github-deploy-key-pagination.yml
- - 7377-proxmox-kvm-deprecate-flag.yml
- - 7378-redhat_subscription-dbus-consumer-type.yaml
- - 7379-url.yml
- - 7382-kernel-blacklist-bugfix.yml
- - 7392-lxd-inventory-server-cert.yml
- - 7396-fix-apt_rpm-local-rpm-installation.yml
- - 7399-cloudflare_dns-add-CAA-record-support.yml
- - 7401-ini-file-modify-inactive-option.yaml
- - 7412-add-port-for-nomad-connection.yaml
- - 7452-fix-icinga2_host-requiring-ip-key.yml
- - 8.0.0.yml
- - ansible-core-2.11-2.12.yml
- - get-secret-by-path.yml
- - improvements-to-jenkins-build-module.yml
- - ini_file-preserve-symlink.yml
- - ini_file-use-inactive-options-when-possible.yml
- - lvol-pct-of-origin.yml
- - removals.yml
- - update-v2-pagerduty-alert.yml
- modules:
- - description: Manipulate Consul policies
- name: consul_policy
- namespace: ''
- - description: Manipulate Consul roles
- name: consul_role
- namespace: ''
- - description: Runs the discovery program C(facter) on the remote system and return
- Ansible facts
- name: facter_facts
- namespace: ''
- - description: Set default handler for MIME type, for applications using Gnome
- GIO
- name: gio_mime
- namespace: ''
- - description: Creates, updates, or deletes GitLab instance variables
- name: gitlab_instance_variable
- namespace: ''
- - description: Create, update, or delete GitLab merge requests
- name: gitlab_merge_request
- namespace: ''
- - description: Get information about Jenkins builds
- name: jenkins_build_info
- namespace: ''
- - description: Allows administration of Keycloak authentication required actions
- name: keycloak_authentication_required_actions
- namespace: ''
- - description: Allows administration of Keycloak client custom Javascript policies
- via Keycloak API
- name: keycloak_authz_custom_policy
- namespace: ''
- - description: Allows administration of Keycloak client authorization permissions
- via Keycloak API
- name: keycloak_authz_permission
- namespace: ''
- - description: Query Keycloak client authorization permissions information
- name: keycloak_authz_permission_info
- namespace: ''
- - description: Allows administration of Keycloak realm keys via Keycloak API
- name: keycloak_realm_key
- namespace: ''
- - description: Create and configure a user in Keycloak
- name: keycloak_user
- namespace: ''
- - description: Renames LVM volume groups
- name: lvg_rename
- namespace: ''
- - description: Manage node.js packages with pnpm
- name: pnpm
- namespace: ''
- - description: Pool management for Proxmox VE cluster
- name: proxmox_pool
- namespace: ''
- - description: Add or delete members from Proxmox VE cluster pools
- name: proxmox_pool_member
- namespace: ''
- - description: Retrieve information about one or more Proxmox VE virtual machines
- name: proxmox_vm_info
- namespace: ''
- - description: Manage services on Source Mage GNU/Linux
- name: simpleinit_msb
- namespace: ''
- plugins:
- lookup:
- - description: Retrieve secrets from Bitwarden Secrets Manager
- name: bitwarden_secrets_manager
- namespace: null
- release_date: '2023-11-01'
- 8.0.1:
- changes:
+ - cpanm - the default of the ``mode`` option changed from ``compatibility``
+ to ``new`` (https://github.com/ansible-collections/community.general/pull/8198).
+ - django_manage - the module now requires Django >= 4.1 (https://github.com/ansible-collections/community.general/pull/8198).
+ - django_manage - the module will now fail if ``virtualenv`` is specified but
+ no virtual environment exists at that location (https://github.com/ansible-collections/community.general/pull/8198).
+ - redfish_command, redfish_config, redfish_info - change the default for ``timeout``
+ from 10 to 60 (https://github.com/ansible-collections/community.general/pull/8198).
bugfixes:
+ - aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd``
+ (https://github.com/ansible-collections/community.general/issues/8151).
+ - aix_filesystem - fix issue with empty list items in crfs logic and option
+ order (https://github.com/ansible-collections/community.general/pull/8052).
+ - apt-rpm - the module did not upgrade packages if a newer version exists. Now
+ the package will be reinstalled if the candidate is newer than the installed
+ version (https://github.com/ansible-collections/community.general/issues/7414).
+ - apt_rpm - when checking whether packages were installed after running ``apt-get
+ -y install <packages>``, only the last package name was checked (https://github.com/ansible-collections/community.general/pull/8263).
+ - bitwarden_secrets_manager lookup plugin - implements retry with exponential
+ backoff to avoid lookup errors when Bitwardn's API rate limiting is encountered
+ (https://github.com/ansible-collections/community.general/issues/8230, https://github.com/ansible-collections/community.general/pull/8238).
+ - 'cargo - fix idempotency issues when using a custom installation path for
+ packages (using the ``--path`` parameter). The initial installation runs fine,
+ but subsequent runs use the ``get_installed()`` function which did not check
+ the given installation location, before running ``cargo install``. This resulted
+ in a false ``changed`` state. Also the removal of packeges using ``state:
+ absent`` failed, as the installation check did not use the given parameter
+ (https://github.com/ansible-collections/community.general/pull/7970).'
+ - cloudflare_dns - fix Cloudflare lookup of SHFP records (https://github.com/ansible-collections/community.general/issues/7652).
+ - consul_token - fix token creation without ``accessor_id`` (https://github.com/ansible-collections/community.general/pull/8091).
+ - from_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow
+ converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183,
+ https://github.com/ansible-collections/community.general/pull/8185).
- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members``
module (https://github.com/ansible-collections/community.general/issues/7467).
+ - gitlab_issue - fix behavior to search GitLab issue, using ``search`` keyword
+ instead of ``title`` (https://github.com/ansible-collections/community.general/issues/7846).
+ - gitlab_issue, gitlab_label, gitlab_milestone - avoid crash during version
+ comparison when the python-gitlab Python module is not installed (https://github.com/ansible-collections/community.general/pull/8158).
- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members``
module (https://github.com/ansible-collections/community.general/issues/7467).
- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches``
module (https://github.com/ansible-collections/community.general/issues/7467).
+ - gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
- - proxmox_pool_member - absent state for type VM did not delete VMs from the
- pools (https://github.com/ansible-collections/community.general/pull/7464).
- - redfish_command - fix usage of message parsing in ``SimpleUpdate`` and ``MultipartHTTPPushUpdate``
- commands to treat the lack of a ``MessageId`` as no message (https://github.com/ansible-collections/community.general/issues/7465,
- https://github.com/ansible-collections/community.general/pull/7471).
- release_summary: Bugfix release for inclusion in Ansible 9.0.0b1.
- fragments:
- - 7464-fix-vm-removal-in-proxmox_pool_member.yml
- - 7465-redfish-firmware-update-message-id-hardening.yml
- - 7467-fix-gitlab-constants-calls.yml
- - 8.0.1.yml
- release_date: '2023-11-06'
- 8.0.2:
- changes:
- bugfixes:
- - ocapi_utils, oci_utils, redfish_utils module utils - replace ``type()`` calls
- with ``isinstance()`` calls (https://github.com/ansible-collections/community.general/pull/7501).
- - pipx module utils - change the CLI argument formatter for the ``pip_args``
- parameter (https://github.com/ansible-collections/community.general/issues/7497,
- https://github.com/ansible-collections/community.general/pull/7506).
- release_summary: Bugfix release for inclusion in Ansible 9.0.0rc1.
- fragments:
- - 7501-type.yml
- - 7506-pipx-pipargs.yml
- - 8.0.2.yml
- release_date: '2023-11-13'
- 8.1.0:
- changes:
- bugfixes:
- - apt-rpm - the module did not upgrade packages if a newer version exists. Now
- the package will be reinstalled if the candidate is newer than the installed
- version (https://github.com/ansible-collections/community.general/issues/7414).
- - cloudflare_dns - fix Cloudflare lookup of SHFP records (https://github.com/ansible-collections/community.general/issues/7652).
+ - haproxy - fix an issue where HAProxy could get stuck in DRAIN mode when the
+ backend was unreachable (https://github.com/ansible-collections/community.general/issues/8092).
+ - homebrew - detect already installed formulae and casks using JSON output from
+ ``brew info`` (https://github.com/ansible-collections/community.general/issues/864).
+ - homebrew - error returned from brew command was ignored and tried to parse
+ empty JSON. Fix now checks for an error and raises it to give accurate error
+ message to users (https://github.com/ansible-collections/community.general/issues/8047).
+ - incus connection plugin - treats ``inventory_hostname`` as a variable instead
+ of a literal in remote connections (https://github.com/ansible-collections/community.general/issues/7874).
- interface_files - also consider ``address_family`` when changing ``option=method``
(https://github.com/ansible-collections/community.general/issues/7610, https://github.com/ansible-collections/community.general/pull/7612).
+ - inventory plugins - add unsafe wrapper to avoid marking strings that do not
+ contain ``{`` or ``}`` as unsafe, to work around a bug in AWX ((https://github.com/ansible-collections/community.general/issues/8212,
+ https://github.com/ansible-collections/community.general/pull/8225).
+ - ipa - fix get version regex in IPA module_utils (https://github.com/ansible-collections/community.general/pull/8175).
+ - ipa_hbacrule - the module uses a string for ``ipaenabledflag`` for new FreeIPA
+ versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
+ - ipa_otptoken - the module expect ``ipatokendisabled`` as string but the ``ipatokendisabled``
+ value is returned as a boolean (https://github.com/ansible-collections/community.general/pull/7795).
+ - ipa_sudorule - the module uses a string for ``ipaenabledflag`` for new FreeIPA
+ versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
+ - iptables_state - fix idempotency issues when restoring incomplete iptables
+ dumps (https://github.com/ansible-collections/community.general/issues/8029).
- irc - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code
for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
- keycloak_* - fix Keycloak API client to quote ``/`` properly (https://github.com/ansible-collections/community.general/pull/7641).
- keycloak_authz_permission - resource payload variable for scope-based permission
was constructed as a string, when it needs to be a list, even for a single
item (https://github.com/ansible-collections/community.general/issues/7151).
+ - keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes``
+ to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
+ - keycloak_client - fixes issue when metadata is provided in desired state when
+ task is in check mode (https://github.com/ansible-collections/community.general/issues/1226,
+ https://github.com/ansible-collections/community.general/pull/7881).
+ - keycloak_identity_provider - ``mappers`` processing was not idempotent if
+ the mappers configuration list had not been sorted by name (in ascending order).
+ Fix resolves the issue by sorting mappers in the desired state using the same
+ key which is used for obtaining existing state (https://github.com/ansible-collections/community.general/pull/7418).
+ - keycloak_identity_provider - it was not possible to reconfigure (add, remove)
+ ``mappers`` once they were created initially. Removal was ignored, adding
+ new ones resulted in dropping the pre-existing unmodified mappers. Fix resolves
+ the issue by supplying correct input to the internal update call (https://github.com/ansible-collections/community.general/pull/7418).
+ - keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales``
+ (https://github.com/ansible-collections/community.general/pull/8224).
+ - keycloak_user - when ``force`` is set, but user does not exist, do not try
+ to delete it (https://github.com/ansible-collections/community.general/pull/7696).
+ - keycloak_user_federation - fix diff of empty ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/8320).
+ - ldap - previously the order number (if present) was expected to follow an
+ equals sign in the DN. This makes it so the order number string is identified
+ correctly anywhere within the DN (https://github.com/ansible-collections/community.general/issues/7646).
+ - linode inventory plugin - add descriptive error message for linode inventory
+ plugin (https://github.com/ansible-collections/community.general/pull/8133).
- log_entries callback plugin - replace ``ssl.wrap_socket`` that was removed
from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
- lvol - test for output messages in both ``stdout`` and ``stderr`` (https://github.com/ansible-collections/community.general/pull/7601,
https://github.com/ansible-collections/community.general/issues/7182).
+ - 'merge_variables lookup plugin - fixing cross host merge: providing access
+ to foreign hosts variables to the perspective of the host that is performing
+ the merge (https://github.com/ansible-collections/community.general/pull/8303).'
+ - modprobe - listing modules files or modprobe files could trigger a FileNotFoundError
+ if ``/etc/modprobe.d`` or ``/etc/modules-load.d`` did not exist. Relevant
+ functions now return empty lists if the directories do not exist to avoid
+ crashing the module (https://github.com/ansible-collections/community.general/issues/7717).
+ - mssql_script - make the module work with Python 2 (https://github.com/ansible-collections/community.general/issues/7818,
+ https://github.com/ansible-collections/community.general/pull/7821).
+ - nmcli - fix ``connection.slave-type`` wired to ``bond`` and not with parameter
+ ``slave_type`` in case of connection type ``wifi`` (https://github.com/ansible-collections/community.general/issues/7389).
+ - ocapi_utils, oci_utils, redfish_utils module utils - replace ``type()`` calls
+ with ``isinstance()`` calls (https://github.com/ansible-collections/community.general/pull/7501).
+ - onepassword lookup plugin - failed for fields that were in sections and had
+ uppercase letters in the label/ID. Field lookups are now case insensitive
+ in all cases (https://github.com/ansible-collections/community.general/pull/7919).
- onepassword lookup plugin - field and section titles are now case insensitive
when using op CLI version two or later. This matches the behavior of version
one (https://github.com/ansible-collections/community.general/pull/7564).
+ - opentelemetry callback plugin - close spans always (https://github.com/ansible-collections/community.general/pull/8367).
+ - opentelemetry callback plugin - honour the ``disable_logs`` option to avoid
+ storing task results since they are not used regardless (https://github.com/ansible-collections/community.general/pull/8373).
+ - pacemaker_cluster - actually implement check mode, which the module claims
+ to support. This means that until now the module also did changes in check
+ mode (https://github.com/ansible-collections/community.general/pull/8081).
+ - pam_limits - when the file does not exist, do not create it in check mode
+ (https://github.com/ansible-collections/community.general/issues/8050, https://github.com/ansible-collections/community.general/pull/8057).
+ - pipx module utils - change the CLI argument formatter for the ``pip_args``
+ parameter (https://github.com/ansible-collections/community.general/issues/7497,
+ https://github.com/ansible-collections/community.general/pull/7506).
+ - pkgin - pkgin (pkgsrc package manager used by SmartOS) raises erratic exceptions
+ and spurious ``changed=true`` (https://github.com/ansible-collections/community.general/pull/7971).
+ - proxmox - fix updating a container config if the setting does not already
+ exist (https://github.com/ansible-collections/community.general/pull/7872).
+ - proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
+ - proxmox_kvm - running ``state=template`` will first check whether VM is already
+ a template (https://github.com/ansible-collections/community.general/pull/7792).
+ - proxmox_pool_member - absent state for type VM did not delete VMs from the
+ pools (https://github.com/ansible-collections/community.general/pull/7464).
+ - puppet - add option ``environment_lang`` to set the environment language encoding.
+ Defaults to lang ``C``. It is recommended to set it to ``C.UTF-8`` or ``en_US.UTF-8``
+ depending on what is available on your system. (https://github.com/ansible-collections/community.general/issues/8000)
+ - redfish_command - fix usage of message parsing in ``SimpleUpdate`` and ``MultipartHTTPPushUpdate``
+ commands to treat the lack of a ``MessageId`` as no message (https://github.com/ansible-collections/community.general/issues/7465,
+ https://github.com/ansible-collections/community.general/pull/7471).
+ - redfish_info - allow for a GET operation invoked by ``GetUpdateStatus`` to
+ allow for an empty response body for cases where a service returns 204 No
+ Content (https://github.com/ansible-collections/community.general/issues/8003).
+ - redfish_info - correct uncaught exception when attempting to retrieve ``Chassis``
+ information (https://github.com/ansible-collections/community.general/pull/7952).
- 'redhat_subscription - use the D-Bus registration on RHEL 7 only on 7.4 and
greater; older versions of RHEL 7 do not have it
@@ -854,12 +162,105 @@ releases:
https://github.com/ansible-collections/community.general/pull/7624).
'
+ - riak - support ``riak admin`` sub-command in newer Riak KV versions beside
+ the legacy ``riak-admin`` main command (https://github.com/ansible-collections/community.general/pull/8211).
+ - statusio_maintenance - fix error caused by incorrectly formed API data payload.
+ Was raising "Failed to create maintenance HTTP Error 400 Bad Request" caused
+ by bad data type for date/time and deprecated dict keys (https://github.com/ansible-collections/community.general/pull/7754).
- terraform - fix multiline string handling in complex variables (https://github.com/ansible-collections/community.general/pull/7535).
+ - to_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow
+ converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183,
+ https://github.com/ansible-collections/community.general/pull/8185).
+ - xml - make module work with lxml 5.1.1, which removed some internals that
+ the module was relying on (https://github.com/ansible-collections/community.general/pull/8169).
+ deprecated_features:
+ - MH DependencyCtxMgr module_utils - deprecate ``module_utils.mh.mixin.deps.DependencyCtxMgr``
+ in favour of ``module_utils.deps`` (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.AnsibleModule``
+ (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.DependencyCtxMgr``
+ (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.StateMixin``
+ (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarDict,``
+ (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarMeta``
+ (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarsMixin``
+ (https://github.com/ansible-collections/community.general/pull/8280).
+ - ModuleHelper module_utils - deprecate use of ``VarsMixin`` in favor of using
+ the ``VardDict`` module_utils (https://github.com/ansible-collections/community.general/pull/8226).
+ - ModuleHelper vars module_utils - bump deprecation of ``VarMeta``, ``VarDict``
+ and ``VarsMixin`` to version 11.0.0 (https://github.com/ansible-collections/community.general/pull/8226).
+ - apt_rpm - the behavior of ``state=present`` and ``state=installed`` is deprecated
+ and will change in community.general 11.0.0. Right now the module will upgrade
+ a package to the latest version if one of these two states is used. You should
+ explicitly use ``state=latest`` if you want this behavior, and switch to ``state=present_not_latest``
+ if you do not want to upgrade the package if it is already installed. In community.general
+ 11.0.0 the behavior of ``state=present`` and ``state=installed`` will change
+ to that of ``state=present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217,
+ https://github.com/ansible-collections/community.general/pull/8285).
+ - consul_acl - the module has been deprecated and will be removed in community.general
+ 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901).
+ - django_manage - the ``ack_venv_creation_deprecation`` option has no more effect
+ and will be removed from community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8198).
+ - gitlab modules - the basic auth method on GitLab API have been deprecated
+ and will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/8383).
+ - hipchat callback plugin - the hipchat service has been discontinued and the
+ self-hosted variant has been End of Life since 2020. The callback plugin is
+ therefore deprecated and will be removed from community.general 10.0.0 if
+ nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/issues/8184,
+ https://github.com/ansible-collections/community.general/pull/8189).
+ - irc - the defaults ``false`` for ``use_tls`` and ``validate_certs`` have been
+ deprecated and will change to ``true`` in community.general 10.0.0 to improve
+ security. You can already improve security now by explicitly setting them
+ to ``true``. Specifying values now disables the deprecation warning (https://github.com/ansible-collections/community.general/pull/7578).
minor_changes:
+ - PythonRunner module utils - specialisation of ``CmdRunner`` to execute Python
+ scripts (https://github.com/ansible-collections/community.general/pull/8289).
+ - Use offset-aware ``datetime.datetime`` objects (with timezone UTC) instead
+ of offset-naive UTC timestamps, which are deprecated in Python 3.12 (https://github.com/ansible-collections/community.general/pull/8222).
+ - aix_lvol - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - 'apt_rpm - add new states ``latest`` and ``present_not_latest``. The value
+ ``latest`` is equivalent to the current behavior of ``present``, which will
+ upgrade a package if a newer version exists. ``present_not_latest`` does what
+ most users would expect ``present`` to do: it does not upgrade if the package
+ is already installed. The current behavior of ``present`` will be deprecated
+ in a later version, and eventually changed to that of ``present_not_latest``
+ (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8247).'
+ - apt_rpm - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - bitwarden lookup plugin - add ``bw_session`` option, to pass session key instead
+ of reading from env (https://github.com/ansible-collections/community.general/pull/7994).
+ - bitwarden lookup plugin - add support to filter by organization ID (https://github.com/ansible-collections/community.general/pull/8188).
+ - bitwarden lookup plugin - allows to fetch all records of a given collection
+ ID, by allowing to pass an empty value for ``search_value`` when ``collection_id``
+ is provided (https://github.com/ansible-collections/community.general/pull/8013).
- bitwarden lookup plugin - when looking for items using an item ID, the item
is now accessed directly with ``bw get item`` instead of searching through
all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
+ - btrfs_subvolume - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - cmd_runner module_utils - add validation for minimum and maximum length in
+ the value passed to ``cmd_runner_fmt.as_list()`` (https://github.com/ansible-collections/community.general/pull/8288).
+ - consul_auth_method, consul_binding_rule, consul_policy, consul_role, consul_session,
+ consul_token - added action group ``community.general.consul`` (https://github.com/ansible-collections/community.general/pull/7897).
+ - consul_policy - added support for diff and check mode (https://github.com/ansible-collections/community.general/pull/7878).
+ - consul_policy, consul_role, consul_session - removed dependency on ``requests``
+ and factored out common parts (https://github.com/ansible-collections/community.general/pull/7826,
+ https://github.com/ansible-collections/community.general/pull/7878).
+ - consul_role - ``node_identities`` now expects a ``node_name`` option to match
+ the Consul API, the old ``name`` is still supported as alias (https://github.com/ansible-collections/community.general/pull/7878).
+ - consul_role - ``service_identities`` now expects a ``service_name`` option
+ to match the Consul API, the old ``name`` is still supported as alias (https://github.com/ansible-collections/community.general/pull/7878).
+ - consul_role - added support for diff mode (https://github.com/ansible-collections/community.general/pull/7878).
+ - consul_role - added support for templated policies (https://github.com/ansible-collections/community.general/pull/7878).
- elastic callback plugin - close elastic client to not leak resources (https://github.com/ansible-collections/community.general/pull/7517).
+ - filesystem - add bcachefs support (https://github.com/ansible-collections/community.general/pull/8126).
+ - gandi_livedns - adds support for personal access tokens (https://github.com/ansible-collections/community.general/issues/7639,
+ https://github.com/ansible-collections/community.general/pull/8337).
+ - gconftool2 - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
- git_config - allow multiple git configs for the same name with the new ``add_mode``
option (https://github.com/ansible-collections/community.general/pull/7260).
- git_config - the ``after`` and ``before`` fields in the ``diff`` of the return
@@ -869,9 +270,37 @@ releases:
(https://github.com/ansible-collections/community.general/pull/7260).
- gitlab modules - add ``ca_path`` option (https://github.com/ansible-collections/community.general/pull/7472).
- gitlab modules - remove duplicate ``gitlab`` package check (https://github.com/ansible-collections/community.general/pull/7486).
+ - gitlab_deploy_key, gitlab_group_members, gitlab_group_variable, gitlab_hook,
+ gitlab_instance_variable, gitlab_project_badge, gitlab_project_variable, gitlab_user
+ - improve API pagination and compatibility with different versions of ``python-gitlab``
+ (https://github.com/ansible-collections/community.general/pull/7790).
+ - gitlab_hook - adds ``releases_events`` parameter for supporting Releases events
+ triggers on GitLab hooks (https://github.com/ansible-collections/community.general/pull/7956).
- gitlab_runner - add support for new runner creation workflow (https://github.com/ansible-collections/community.general/pull/7199).
+ - homebrew - adds ``force_formula`` parameter to disambiguate a formula from
+ a cask of the same name (https://github.com/ansible-collections/community.general/issues/8274).
+ - homebrew, homebrew_cask - refactor common argument validation logic into a
+ dedicated ``homebrew`` module utils (https://github.com/ansible-collections/community.general/issues/8323,
+ https://github.com/ansible-collections/community.general/pull/8324).
+ - icinga2 inventory plugin - add Jinja2 templating support to ``url``, ``user``,
+ and ``password`` paramenters (https://github.com/ansible-collections/community.general/issues/7074,
+ https://github.com/ansible-collections/community.general/pull/7996).
+ - icinga2 inventory plugin - adds new parameter ``group_by_hostgroups`` in order
+ to make grouping by Icinga2 hostgroups optional (https://github.com/ansible-collections/community.general/pull/7998).
+ - ini_file - add an optional parameter ``section_has_values``. If the target
+ ini file contains more than one ``section``, use ``section_has_values`` to
+ specify which one should be updated (https://github.com/ansible-collections/community.general/pull/7505).
+ - ini_file - support optional spaces between section names and their surrounding
+ brackets (https://github.com/ansible-collections/community.general/pull/8075).
+ - installp - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- ipa_config - adds ``passkey`` choice to ``ipauserauthtype`` parameter's choices
(https://github.com/ansible-collections/community.general/pull/7588).
+ - ipa_dnsrecord - adds ability to manage NS record types (https://github.com/ansible-collections/community.general/pull/7737).
+ - ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with
+ a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
+ - ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``,
+ ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
- ipa_sudorule - adds options to include denied commands or command groups (https://github.com/ansible-collections/community.general/pull/7415).
- ipa_user - adds ``idp`` and ``passkey`` choice to ``ipauserauthtype`` parameter's
choices (https://github.com/ansible-collections/community.general/pull/7589).
@@ -880,26 +309,84 @@ releases:
is ``false`` for backwards compatibility. We recommend to every user of this
module to explicitly set ``use_tls=true`` and `validate_certs=true`` whenever
possible, especially when communicating to IRC servers over the internet (https://github.com/ansible-collections/community.general/pull/7550).
+ - java_cert - add ``cert_content`` argument (https://github.com/ansible-collections/community.general/pull/8153).
+ - java_cert - enable ``owner``, ``group``, ``mode``, and other generic file
+ arguments (https://github.com/ansible-collections/community.general/pull/8116).
+ - kernel_blacklist - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
- keycloak module utils - expose error message from Keycloak server for HTTP
errors in some specific situations (https://github.com/ansible-collections/community.general/pull/7645).
+ - keycloak_client, keycloak_clientscope, keycloak_clienttemplate - added ``docker-v2``
+ protocol support, enhancing alignment with Keycloak's protocol options (https://github.com/ansible-collections/community.general/issues/8215,
+ https://github.com/ansible-collections/community.general/pull/8216).
+ - keycloak_realm_key - the ``config.algorithm`` option now supports 8 additional
+ key algorithms (https://github.com/ansible-collections/community.general/pull/7698).
+ - keycloak_realm_key - the ``config.certificate`` option value is no longer
+ defined with ``no_log=True`` (https://github.com/ansible-collections/community.general/pull/7698).
+ - keycloak_realm_key - the ``provider_id`` option now supports RSA encryption
+ key usage (value ``rsa-enc``) (https://github.com/ansible-collections/community.general/pull/7698).
- keycloak_user_federation - add option for ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/7538).
+ - keycloak_user_federation - allow custom user storage providers to be set through
+ ``provider_id`` (https://github.com/ansible-collections/community.general/pull/7789).
+ - ldap_attrs - module now supports diff mode, showing which attributes are changed
+ within an operation (https://github.com/ansible-collections/community.general/pull/8073).
+ - lvg - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- lvol - change ``pvs`` argument type to list of strings (https://github.com/ansible-collections/community.general/pull/7676,
https://github.com/ansible-collections/community.general/issues/7504).
+ - lvol - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- 'lxd connection plugin - tighten the detection logic for lxd ``Instance not
found`` errors, to avoid false detection on unrelated errors such as ``/usr/bin/python3:
not found`` (https://github.com/ansible-collections/community.general/pull/7521).'
+ - lxd_container - uses ``/1.0/instances`` API endpoint, if available. Falls
+ back to ``/1.0/containers`` or ``/1.0/virtual-machines``. Fixes issue when
+ using Incus or LXD 5.19 due to migrating to ``/1.0/instances`` endpoint (https://github.com/ansible-collections/community.general/pull/7980).
+ - macports - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - mail - add ``Message-ID`` header; which is required by some mail servers (https://github.com/ansible-collections/community.general/pull/7740).
+ - mail module, mail callback plugin - allow to configure the domain name of
+ the Message-ID header with a new ``message_id_domain`` option (https://github.com/ansible-collections/community.general/pull/7765).
+ - mssql_script - adds transactional (rollback/commit) support via optional boolean
+ param ``transaction`` (https://github.com/ansible-collections/community.general/pull/7976).
- netcup_dns - adds support for record types ``OPENPGPKEY``, ``SMIMEA``, and
``SSHFP`` (https://github.com/ansible-collections/community.general/pull/7489).
- nmcli - add support for new connection type ``loopback`` (https://github.com/ansible-collections/community.general/issues/6572).
+ - nmcli - adds OpenvSwitch support with new ``type`` values ``ovs-port``, ``ovs-interface``,
+ and ``ovs-bridge``, and new ``slave_type`` value ``ovs-port`` (https://github.com/ansible-collections/community.general/pull/8154).
- nmcli - allow for ``infiniband`` slaves of ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7569).
- nmcli - allow for the setting of ``MTU`` for ``infiniband`` and ``bond`` interface
types (https://github.com/ansible-collections/community.general/pull/7499).
+ - nmcli - allow setting ``MTU`` for ``bond-slave`` interface types (https://github.com/ansible-collections/community.general/pull/8118).
- onepassword lookup plugin - support 1Password Connect with the opv2 client
by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116).
- onepassword_raw lookup plugin - support 1Password Connect with the opv2 client
by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116)
+ - opentelemetry - add support for HTTP trace_exporter and configures the behavior
+ via ``OTEL_EXPORTER_OTLP_TRACES_PROTOCOL`` (https://github.com/ansible-collections/community.general/issues/7888,
+ https://github.com/ansible-collections/community.general/pull/8321).
+ - opentelemetry - add support for exporting spans in a file via ``ANSIBLE_OPENTELEMETRY_STORE_SPANS_IN_FILE``
+ (https://github.com/ansible-collections/community.general/issues/7888, https://github.com/ansible-collections/community.general/pull/8363).
+ - opkg - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+ - osx_defaults - add option ``check_types`` to enable changing the type of existing
+ defaults on the fly (https://github.com/ansible-collections/community.general/pull/8173).
+ - parted - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- passwordstore - adds ``timestamp`` and ``preserve`` parameters to modify the
stored password format (https://github.com/ansible-collections/community.general/pull/7426).
+ - passwordstore lookup - add ``missing_subkey`` parameter defining the behavior
+ of the lookup when a passwordstore subkey is missing (https://github.com/ansible-collections/community.general/pull/8166).
+ - pipx - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+ - pkg5 - add support for non-silent execution (https://github.com/ansible-collections/community.general/issues/8379,
+ https://github.com/ansible-collections/community.general/pull/8382).
+ - pkgin - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - portage - adds the possibility to explicitely tell portage to write packages
+ to world file (https://github.com/ansible-collections/community.general/issues/6226,
+ https://github.com/ansible-collections/community.general/pull/8236).
+ - portinstall - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - proxmox - adds ``startup`` parameters to configure startup order, startup
+ delay and shutdown delay (https://github.com/ansible-collections/community.general/pull/8038).
- proxmox - adds ``template`` value to the ``state`` parameter, allowing conversion
of container to a template (https://github.com/ansible-collections/community.general/pull/7143).
- proxmox - adds ``update`` parameter, allowing update of an already existing
@@ -908,18 +395,98 @@ releases:
inventory generation. The new setting is optional, not using this option will
behave as usual (https://github.com/ansible-collections/community.general/issues/6714,
https://github.com/ansible-collections/community.general/pull/7461).
+ - proxmox* modules - there is now a ``community.general.proxmox`` module defaults
+ group that can be used to set default options for all Proxmox modules (https://github.com/ansible-collections/community.general/pull/8334).
- proxmox_disk - add ability to manipulate CD-ROM drive (https://github.com/ansible-collections/community.general/pull/7495).
+ - proxmox_kvm - add parameter ``update_unsafe`` to avoid limitations when updating
+ dangerous values (https://github.com/ansible-collections/community.general/pull/7843).
- proxmox_kvm - adds ``template`` value to the ``state`` parameter, allowing
conversion of a VM to a template (https://github.com/ansible-collections/community.general/pull/7143).
+ - proxmox_kvm - adds``usb`` parameter for setting USB devices on proxmox KVM
+ VMs (https://github.com/ansible-collections/community.general/pull/8199).
- proxmox_kvm - support the ``hookscript`` parameter (https://github.com/ansible-collections/community.general/issues/7600).
- proxmox_ostype - it is now possible to specify the ``ostype`` when creating
an LXC container (https://github.com/ansible-collections/community.general/pull/7462).
- proxmox_vm_info - add ability to retrieve configuration info (https://github.com/ansible-collections/community.general/pull/7485).
+ - puppet - new feature to set ``--waitforlock`` option (https://github.com/ansible-collections/community.general/pull/8282).
+ - redfish_command - add command ``ResetToDefaults`` to reset manager to default
+ state (https://github.com/ansible-collections/community.general/issues/8163).
+ - redfish_config - add command ``SetServiceIdentification`` to set service identification
+ (https://github.com/ansible-collections/community.general/issues/7916).
+ - redfish_info - add boolean return value ``MultipartHttpPush`` to ``GetFirmwareUpdateCapabilities``
+ (https://github.com/ansible-collections/community.general/issues/8194, https://github.com/ansible-collections/community.general/pull/8195).
+ - redfish_info - add command ``GetServiceIdentification`` to get service identification
+ (https://github.com/ansible-collections/community.general/issues/7882).
- redfish_info - adding the ``BootProgress`` property when getting ``Systems``
info (https://github.com/ansible-collections/community.general/pull/7626).
+ - revbitspss lookup plugin - removed a redundant unicode prefix. The prefix
+ was not necessary for Python 3 and has been cleaned up to streamline the code
+ (https://github.com/ansible-collections/community.general/pull/8087).
+ - rundeck module utils - allow to pass ``Content-Type`` to API requests (https://github.com/ansible-collections/community.general/pull/7684).
+ - slackpkg - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
- ssh_config - adds ``controlmaster``, ``controlpath`` and ``controlpersist``
parameters (https://github.com/ansible-collections/community.general/pull/7456).
- release_summary: Regular bugfix and feature release.
+ - ssh_config - allow ``accept-new`` as valid value for ``strict_host_key_checking``
+ (https://github.com/ansible-collections/community.general/pull/8257).
+ - ssh_config - new feature to set ``AddKeysToAgent`` option to ``yes`` or ``no``
+ (https://github.com/ansible-collections/community.general/pull/7703).
+ - ssh_config - new feature to set ``IdentitiesOnly`` option to ``yes`` or ``no``
+ (https://github.com/ansible-collections/community.general/pull/7704).
+ - sudoers - add support for the ``NOEXEC`` tag in sudoers rules (https://github.com/ansible-collections/community.general/pull/7983).
+ - svr4pkg - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - swdepot - refactor module to pass list of arguments to ``module.run_command()``
+ instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
+ - terraform - add support for ``diff_mode`` for terraform resource_changes (https://github.com/ansible-collections/community.general/pull/7896).
+ - terraform - fix ``diff_mode`` in state ``absent`` and when terraform ``resource_changes``
+ does not exist (https://github.com/ansible-collections/community.general/pull/7963).
+ - xcc_redfish_command - added support for raw POSTs (``command=PostResource``
+ in ``category=Raw``) without a specific action info (https://github.com/ansible-collections/community.general/pull/7746).
+ - xfconf - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+ - xfconf_info - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
+ release_summary: This is release 9.0.0 of ``community.general``, released on
+ 2024-05-20.
+ removed_features:
+ - The deprecated redirects for internal module names have been removed. These
+ internal redirects were extra-long FQCNs like ``community.general.packaging.os.apt_rpm``
+ that redirect to the short FQCN ``community.general.apt_rpm``. They were originally
+ needed to implement flatmapping; as various tooling started to recommend users
+ to use the long names flatmapping was removed from the collection and redirects
+ were added for users who already followed these incorrect recommendations
+ (https://github.com/ansible-collections/community.general/pull/7835).
+ - ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211``
+ options have been removed. They no longer had any effect (https://github.com/ansible-collections/community.general/pull/8198).
+ - cloudflare_dns - remove support for SPF records. These are no longer supported
+ by CloudFlare (https://github.com/ansible-collections/community.general/pull/7782).
+ - django_manage - support for the ``command`` values ``cleanup``, ``syncdb``,
+ and ``validate`` were removed. Use ``clearsessions``, ``migrate``, and ``check``
+ instead, respectively (https://github.com/ansible-collections/community.general/pull/8198).
+ - flowdock - this module relied on HTTPS APIs that do not exist anymore and
+ was thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+ - mh.mixins.deps module utils - the ``DependencyMixin`` has been removed. Use
+ the ``deps`` module utils instead (https://github.com/ansible-collections/community.general/pull/8198).
+ - proxmox - the ``proxmox_default_behavior`` option has been removed (https://github.com/ansible-collections/community.general/pull/8198).
+ - rax* modules, rax module utils, rax docs fragment - the Rackspace modules
+ relied on the deprecated package ``pyrax`` and were thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+ - redhat module utils - the classes ``Rhsm``, ``RhsmPool``, and ``RhsmPools``
+ have been removed (https://github.com/ansible-collections/community.general/pull/8198).
+ - redhat_subscription - the alias ``autosubscribe`` of the ``auto_attach`` option
+ was removed (https://github.com/ansible-collections/community.general/pull/8198).
+ - stackdriver - this module relied on HTTPS APIs that do not exist anymore and
+ was thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+ - webfaction_* modules - these modules relied on HTTPS APIs that do not exist
+ anymore and were thus removed (https://github.com/ansible-collections/community.general/pull/8198).
+ security_fixes:
+ - cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox,
+ scaleway, stackpath_compute, virtualbox, and xen_orchestra inventory plugin
+ - make sure all data received from the remote servers is marked as unsafe,
+ so remote code execution by obtaining texts that can be evaluated as templates
+ is not possible (https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/,
+ https://github.com/ansible-collections/community.general/pull/8098).
+ - keycloak_identity_provider - the client secret was not correctly sanitized
+ by the module. The return values ``proposed``, ``existing``, and ``end_state``,
+ as well as the diff, did contain the client secret unmasked (https://github.com/ansible-collections/community.general/pull/8355).
fragments:
- 000-redhat_subscription-dbus-on-7.4-plus.yaml
- 5588-support-1password-connect.yml
@@ -928,25 +495,34 @@ releases:
- 7151-fix-keycloak_authz_permission-incorrect-resource-payload.yml
- 7199-gitlab-runner-new-creation-workflow.yml
- 7242-multi-values-for-same-name-in-git-config.yml
+ - 7389-nmcli-issue-with-creating-a-wifi-bridge-slave.yml
+ - 7418-kc_identity_provider-mapper-reconfiguration-fixes.yml
- 7426-add-timestamp-and-preserve-options-for-passwordstore.yaml
- 7456-add-ssh-control-master.yml
- 7461-proxmox-inventory-add-exclude-nodes.yaml
- 7462-Add-ostype-parameter-in-LXC-container-clone-of-ProxmoxVE.yaml
+ - 7464-fix-vm-removal-in-proxmox_pool_member.yml
+ - 7465-redfish-firmware-update-message-id-hardening.yml
+ - 7467-fix-gitlab-constants-calls.yml
- 7472-gitlab-add-ca-path-option.yml
- 7485-proxmox_vm_info-config.yml
- 7486-gitlab-refactor-package-check.yml
- 7489-netcup-dns-record-types.yml
- 7495-proxmox_disk-manipulate-cdrom.yml
- 7499-allow-mtu-setting-on-bond-and-infiniband-interfaces.yml
+ - 7501-type.yml
+ - 7505-ini_file-section_has.yml
+ - 7506-pipx-pipargs.yml
- 7517-elastic-close-client.yaml
- 7535-terraform-fix-multiline-string-handling-in-complex-variables.yml
- 7538-add-krbprincipalattribute-option.yml
- - 7540-proxmox-update config.yml
+ - 7540-proxmox-update-config.yml
- 7542-irc-logentries-ssl.yml
- 7550-irc-use_tls-validate_certs.yml
- 7564-onepassword-lookup-case-insensitive.yaml
- 7569-infiniband-slave-support.yml
- 7577-fix-apt_rpm-module.yml
+ - 7578-irc-tls.yml
- 7588-ipa-config-new-choice-passkey-to-ipauserauthtype.yml
- 7589-ipa-config-new-choices-idp-and-passkey-to-ipauserauthtype.yml
- 7600-proxmox_kvm-hookscript.yml
@@ -955,257 +531,43 @@ releases:
- 7626-redfish-info-add-boot-progress-property.yml
- 7641-fix-keycloak-api-client-to-quote-properly.yml
- 7645-Keycloak-print-error-msg-from-server.yml
+ - 7646-fix-order-number-detection-in-dn.yml
- 7653-fix-cloudflare-lookup.yml
- 7676-lvol-pvs-as-list.yml
- - 8.1.0.yml
- - add-ipa-sudorule-deny-cmd.yml
- - bitwarden-lookup-performance.yaml
- - lxd-instance-not-found-avoid-false-positives.yml
- modules:
- - description: Read git configuration
- name: git_config_info
- namespace: ''
- - description: Create, update, or delete GitLab issues
- name: gitlab_issue
- namespace: ''
- - description: Manage Nomad ACL tokens
- name: nomad_token
- namespace: ''
- plugins:
- lookup:
- - description: Fetch documents stored in 1Password
- name: onepassword_doc
- namespace: null
- test:
- - description: Validates fully-qualified domain names against RFC 1123
- name: fqdn_valid
- namespace: null
- release_date: '2023-12-04'
- 8.2.0:
- changes:
- bugfixes:
- - keycloak_identity_provider - ``mappers`` processing was not idempotent if
- the mappers configuration list had not been sorted by name (in ascending order).
- Fix resolves the issue by sorting mappers in the desired state using the same
- key which is used for obtaining existing state (https://github.com/ansible-collections/community.general/pull/7418).
- - keycloak_identity_provider - it was not possible to reconfigure (add, remove)
- ``mappers`` once they were created initially. Removal was ignored, adding
- new ones resulted in dropping the pre-existing unmodified mappers. Fix resolves
- the issue by supplying correct input to the internal update call (https://github.com/ansible-collections/community.general/pull/7418).
- - keycloak_user - when ``force`` is set, but user does not exist, do not try
- to delete it (https://github.com/ansible-collections/community.general/pull/7696).
- - proxmox_kvm - running ``state=template`` will first check whether VM is already
- a template (https://github.com/ansible-collections/community.general/pull/7792).
- - statusio_maintenance - fix error caused by incorrectly formed API data payload.
- Was raising "Failed to create maintenance HTTP Error 400 Bad Request" caused
- by bad data type for date/time and deprecated dict keys (https://github.com/ansible-collections/community.general/pull/7754).
- minor_changes:
- - ipa_dnsrecord - adds ability to manage NS record types (https://github.com/ansible-collections/community.general/pull/7737).
- - ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with
- a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
- - ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``,
- ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
- - keycloak_realm_key - the ``config.algorithm`` option now supports 8 additional
- key algorithms (https://github.com/ansible-collections/community.general/pull/7698).
- - keycloak_realm_key - the ``config.certificate`` option value is no longer
- defined with ``no_log=True`` (https://github.com/ansible-collections/community.general/pull/7698).
- - keycloak_realm_key - the ``provider_id`` option now supports RSA encryption
- key usage (value ``rsa-enc``) (https://github.com/ansible-collections/community.general/pull/7698).
- - keycloak_user_federation - allow custom user storage providers to be set through
- ``provider_id`` (https://github.com/ansible-collections/community.general/pull/7789).
- - mail - add ``Message-ID`` header; which is required by some mail servers (https://github.com/ansible-collections/community.general/pull/7740).
- - mail module, mail callback plugin - allow to configure the domain name of
- the Message-ID header with a new ``message_id_domain`` option (https://github.com/ansible-collections/community.general/pull/7765).
- - ssh_config - new feature to set ``AddKeysToAgent`` option to ``yes`` or ``no``
- (https://github.com/ansible-collections/community.general/pull/7703).
- - ssh_config - new feature to set ``IdentitiesOnly`` option to ``yes`` or ``no``
- (https://github.com/ansible-collections/community.general/pull/7704).
- - xcc_redfish_command - added support for raw POSTs (``command=PostResource``
- in ``category=Raw``) without a specific action info (https://github.com/ansible-collections/community.general/pull/7746).
- release_summary: Regular bugfix and feature release.
- fragments:
- - 7418-kc_identity_provider-mapper-reconfiguration-fixes.yml
+ - 7683-added-contenttype-parameter.yml
- 7696-avoid-attempt-to-delete-non-existing-user.yml
- 7698-improvements-to-keycloak_realm_key.yml
- 7703-ssh_config_add_keys_to_agent_option.yml
- 7704-ssh_config_identities_only_option.yml
+ - 7717-prevent-modprobe-error.yml
- 7723-ipa-pwpolicy-update-pwpolicy-module.yml
- 7737-add-ipa-dnsrecord-ns-type.yml
- 7740-add-message-id-header-to-mail-module.yml
- 7746-raw_post-without-actions.yml
- 7754-fixed-payload-format.yml
- 7765-mail-message-id.yml
+ - 7782-cloudflare_dns-spf.yml
- 7789-keycloak-user-federation-custom-provider-type.yml
+ - 7790-gitlab-runner-api-pagination.yml
- 7791-proxmox_kvm-state-template-will-check-status-first.yaml
- - 8.2.0.yml
- modules:
- - description: Enable or disable dnf repositories using config-manager
- name: dnf_config_manager
- namespace: ''
- - description: Retrive component info in Keycloak
- name: keycloak_component_info
- namespace: ''
- - description: Allows administration of Keycloak realm role mappings into groups
- with the Keycloak API
- name: keycloak_realm_rolemapping
- namespace: ''
- - description: Retrieve information about one or more Proxmox VE nodes
- name: proxmox_node_info
- namespace: ''
- - description: List content from a Proxmox VE storage
- name: proxmox_storage_contents_info
- namespace: ''
- plugins:
- connection:
- - description: Run tasks in Incus instances via the Incus CLI.
- name: incus
- namespace: null
- filter:
- - description: Converts INI text input into a dictionary
- name: from_ini
- namespace: null
- - description: Converts a dictionary to the INI file format
- name: to_ini
- namespace: null
- lookup:
- - description: Obtain short-lived Github App Access tokens
- name: github_app_access_token
- namespace: null
- release_date: '2024-01-01'
- 8.3.0:
- changes:
- bugfixes:
- - homebrew - detect already installed formulae and casks using JSON output from
- ``brew info`` (https://github.com/ansible-collections/community.general/issues/864).
- - incus connection plugin - treats ``inventory_hostname`` as a variable instead
- of a literal in remote connections (https://github.com/ansible-collections/community.general/issues/7874).
- - ipa_otptoken - the module expect ``ipatokendisabled`` as string but the ``ipatokendisabled``
- value is returned as a boolean (https://github.com/ansible-collections/community.general/pull/7795).
- - ldap - previously the order number (if present) was expected to follow an
- equals sign in the DN. This makes it so the order number string is identified
- correctly anywhere within the DN (https://github.com/ansible-collections/community.general/issues/7646).
- - mssql_script - make the module work with Python 2 (https://github.com/ansible-collections/community.general/issues/7818,
- https://github.com/ansible-collections/community.general/pull/7821).
- - nmcli - fix ``connection.slave-type`` wired to ``bond`` and not with parameter
- ``slave_type`` in case of connection type ``wifi`` (https://github.com/ansible-collections/community.general/issues/7389).
- - proxmox - fix updating a container config if the setting does not already
- exist (https://github.com/ansible-collections/community.general/pull/7872).
- deprecated_features:
- - consul_acl - the module has been deprecated and will be removed in community.general
- 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901).
- minor_changes:
- - consul_auth_method, consul_binding_rule, consul_policy, consul_role, consul_session,
- consul_token - added action group ``community.general.consul`` (https://github.com/ansible-collections/community.general/pull/7897).
- - consul_policy - added support for diff and check mode (https://github.com/ansible-collections/community.general/pull/7878).
- - consul_policy, consul_role, consul_session - removed dependency on ``requests``
- and factored out common parts (https://github.com/ansible-collections/community.general/pull/7826,
- https://github.com/ansible-collections/community.general/pull/7878).
- - consul_role - ``node_identities`` now expects a ``node_name`` option to match
- the Consul API, the old ``name`` is still supported as alias (https://github.com/ansible-collections/community.general/pull/7878).
- - consul_role - ``service_identities`` now expects a ``service_name`` option
- to match the Consul API, the old ``name`` is still supported as alias (https://github.com/ansible-collections/community.general/pull/7878).
- - consul_role - added support for diff mode (https://github.com/ansible-collections/community.general/pull/7878).
- - consul_role - added support for templated policies (https://github.com/ansible-collections/community.general/pull/7878).
- - redfish_info - add command ``GetServiceIdentification`` to get service identification
- (https://github.com/ansible-collections/community.general/issues/7882).
- - terraform - add support for ``diff_mode`` for terraform resource_changes (https://github.com/ansible-collections/community.general/pull/7896).
- release_summary: Regular bugfix and feature release.
- fragments:
- - 7389-nmcli-issue-with-creating-a-wifi-bridge-slave.yml
- - 7646-fix-order-number-detection-in-dn.yml
- 7797-ipa-fix-otp-idempotency.yml
- 7821-mssql_script-py2.yml
- 7826-consul-modules-refactoring.yaml
+ - 7843-proxmox_kvm-update_unsafe.yml
+ - 7847-gitlab-issue-title.yml
- 7870-homebrew-cask-installed-detection.yml
- 7872-proxmox_fix-update-if-setting-doesnt-exist.yaml
- 7874-incus_connection_treats_inventory_hostname_as_literal_in_remotes.yml
+ - 7880-ipa-fix-sudo-and-hbcalrule-idempotence.yml
+ - 7881-fix-keycloak-client-ckeckmode.yml
- 7882-add-redfish-get-service-identification.yml
- 7896-add-terraform-diff-mode.yml
- 7897-consul-action-group.yaml
- 7901-consul-acl-deprecation.yaml
- - 8.3.0.yml
- modules:
- - description: Bootstrap ACLs in Consul
- name: consul_acl_bootstrap
- namespace: ''
- - description: Manipulate Consul auth methods
- name: consul_auth_method
- namespace: ''
- - description: Manipulate Consul binding rules
- name: consul_binding_rule
- namespace: ''
- - description: Manipulate Consul tokens
- name: consul_token
- namespace: ''
- - description: Creates/updates/deletes GitLab Labels belonging to project or group.
- name: gitlab_label
- namespace: ''
- - description: Creates/updates/deletes GitLab Milestones belonging to project
- or group
- name: gitlab_milestone
- namespace: ''
- release_date: '2024-01-29'
- 8.4.0:
- changes:
- bugfixes:
- - 'cargo - fix idempotency issues when using a custom installation path for
- packages (using the ``--path`` parameter). The initial installation runs fine,
- but subsequent runs use the ``get_installed()`` function which did not check
- the given installation location, before running ``cargo install``. This resulted
- in a false ``changed`` state. Also the removal of packeges using ``state:
- absent`` failed, as the installation check did not use the given parameter
- (https://github.com/ansible-collections/community.general/pull/7970).'
- - gitlab_issue - fix behavior to search GitLab issue, using ``search`` keyword
- instead of ``title`` (https://github.com/ansible-collections/community.general/issues/7846).
- - gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
- - keycloak_client - fixes issue when metadata is provided in desired state when
- task is in check mode (https://github.com/ansible-collections/community.general/issues/1226,
- https://github.com/ansible-collections/community.general/pull/7881).
- - modprobe - listing modules files or modprobe files could trigger a FileNotFoundError
- if ``/etc/modprobe.d`` or ``/etc/modules-load.d`` did not exist. Relevant
- functions now return empty lists if the directories do not exist to avoid
- crashing the module (https://github.com/ansible-collections/community.general/issues/7717).
- - onepassword lookup plugin - failed for fields that were in sections and had
- uppercase letters in the label/ID. Field lookups are now case insensitive
- in all cases (https://github.com/ansible-collections/community.general/pull/7919).
- - pkgin - pkgin (pkgsrc package manager used by SmartOS) raises erratic exceptions
- and spurious ``changed=true`` (https://github.com/ansible-collections/community.general/pull/7971).
- - redfish_info - allow for a GET operation invoked by ``GetUpdateStatus`` to
- allow for an empty response body for cases where a service returns 204 No
- Content (https://github.com/ansible-collections/community.general/issues/8003).
- - redfish_info - correct uncaught exception when attempting to retrieve ``Chassis``
- information (https://github.com/ansible-collections/community.general/pull/7952).
- minor_changes:
- - bitwarden lookup plugin - add ``bw_session`` option, to pass session key instead
- of reading from env (https://github.com/ansible-collections/community.general/pull/7994).
- - gitlab_deploy_key, gitlab_group_members, gitlab_group_variable, gitlab_hook,
- gitlab_instance_variable, gitlab_project_badge, gitlab_project_variable, gitlab_user
- - improve API pagination and compatibility with different versions of ``python-gitlab``
- (https://github.com/ansible-collections/community.general/pull/7790).
- - gitlab_hook - adds ``releases_events`` parameter for supporting Releases events
- triggers on GitLab hooks (https://github.com/ansible-collections/community.general/pull/7956).
- - icinga2 inventory plugin - add Jinja2 templating support to ``url``, ``user``,
- and ``password`` paramenters (https://github.com/ansible-collections/community.general/issues/7074,
- https://github.com/ansible-collections/community.general/pull/7996).
- - mssql_script - adds transactional (rollback/commit) support via optional boolean
- param ``transaction`` (https://github.com/ansible-collections/community.general/pull/7976).
- - proxmox_kvm - add parameter ``update_unsafe`` to avoid limitations when updating
- dangerous values (https://github.com/ansible-collections/community.general/pull/7843).
- - redfish_config - add command ``SetServiceIdentification`` to set service identification
- (https://github.com/ansible-collections/community.general/issues/7916).
- - sudoers - add support for the ``NOEXEC`` tag in sudoers rules (https://github.com/ansible-collections/community.general/pull/7983).
- - terraform - fix ``diff_mode`` in state ``absent`` and when terraform ``resource_changes``
- does not exist (https://github.com/ansible-collections/community.general/pull/7963).
- release_summary: Regular bugfix and feature release.
- fragments:
- - 7717-prevent-modprobe-error.yml
- - 7790-gitlab-runner-api-pagination.yml
- - 7843-proxmox_kvm-update_unsafe.yml
- - 7847-gitlab-issue-title.yml
- - 7881-fix-keycloak-client-ckeckmode.yml
- 7916-add-redfish-set-service-identification.yml
- 7919-onepassword-fieldname-casing.yaml
- 7951-fix-redfish_info-exception.yml
+ - 7953-proxmox_kvm-fix_status_check.yml
- 7956-adding-releases_events-option-to-gitlab_hook-module.yaml
- 7963-fix-terraform-diff-absent.yml
- 7970-fix-cargo-path-idempotency.yaml
@@ -1213,92 +575,8 @@ releases:
- 7983-sudoers-add-support-noexec.yml
- 7994-bitwarden-session-arg.yaml
- 7996-add-templating-support-to-icinga2-inventory.yml
- - 8.4.0.yml
- - 8003-redfish-get-update-status-empty-response.yml
- - pkgin.yml
- modules:
- - description: Manages GitLab group access tokens
- name: gitlab_group_access_token
- namespace: ''
- - description: Manages GitLab project access tokens
- name: gitlab_project_access_token
- namespace: ''
- plugins:
- callback:
- - description: The default ansible callback without diff output
- name: default_without_diff
- namespace: null
- filter:
- - description: Difference of lists with a predictive order
- name: lists_difference
- namespace: null
- - description: Intersection of lists with a predictive order
- name: lists_intersect
- namespace: null
- - description: Symmetric Difference of lists with a predictive order
- name: lists_symmetric_difference
- namespace: null
- - description: Union of lists with a predictive order
- name: lists_union
- namespace: null
- release_date: '2024-02-26'
- 8.5.0:
- changes:
- bugfixes:
- - aix_filesystem - fix issue with empty list items in crfs logic and option
- order (https://github.com/ansible-collections/community.general/pull/8052).
- - consul_token - fix token creation without ``accessor_id`` (https://github.com/ansible-collections/community.general/pull/8091).
- - homebrew - error returned from brew command was ignored and tried to parse
- empty JSON. Fix now checks for an error and raises it to give accurate error
- message to users (https://github.com/ansible-collections/community.general/issues/8047).
- - ipa_hbacrule - the module uses a string for ``ipaenabledflag`` for new FreeIPA
- versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
- - ipa_sudorule - the module uses a string for ``ipaenabledflag`` for new FreeIPA
- versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
- - iptables_state - fix idempotency issues when restoring incomplete iptables
- dumps (https://github.com/ansible-collections/community.general/issues/8029).
- - linode inventory plugin - add descriptive error message for linode inventory
- plugin (https://github.com/ansible-collections/community.general/pull/8133).
- - pacemaker_cluster - actually implement check mode, which the module claims
- to support. This means that until now the module also did changes in check
- mode (https://github.com/ansible-collections/community.general/pull/8081).
- - pam_limits - when the file does not exist, do not create it in check mode
- (https://github.com/ansible-collections/community.general/issues/8050, https://github.com/ansible-collections/community.general/pull/8057).
- - proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
- minor_changes:
- - bitwarden lookup plugin - allows to fetch all records of a given collection
- ID, by allowing to pass an empty value for ``search_value`` when ``collection_id``
- is provided (https://github.com/ansible-collections/community.general/pull/8013).
- - icinga2 inventory plugin - adds new parameter ``group_by_hostgroups`` in order
- to make grouping by Icinga2 hostgroups optional (https://github.com/ansible-collections/community.general/pull/7998).
- - ini_file - support optional spaces between section names and their surrounding
- brackets (https://github.com/ansible-collections/community.general/pull/8075).
- - java_cert - enable ``owner``, ``group``, ``mode``, and other generic file
- arguments (https://github.com/ansible-collections/community.general/pull/8116).
- - ldap_attrs - module now supports diff mode, showing which attributes are changed
- within an operation (https://github.com/ansible-collections/community.general/pull/8073).
- - lxd_container - uses ``/1.0/instances`` API endpoint, if available. Falls
- back to ``/1.0/containers`` or ``/1.0/virtual-machines``. Fixes issue when
- using Incus or LXD 5.19 due to migrating to ``/1.0/instances`` endpoint (https://github.com/ansible-collections/community.general/pull/7980).
- - nmcli - allow setting ``MTU`` for ``bond-slave`` interface types (https://github.com/ansible-collections/community.general/pull/8118).
- - proxmox - adds ``startup`` parameters to configure startup order, startup
- delay and shutdown delay (https://github.com/ansible-collections/community.general/pull/8038).
- - revbitspss lookup plugin - removed a redundant unicode prefix. The prefix
- was not necessary for Python 3 and has been cleaned up to streamline the code
- (https://github.com/ansible-collections/community.general/pull/8087).
- release_summary: Regular feature and bugfix release with security fixes.
- security_fixes:
- - cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox,
- scaleway, stackpath_compute, virtualbox, and xen_orchestra inventory plugin
- - make sure all data received from the remote servers is marked as unsafe,
- so remote code execution by obtaining texts that can be evaluated as templates
- is not possible (https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/,
- https://github.com/ansible-collections/community.general/pull/8098).
- fragments:
- - 7880-ipa-fix-sudo-and-hbcalrule-idempotence.yml
- - 7953-proxmox_kvm-fix_status_check.yml
- 7998-icinga2-inventory-group_by_hostgroups-parameter.yml
- - 8.5.0.yml
+ - 8003-redfish-get-update-status-empty-response.yml
- 8013-bitwarden-full-collection-item-list.yaml
- 8029-iptables-state-restore-check-mode.yml
- 8038-proxmox-startup.yml
@@ -1308,99 +586,11 @@ releases:
- 8075-optional-space-around-section-names.yaml
- 8087-removed-redundant-unicode-prefixes.yml
- 8091-consul-token-fixes.yaml
+ - 8100-haproxy-drain-fails-on-down-backend.yml
- 8116-java_cert-enable-owner-group-mode-args.yml
- 8118-fix-bond-slave-honoring-mtu.yml
- - 8133-add-error-message-for-linode-inventory-plugin.yaml
- - aix_filesystem-crfs-issue.yml
- - inventory-rce.yml
- - lxd-instances-api-endpoint-added.yml
- - pacemaker-cluster.yml
- modules:
- - description: Allows listing information about USB devices
- name: usb_facts
- namespace: ''
- release_date: '2024-03-25'
- 8.6.0:
- changes:
- bugfixes:
- - aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd``
- (https://github.com/ansible-collections/community.general/issues/8151).
- - apt_rpm - when checking whether packages were installed after running ``apt-get
- -y install <packages>``, only the last package name was checked (https://github.com/ansible-collections/community.general/pull/8263).
- - bitwarden_secrets_manager lookup plugin - implements retry with exponential
- backoff to avoid lookup errors when Bitwardn's API rate limiting is encountered
- (https://github.com/ansible-collections/community.general/issues/8230, https://github.com/ansible-collections/community.general/pull/8238).
- - from_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow
- converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183,
- https://github.com/ansible-collections/community.general/pull/8185).
- - gitlab_issue, gitlab_label, gitlab_milestone - avoid crash during version
- comparison when the python-gitlab Python module is not installed (https://github.com/ansible-collections/community.general/pull/8158).
- - haproxy - fix an issue where HAProxy could get stuck in DRAIN mode when the
- backend was unreachable (https://github.com/ansible-collections/community.general/issues/8092).
- - inventory plugins - add unsafe wrapper to avoid marking strings that do not
- contain ``{`` or ``}`` as unsafe, to work around a bug in AWX ((https://github.com/ansible-collections/community.general/issues/8212,
- https://github.com/ansible-collections/community.general/pull/8225).
- - ipa - fix get version regex in IPA module_utils (https://github.com/ansible-collections/community.general/pull/8175).
- - keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes``
- to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
- - keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales``
- (https://github.com/ansible-collections/community.general/pull/8224).
- - puppet - add option ``environment_lang`` to set the environment language encoding.
- Defaults to lang ``C``. It is recommended to set it to ``C.UTF-8`` or ``en_US.UTF-8``
- depending on what is available on your system. (https://github.com/ansible-collections/community.general/issues/8000)
- - riak - support ``riak admin`` sub-command in newer Riak KV versions beside
- the legacy ``riak-admin`` main command (https://github.com/ansible-collections/community.general/pull/8211).
- - to_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow
- converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183,
- https://github.com/ansible-collections/community.general/pull/8185).
- - xml - make module work with lxml 5.1.1, which removed some internals that
- the module was relying on (https://github.com/ansible-collections/community.general/pull/8169).
- deprecated_features:
- - hipchat callback plugin - the hipchat service has been discontinued and the
- self-hosted variant has been End of Life since 2020. The callback plugin is
- therefore deprecated and will be removed from community.general 10.0.0 if
- nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/issues/8184,
- https://github.com/ansible-collections/community.general/pull/8189).
- minor_changes:
- - Use offset-aware ``datetime.datetime`` objects (with timezone UTC) instead
- of offset-naive UTC timestamps, which are deprecated in Python 3.12 (https://github.com/ansible-collections/community.general/pull/8222).
- - 'apt_rpm - add new states ``latest`` and ``present_not_latest``. The value
- ``latest`` is equivalent to the current behavior of ``present``, which will
- upgrade a package if a newer version exists. ``present_not_latest`` does what
- most users would expect ``present`` to do: it does not upgrade if the package
- is already installed. The current behavior of ``present`` will be deprecated
- in a later version, and eventually changed to that of ``present_not_latest``
- (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8247).'
- - bitwarden lookup plugin - add support to filter by organization ID (https://github.com/ansible-collections/community.general/pull/8188).
- - filesystem - add bcachefs support (https://github.com/ansible-collections/community.general/pull/8126).
- - ini_file - add an optional parameter ``section_has_values``. If the target
- ini file contains more than one ``section``, use ``section_has_values`` to
- specify which one should be updated (https://github.com/ansible-collections/community.general/pull/7505).
- - java_cert - add ``cert_content`` argument (https://github.com/ansible-collections/community.general/pull/8153).
- - keycloak_client, keycloak_clientscope, keycloak_clienttemplate - added ``docker-v2``
- protocol support, enhancing alignment with Keycloak's protocol options (https://github.com/ansible-collections/community.general/issues/8215,
- https://github.com/ansible-collections/community.general/pull/8216).
- - nmcli - adds OpenvSwitch support with new ``type`` values ``ovs-port``, ``ovs-interface``,
- and ``ovs-bridge``, and new ``slave_type`` value ``ovs-port`` (https://github.com/ansible-collections/community.general/pull/8154).
- - osx_defaults - add option ``check_types`` to enable changing the type of existing
- defaults on the fly (https://github.com/ansible-collections/community.general/pull/8173).
- - passwordstore lookup - add ``missing_subkey`` parameter defining the behavior
- of the lookup when a passwordstore subkey is missing (https://github.com/ansible-collections/community.general/pull/8166).
- - portage - adds the possibility to explicitely tell portage to write packages
- to world file (https://github.com/ansible-collections/community.general/issues/6226,
- https://github.com/ansible-collections/community.general/pull/8236).
- - redfish_command - add command ``ResetToDefaults`` to reset manager to default
- state (https://github.com/ansible-collections/community.general/issues/8163).
- - redfish_info - add boolean return value ``MultipartHttpPush`` to ``GetFirmwareUpdateCapabilities``
- (https://github.com/ansible-collections/community.general/issues/8194, https://github.com/ansible-collections/community.general/pull/8195).
- - ssh_config - allow ``accept-new`` as valid value for ``strict_host_key_checking``
- (https://github.com/ansible-collections/community.general/pull/8257).
- release_summary: Regular bugfix and features release.
- fragments:
- - 7505-ini_file-section_has.yml
- - 8.6.0.yml
- - 8100-haproxy-drain-fails-on-down-backend.yml
- 8126-filesystem-bcachefs-support.yaml
+ - 8133-add-error-message-for-linode-inventory-plugin.yaml
- 8151-fix-lsvg_cmd-failed.yml
- 8153-java_cert-add-cert_content-arg.yml
- 8154-add-ovs-commands-to-nmcli-module.yml
@@ -1413,22 +603,194 @@ releases:
- 8183-from_ini_to_ini.yml
- 8188-bitwarden-add-organization_id.yml
- 8194-redfish-add-multipart-to-capabilities.yml
+ - 8199-added-usb-support-to-proxmox-module.yml
- 8211-riak-admin-sub-command-support.yml
- 8215-add-docker-v2-protocol.yml
- 8222-datetime.yml
- 8223-keycloak_client-additional-normalizations.yaml
- 8224-keycloak_realm-add-normalizations.yaml
- 8225-unsafe.yml
+ - 8226-mh-vardict.yml
- 8236-portage-select-feature.yml
- 8238-bitwarden-secrets-manager-rate-limit-retry-with-backoff.yml
- 8247-apt_rpm-latest.yml
- 8257-ssh-config-hostkey-support-accept-new.yaml
- 8263-apt_rpm-install-check.yml
+ - 8264-run_command.yml
+ - 8274-homebrew-force-formula.yml
+ - 8280-mh-deprecations.yml
+ - 8281-puppet-waitforlock.yaml
+ - 8285-apt_rpm-state-deprecate.yml
+ - 8288-cmdrunner-fmt-list-len-limits.yml
+ - 8289-python-runner.yml
+ - 8290-gandi-livedns-personal-access-token.yml
+ - 8303-fix-rendering-foreign-variables.yaml
+ - 8320-keycloak_user_federation-fix-diff-krbPrincipalAttribute.yaml
+ - 8321-fix-opentelemetry-callback.yml
+ - 8323-refactor-homebrew-logic-module-utils.yml
+ - 8334-proxmox-action-group.yml
+ - 8355-keycloak-idp-sanitize.yaml
+ - 8363-opentelemetry-export-to-a-file.yml
+ - 8367-fix-close-span-if-no-logs.yaml
+ - 8373-honour-disable-logs.yaml
+ - 8379-verbose-mode-pkg5.yml
+ - 8383-deprecate-gitlab-basic-auth.yml
+ - 9.0.0.yml
+ - add-ipa-sudorule-deny-cmd.yml
+ - aix_filesystem-crfs-issue.yml
+ - bitwarden-lookup-performance.yaml
- hipchat.yml
+ - internal-redirects.yml
+ - inventory-rce.yml
+ - lxd-instance-not-found-avoid-false-positives.yml
+ - lxd-instances-api-endpoint-added.yml
+ - pacemaker-cluster.yml
+ - pkgin.yml
- puppet_lang_force.yml
+ - remove_deprecated.yml
modules:
+ - description: Bootstrap ACLs in Consul.
+ name: consul_acl_bootstrap
+ namespace: ''
+ - description: Manipulate Consul auth methods.
+ name: consul_auth_method
+ namespace: ''
+ - description: Manipulate Consul binding rules.
+ name: consul_binding_rule
+ namespace: ''
+ - description: Manipulate Consul tokens.
+ name: consul_token
+ namespace: ''
+ - description: Run Django admin commands.
+ name: django_command
+ namespace: ''
+ - description: Enable or disable dnf repositories using config-manager.
+ name: dnf_config_manager
+ namespace: ''
+ - description: Read git configuration.
+ name: git_config_info
+ namespace: ''
+ - description: Manages GitLab group access tokens.
+ name: gitlab_group_access_token
+ namespace: ''
+ - description: Create, update, or delete GitLab issues.
+ name: gitlab_issue
+ namespace: ''
+ - description: Creates/updates/deletes GitLab Labels belonging to project or group.
+ name: gitlab_label
+ namespace: ''
+ - description: Creates/updates/deletes GitLab Milestones belonging to project
+ or group.
+ name: gitlab_milestone
+ namespace: ''
+ - description: Manages GitLab project access tokens.
+ name: gitlab_project_access_token
+ namespace: ''
- description: Allows administration of Keycloak client roles scope to restrict
the usage of certain roles to a other specific client applications.
name: keycloak_client_rolescope
namespace: ''
- release_date: '2024-04-22'
+ - description: Retrive component info in Keycloak.
+ name: keycloak_component_info
+ namespace: ''
+ - description: Allows administration of Keycloak realm role mappings into groups
+ with the Keycloak API.
+ name: keycloak_realm_rolemapping
+ namespace: ''
+ - description: Manage Nomad ACL tokens.
+ name: nomad_token
+ namespace: ''
+ - description: Retrieve information about one or more Proxmox VE nodes.
+ name: proxmox_node_info
+ namespace: ''
+ - description: List content from a Proxmox VE storage.
+ name: proxmox_storage_contents_info
+ namespace: ''
+ - description: Allows listing information about USB devices.
+ name: usb_facts
+ namespace: ''
+ plugins:
+ become:
+ - description: Systemd's run0.
+ name: run0
+ namespace: null
+ callback:
+ - description: The default ansible callback without diff output.
+ name: default_without_diff
+ namespace: null
+ - description: Adds simple timestamp for each header.
+ name: timestamp
+ namespace: null
+ connection:
+ - description: Run tasks in Incus instances via the Incus CLI.
+ name: incus
+ namespace: null
+ filter:
+ - description: Converts INI text input into a dictionary.
+ name: from_ini
+ namespace: null
+ - description: Difference of lists with a predictive order.
+ name: lists_difference
+ namespace: null
+ - description: Intersection of lists with a predictive order.
+ name: lists_intersect
+ namespace: null
+ - description: Symmetric Difference of lists with a predictive order.
+ name: lists_symmetric_difference
+ namespace: null
+ - description: Union of lists with a predictive order.
+ name: lists_union
+ namespace: null
+ - description: Converts a dictionary to the INI file format.
+ name: to_ini
+ namespace: null
+ lookup:
+ - description: Obtain short-lived Github App Access tokens.
+ name: github_app_access_token
+ namespace: null
+ - description: Fetch documents stored in 1Password.
+ name: onepassword_doc
+ namespace: null
+ test:
+ - description: Validates fully-qualified domain names against RFC 1123.
+ name: fqdn_valid
+ namespace: null
+ release_date: '2024-05-20'
+ 9.0.1:
+ changes:
+ bugfixes:
+ - cpanm - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - django module utils - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - gconftool2_info - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - homebrew - do not fail when brew prints warnings (https://github.com/ansible-collections/community.general/pull/8406,
+ https://github.com/ansible-collections/community.general/issues/7044).
+ - hponcfg - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - kernel_blacklist - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - keycloak_client - fix TypeError when sanitizing the ``saml.signing.private.key``
+ attribute in the module's diff or state output. The ``sanitize_cr`` function
+ expected a dict where in some cases a list might occur (https://github.com/ansible-collections/community.general/pull/8403).
+ - locale_gen - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - mksysb - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - pipx_info - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - snap - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ - snap_alias - use new ``VarDict`` to prevent deprecation warning (https://github.com/ansible-collections/community.general/issues/8410,
+ https://github.com/ansible-collections/community.general/pull/8411).
+ minor_changes:
+ - ansible_galaxy_install - minor refactor in the module (https://github.com/ansible-collections/community.general/pull/8413).
+ release_summary: Bugfix release for inclusion in Ansible 10.0.0rc1.
+ fragments:
+ - 8403-fix-typeerror-in-keycloak-client.yaml
+ - 8406-fix-homebrew-cask-warning.yaml
+ - 8411-locale-gen-vardict.yml
+ - 8413-galaxy-refactor.yml
+ - 9.0.1.yml
+ release_date: '2024-05-27'
diff --git a/ansible_collections/community/general/changelogs/config.yaml b/ansible_collections/community/general/changelogs/config.yaml
index 23afe36d2..2cef6e26f 100644
--- a/ansible_collections/community/general/changelogs/config.yaml
+++ b/ansible_collections/community/general/changelogs/config.yaml
@@ -35,3 +35,6 @@ sections:
- - known_issues
- Known Issues
title: Community General
+trivial_section_name: trivial
+use_fqcn: true
+add_plugin_period: true
diff --git a/ansible_collections/community/general/meta/runtime.yml b/ansible_collections/community/general/meta/runtime.yml
index a9354aab3..edeb53005 100644
--- a/ansible_collections/community/general/meta/runtime.yml
+++ b/ansible_collections/community/general/meta/runtime.yml
@@ -12,6 +12,23 @@ action_groups:
- consul_role
- consul_session
- consul_token
+ proxmox:
+ - proxmox
+ - proxmox_disk
+ - proxmox_domain_info
+ - proxmox_group_info
+ - proxmox_kvm
+ - proxmox_nic
+ - proxmox_node_info
+ - proxmox_pool
+ - proxmox_pool_member
+ - proxmox_snap
+ - proxmox_storage_contents_info
+ - proxmox_storage_info
+ - proxmox_tasks_info
+ - proxmox_template
+ - proxmox_user_info
+ - proxmox_vm_info
plugin_routing:
callback:
actionable:
@@ -57,109 +74,109 @@ plugin_routing:
removal_version: 10.0.0
warning_text: Use community.general.consul_token and/or community.general.consul_policy instead.
rax_cbs_attachments:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_cbs:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_cdb_database:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_cdb_user:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_cdb:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_clb_nodes:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_clb_ssl:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_clb:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_dns_record:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_dns:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_facts:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_files_objects:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_files:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_identity:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_keypair:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_meta:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_mon_alarm:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_mon_check:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_mon_entity:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_mon_notification_plan:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_mon_notification:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_network:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_queue:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_scaling_group:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rax_scaling_policy:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on the deprecated package pyrax.
+ warning_text: This module relied on the deprecated package pyrax.
rhn_channel:
deprecation:
removal_version: 10.0.0
@@ -170,543 +187,18 @@ plugin_routing:
removal_version: 10.0.0
warning_text: RHN is EOL, please contact the community.general maintainers
if still using this; see the module documentation for more details.
- database.aerospike.aerospike_migrations:
- redirect: community.general.aerospike_migrations
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.aerospike_migrations
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.airbrake_deployment:
- redirect: community.general.airbrake_deployment
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.airbrake_deployment
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
stackdriver:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore,
+ warning_text: This module relied on HTTPS APIs that do not exist anymore,
and any new development in the direction of providing an alternative should
happen in the context of the google.cloud collection.
- system.aix_devices:
- redirect: community.general.aix_devices
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.aix_devices
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.aix_filesystem:
- redirect: community.general.aix_filesystem
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.aix_filesystem
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.aix_inittab:
- redirect: community.general.aix_inittab
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.aix_inittab
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.aix_lvg:
- redirect: community.general.aix_lvg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.aix_lvg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.aix_lvol:
- redirect: community.general.aix_lvol
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.aix_lvol
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.alerta_customer:
- redirect: community.general.alerta_customer
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.alerta_customer
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.alicloud.ali_instance:
- redirect: community.general.ali_instance
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ali_instance
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
ali_instance_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.ali_instance_info instead.
- cloud.alicloud.ali_instance_info:
- redirect: community.general.ali_instance_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ali_instance_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.alternatives:
- redirect: community.general.alternatives
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.alternatives
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.ansible_galaxy_install:
- redirect: community.general.ansible_galaxy_install
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ansible_galaxy_install
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.apache2_mod_proxy:
- redirect: community.general.apache2_mod_proxy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.apache2_mod_proxy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.apache2_module:
- redirect: community.general.apache2_module
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.apache2_module
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.apk:
- redirect: community.general.apk
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.apk
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.apt_repo:
- redirect: community.general.apt_repo
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.apt_repo
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.apt_rpm:
- redirect: community.general.apt_rpm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.apt_rpm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.archive:
- redirect: community.general.archive
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.archive
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.atomic.atomic_container:
- redirect: community.general.atomic_container
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.atomic_container
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.atomic.atomic_host:
- redirect: community.general.atomic_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.atomic_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.atomic.atomic_image:
- redirect: community.general.atomic_image
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.atomic_image
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.awall:
- redirect: community.general.awall
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.awall
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.beadm:
- redirect: community.general.beadm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.beadm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.bearychat:
- redirect: community.general.bearychat
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bearychat
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.bigpanda:
- redirect: community.general.bigpanda
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bigpanda
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.bitbucket.bitbucket_access_key:
- redirect: community.general.bitbucket_access_key
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bitbucket_access_key
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.bitbucket.bitbucket_pipeline_key_pair:
- redirect: community.general.bitbucket_pipeline_key_pair
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bitbucket_pipeline_key_pair
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.bitbucket.bitbucket_pipeline_known_host:
- redirect: community.general.bitbucket_pipeline_known_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bitbucket_pipeline_known_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.bitbucket.bitbucket_pipeline_variable:
- redirect: community.general.bitbucket_pipeline_variable
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bitbucket_pipeline_variable
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.bower:
- redirect: community.general.bower
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bower
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.bundler:
- redirect: community.general.bundler
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bundler
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.bzr:
- redirect: community.general.bzr
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.bzr
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.campfire:
- redirect: community.general.campfire
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.campfire
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.capabilities:
- redirect: community.general.capabilities
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.capabilities
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.cargo:
- redirect: community.general.cargo
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cargo
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.catapult:
- redirect: community.general.catapult
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.catapult
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.circonus_annotation:
- redirect: community.general.circonus_annotation
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.circonus_annotation
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
cisco_spark:
redirect: community.general.cisco_webex
- notification.cisco_spark:
- redirect: community.general.cisco_webex
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cisco_webex
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.cisco_webex:
- redirect: community.general.cisco_webex
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cisco_webex
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_aa_policy:
- redirect: community.general.clc_aa_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_aa_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_alert_policy:
- redirect: community.general.clc_alert_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_alert_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_blueprint_package:
- redirect: community.general.clc_blueprint_package
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_blueprint_package
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_firewall_policy:
- redirect: community.general.clc_firewall_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_firewall_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_group:
- redirect: community.general.clc_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_loadbalancer:
- redirect: community.general.clc_loadbalancer
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_loadbalancer
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_modify_server:
- redirect: community.general.clc_modify_server
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_modify_server
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_publicip:
- redirect: community.general.clc_publicip
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_publicip
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_server:
- redirect: community.general.clc_server
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_server
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.centurylink.clc_server_snapshot:
- redirect: community.general.clc_server_snapshot
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.clc_server_snapshot
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.cloud_init_data_facts:
- redirect: community.general.cloud_init_data_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cloud_init_data_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.cloudflare_dns:
- redirect: community.general.cloudflare_dns
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cloudflare_dns
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.cobbler.cobbler_sync:
- redirect: community.general.cobbler_sync
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cobbler_sync
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.cobbler.cobbler_system:
- redirect: community.general.cobbler_system
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cobbler_system
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.composer:
- redirect: community.general.composer
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.composer
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.consul.consul:
- redirect: community.general.consul
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.consul
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.consul.consul_acl:
- redirect: community.general.consul_acl
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.consul_acl
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.consul.consul_kv:
- redirect: community.general.consul_kv
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.consul_kv
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.consul.consul_session:
- redirect: community.general.consul_session
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.consul_session
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.copr:
- redirect: community.general.copr
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.copr
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.cpanm:
- redirect: community.general.cpanm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cpanm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.cronvar:
- redirect: community.general.cronvar
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.cronvar
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.crypttab:
- redirect: community.general.crypttab
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.crypttab
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.datadog.datadog_downtime:
- redirect: community.general.datadog_downtime
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.datadog_downtime
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.datadog.datadog_event:
- redirect: community.general.datadog_event
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.datadog_event
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.datadog.datadog_monitor:
- redirect: community.general.datadog_monitor
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.datadog_monitor
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.dconf:
- redirect: community.general.dconf
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dconf
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.deploy_helper:
- redirect: community.general.deploy_helper
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.deploy_helper
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.dimensiondata.dimensiondata_network:
- redirect: community.general.dimensiondata_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dimensiondata_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.dimensiondata.dimensiondata_vlan:
- redirect: community.general.dimensiondata_vlan
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dimensiondata_vlan
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.discord:
- redirect: community.general.discord
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.discord
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.django_manage:
- redirect: community.general.django_manage
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.django_manage
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.dnf_versionlock:
- redirect: community.general.dnf_versionlock
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dnf_versionlock
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.dnsimple:
- redirect: community.general.dnsimple
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dnsimple
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.dnsimple_info:
- redirect: community.general.dnsimple_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dnsimple_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.dnsmadeeasy:
- redirect: community.general.dnsmadeeasy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dnsmadeeasy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
docker_compose:
redirect: community.docker.docker_compose
docker_config:
@@ -761,106 +253,15 @@ plugin_routing:
redirect: community.docker.docker_volume
docker_volume_info:
redirect: community.docker.docker_volume_info
- system.dpkg_divert:
- redirect: community.general.dpkg_divert
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.dpkg_divert
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.easy_install:
- redirect: community.general.easy_install
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.easy_install
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.ejabberd_user:
- redirect: community.general.ejabberd_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ejabberd_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.elasticsearch_plugin:
- redirect: community.general.elasticsearch_plugin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.elasticsearch_plugin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.emc.emc_vnx_sg_member:
- redirect: community.general.emc_vnx_sg_member
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.emc_vnx_sg_member
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.etcd3:
- redirect: community.general.etcd3
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.etcd3
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.facter:
- redirect: community.general.facter
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.facter
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.filesize:
- redirect: community.general.filesize
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.filesize
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.filesystem:
- redirect: community.general.filesystem
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.filesystem
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.flatpak:
- redirect: community.general.flatpak
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.flatpak
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.flatpak_remote:
- redirect: community.general.flatpak_remote
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.flatpak_remote
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
flowdock:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore and
+ warning_text: This module relied on HTTPS APIs that do not exist anymore and
there is no clear path to update.
- notification.flowdock:
- redirect: community.general.flowdock
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.flowdock
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
foreman:
tombstone:
removal_version: 2.0.0
warning_text: Use the modules from the theforeman.foreman collection instead.
- net_tools.gandi_livedns:
- redirect: community.general.gandi_livedns
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gandi_livedns
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
gc_storage:
redirect: community.google.gc_storage
gcdns_record:
@@ -895,20 +296,6 @@ plugin_routing:
redirect: community.google.gce_snapshot
gce_tag:
redirect: community.google.gce_tag
- system.gconftool2:
- redirect: community.general.gconftool2
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gconftool2
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.gconftool2_info:
- redirect: community.general.gconftool2_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gconftool2_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
gcp_backend_service:
tombstone:
removal_version: 2.0.0
@@ -944,193 +331,11 @@ plugin_routing:
removal_version: 2.0.0
warning_text: Use google.cloud.gcp_spanner_database and/or google.cloud.gcp_spanner_instance
instead.
- packaging.language.gem:
- redirect: community.general.gem
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gem
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.git_config:
- redirect: community.general.git_config
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.git_config
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.github.github_deploy_key:
- redirect: community.general.github_deploy_key
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_deploy_key
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
github_hooks:
tombstone:
removal_version: 2.0.0
warning_text: Use community.general.github_webhook and community.general.github_webhook_info
instead.
- source_control.github.github_issue:
- redirect: community.general.github_issue
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_issue
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.github.github_key:
- redirect: community.general.github_key
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_key
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.github.github_release:
- redirect: community.general.github_release
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_release
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.github.github_repo:
- redirect: community.general.github_repo
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_repo
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.github.github_webhook:
- redirect: community.general.github_webhook
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_webhook
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.github.github_webhook_info:
- redirect: community.general.github_webhook_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.github_webhook_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_branch:
- redirect: community.general.gitlab_branch
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_branch
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_deploy_key:
- redirect: community.general.gitlab_deploy_key
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_deploy_key
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_group:
- redirect: community.general.gitlab_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_group_members:
- redirect: community.general.gitlab_group_members
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_group_members
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_group_variable:
- redirect: community.general.gitlab_group_variable
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_group_variable
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_hook:
- redirect: community.general.gitlab_hook
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_hook
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_project:
- redirect: community.general.gitlab_project
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_project
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_project_members:
- redirect: community.general.gitlab_project_members
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_project_members
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_project_variable:
- redirect: community.general.gitlab_project_variable
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_project_variable
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_protected_branch:
- redirect: community.general.gitlab_protected_branch
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_protected_branch
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_runner:
- redirect: community.general.gitlab_runner
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_runner
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- source_control.gitlab.gitlab_user:
- redirect: community.general.gitlab_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gitlab_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.grove:
- redirect: community.general.grove
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.grove
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.gunicorn:
- redirect: community.general.gunicorn
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.gunicorn
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.saphana.hana_query:
- redirect: community.general.hana_query
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hana_query
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.haproxy:
- redirect: community.general.haproxy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.haproxy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.heroku.heroku_collaborator:
- redirect: community.general.heroku_collaborator
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.heroku_collaborator
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
hana_query:
redirect: community.sap_libs.sap_hdbsql
hetzner_failover_ip:
@@ -1141,740 +346,26 @@ plugin_routing:
redirect: community.hrobot.firewall
hetzner_firewall_info:
redirect: community.hrobot.firewall_info
- source_control.hg:
- redirect: community.general.hg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.hipchat:
- redirect: community.general.hipchat
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hipchat
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.homebrew:
- redirect: community.general.homebrew
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.homebrew
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.homebrew_cask:
- redirect: community.general.homebrew_cask
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.homebrew_cask
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.homebrew_tap:
- redirect: community.general.homebrew_tap
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.homebrew_tap
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.homectl:
- redirect: community.general.homectl
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.homectl
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.honeybadger_deployment:
- redirect: community.general.honeybadger_deployment
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.honeybadger_deployment
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.hpilo.hpilo_boot:
- redirect: community.general.hpilo_boot
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hpilo_boot
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
hpilo_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.hpilo_info instead.
- remote_management.hpilo.hpilo_info:
- redirect: community.general.hpilo_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hpilo_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.hpilo.hponcfg:
- redirect: community.general.hponcfg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hponcfg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.htpasswd:
- redirect: community.general.htpasswd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.htpasswd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_ecs_instance:
- redirect: community.general.hwc_ecs_instance
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_ecs_instance
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_evs_disk:
- redirect: community.general.hwc_evs_disk
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_evs_disk
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_network_vpc:
- redirect: community.general.hwc_network_vpc
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_network_vpc
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_smn_topic:
- redirect: community.general.hwc_smn_topic
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_smn_topic
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_eip:
- redirect: community.general.hwc_vpc_eip
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_eip
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_peering_connect:
- redirect: community.general.hwc_vpc_peering_connect
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_peering_connect
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_port:
- redirect: community.general.hwc_vpc_port
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_port
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_private_ip:
- redirect: community.general.hwc_vpc_private_ip
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_private_ip
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_route:
- redirect: community.general.hwc_vpc_route
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_route
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_security_group:
- redirect: community.general.hwc_vpc_security_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_security_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_security_group_rule:
- redirect: community.general.hwc_vpc_security_group_rule
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_security_group_rule
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.huawei.hwc_vpc_subnet:
- redirect: community.general.hwc_vpc_subnet
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.hwc_vpc_subnet
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.ibm.ibm_sa_domain:
- redirect: community.general.ibm_sa_domain
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ibm_sa_domain
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.ibm.ibm_sa_host:
- redirect: community.general.ibm_sa_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ibm_sa_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.ibm.ibm_sa_host_ports:
- redirect: community.general.ibm_sa_host_ports
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ibm_sa_host_ports
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.ibm.ibm_sa_pool:
- redirect: community.general.ibm_sa_pool
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ibm_sa_pool
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.ibm.ibm_sa_vol:
- redirect: community.general.ibm_sa_vol
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ibm_sa_vol
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.ibm.ibm_sa_vol_map:
- redirect: community.general.ibm_sa_vol_map
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ibm_sa_vol_map
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.icinga2_feature:
- redirect: community.general.icinga2_feature
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.icinga2_feature
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.icinga2_host:
- redirect: community.general.icinga2_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.icinga2_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
idrac_firmware:
redirect: dellemc.openmanage.idrac_firmware
- remote_management.redfish.idrac_redfish_command:
- redirect: community.general.idrac_redfish_command
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.idrac_redfish_command
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.redfish.idrac_redfish_config:
- redirect: community.general.idrac_redfish_config
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.idrac_redfish_config
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
idrac_redfish_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.idrac_redfish_info instead.
- remote_management.redfish.idrac_redfish_info:
- redirect: community.general.idrac_redfish_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.idrac_redfish_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
idrac_server_config_profile:
redirect: dellemc.openmanage.idrac_server_config_profile
- remote_management.redfish.ilo_redfish_config:
- redirect: community.general.ilo_redfish_config
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ilo_redfish_config
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.redfish.ilo_redfish_info:
- redirect: community.general.ilo_redfish_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ilo_redfish_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.imc.imc_rest:
- redirect: community.general.imc_rest
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.imc_rest
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.smartos.imgadm:
- redirect: community.general.imgadm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.imgadm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.infinity.infinity:
- redirect: community.general.infinity
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.infinity
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.influxdb.influxdb_database:
- redirect: community.general.influxdb_database
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.influxdb_database
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.influxdb.influxdb_query:
- redirect: community.general.influxdb_query
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.influxdb_query
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.influxdb.influxdb_retention_policy:
- redirect: community.general.influxdb_retention_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.influxdb_retention_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.influxdb.influxdb_user:
- redirect: community.general.influxdb_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.influxdb_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.influxdb.influxdb_write:
- redirect: community.general.influxdb_write
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.influxdb_write
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.ini_file:
- redirect: community.general.ini_file
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ini_file
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.installp:
- redirect: community.general.installp
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.installp
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.interfaces_file:
- redirect: community.general.interfaces_file
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.interfaces_file
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ip_netns:
- redirect: community.general.ip_netns
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ip_netns
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_config:
- redirect: community.general.ipa_config
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_config
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_dnsrecord:
- redirect: community.general.ipa_dnsrecord
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_dnsrecord
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_dnszone:
- redirect: community.general.ipa_dnszone
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_dnszone
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_group:
- redirect: community.general.ipa_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_hbacrule:
- redirect: community.general.ipa_hbacrule
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_hbacrule
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_host:
- redirect: community.general.ipa_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_hostgroup:
- redirect: community.general.ipa_hostgroup
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_hostgroup
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_otpconfig:
- redirect: community.general.ipa_otpconfig
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_otpconfig
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_otptoken:
- redirect: community.general.ipa_otptoken
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_otptoken
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_pwpolicy:
- redirect: community.general.ipa_pwpolicy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_pwpolicy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_role:
- redirect: community.general.ipa_role
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_role
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_service:
- redirect: community.general.ipa_service
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_service
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_subca:
- redirect: community.general.ipa_subca
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_subca
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_sudocmd:
- redirect: community.general.ipa_sudocmd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_sudocmd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_sudocmdgroup:
- redirect: community.general.ipa_sudocmdgroup
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_sudocmdgroup
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_sudorule:
- redirect: community.general.ipa_sudorule
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_sudorule
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_user:
- redirect: community.general.ipa_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.ipa.ipa_vault:
- redirect: community.general.ipa_vault
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipa_vault
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ipify_facts:
- redirect: community.general.ipify_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipify_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ipinfoio_facts:
- redirect: community.general.ipinfoio_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipinfoio_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.ipmi.ipmi_boot:
- redirect: community.general.ipmi_boot
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipmi_boot
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.ipmi.ipmi_power:
- redirect: community.general.ipmi_power
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipmi_power
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.iptables_state:
- redirect: community.general.iptables_state
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.iptables_state
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ipwcli_dns:
- redirect: community.general.ipwcli_dns
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ipwcli_dns
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.irc:
- redirect: community.general.irc
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.irc
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.iso_create:
- redirect: community.general.iso_create
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.iso_create
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.iso_extract:
- redirect: community.general.iso_extract
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.iso_extract
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.iso_customize:
- redirect: community.general.iso_customize
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.iso_customize
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.jabber:
- redirect: community.general.jabber
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jabber
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.java_cert:
- redirect: community.general.java_cert
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.java_cert
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.java_keystore:
- redirect: community.general.java_keystore
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.java_keystore
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.jboss:
- redirect: community.general.jboss
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jboss
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.jenkins_build:
- redirect: community.general.jenkins_build
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jenkins_build
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.jenkins_job:
- redirect: community.general.jenkins_job
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jenkins_job
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
jenkins_job_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.jenkins_job_info instead.
- web_infrastructure.jenkins_job_info:
- redirect: community.general.jenkins_job_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jenkins_job_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.jenkins_plugin:
- redirect: community.general.jenkins_plugin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jenkins_plugin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.jenkins_script:
- redirect: community.general.jenkins_script
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jenkins_script
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.jira:
- redirect: community.general.jira
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.jira
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
katello:
tombstone:
removal_version: 2.0.0
warning_text: Use the modules from the theforeman.foreman collection instead.
- system.kernel_blacklist:
- redirect: community.general.kernel_blacklist
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.kernel_blacklist
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_authentication:
- redirect: community.general.keycloak_authentication
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_authentication
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_client:
- redirect: community.general.keycloak_client
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_client
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_client_rolemapping:
- redirect: community.general.keycloak_client_rolemapping
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_client_rolemapping
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_clientscope:
- redirect: community.general.keycloak_clientscope
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_clientscope
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_clienttemplate:
- redirect: community.general.keycloak_clienttemplate
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_clienttemplate
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_group:
- redirect: community.general.keycloak_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_identity_provider:
- redirect: community.general.keycloak_identity_provider
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_identity_provider
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_realm:
- redirect: community.general.keycloak_realm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_realm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_realm_info:
- redirect: community.general.keycloak_realm_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_realm_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_role:
- redirect: community.general.keycloak_role
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_role
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_user_federation:
- redirect: community.general.keycloak_user_federation
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_user_federation
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.keycloak.keycloak_user_rolemapping:
- redirect: community.general.keycloak_user_rolemapping
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keycloak_user_rolemapping
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.keyring:
- redirect: community.general.keyring
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keyring
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.keyring_info:
- redirect: community.general.keyring_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.keyring_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.kibana_plugin:
- redirect: community.general.kibana_plugin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.kibana_plugin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
kubevirt_cdi_upload:
redirect: community.kubevirt.kubevirt_cdi_upload
kubevirt_preset:
@@ -1887,115 +378,10 @@ plugin_routing:
redirect: community.kubevirt.kubevirt_template
kubevirt_vm:
redirect: community.kubevirt.kubevirt_vm
- system.launchd:
- redirect: community.general.launchd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.launchd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.layman:
- redirect: community.general.layman
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.layman
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.lbu:
- redirect: community.general.lbu
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lbu
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
ldap_attr:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.ldap_attrs instead.
- net_tools.ldap.ldap_attrs:
- redirect: community.general.ldap_attrs
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ldap_attrs
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ldap.ldap_entry:
- redirect: community.general.ldap_entry
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ldap_entry
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ldap.ldap_passwd:
- redirect: community.general.ldap_passwd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ldap_passwd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.ldap.ldap_search:
- redirect: community.general.ldap_search
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ldap_search
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.librato_annotation:
- redirect: community.general.librato_annotation
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.librato_annotation
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.linode.linode:
- redirect: community.general.linode
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.linode
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.linode.linode_v4:
- redirect: community.general.linode_v4
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.linode_v4
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.listen_ports_facts:
- redirect: community.general.listen_ports_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.listen_ports_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.lldp:
- redirect: community.general.lldp
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lldp
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.locale_gen:
- redirect: community.general.locale_gen
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.locale_gen
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.logentries:
- redirect: community.general.logentries
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.logentries
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.logentries_msg:
- redirect: community.general.logentries_msg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.logentries_msg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
logicmonitor:
tombstone:
removal_version: 1.0.0
@@ -2006,280 +392,14 @@ plugin_routing:
removal_version: 1.0.0
warning_text: The logicmonitor_facts module is no longer maintained and the
API used has been disabled in 2017.
- monitoring.logstash_plugin:
- redirect: community.general.logstash_plugin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.logstash_plugin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.lvg:
- redirect: community.general.lvg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lvg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.lvol:
- redirect: community.general.lvol
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lvol
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.lxc.lxc_container:
- redirect: community.general.lxc_container
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lxc_container
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.lxca.lxca_cmms:
- redirect: community.general.lxca_cmms
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lxca_cmms
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.lxca.lxca_nodes:
- redirect: community.general.lxca_nodes
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lxca_nodes
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.lxd.lxd_container:
- redirect: community.general.lxd_container
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lxd_container
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.lxd.lxd_profile:
- redirect: community.general.lxd_profile
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lxd_profile
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.lxd.lxd_project:
- redirect: community.general.lxd_project
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.lxd_project
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.macports:
- redirect: community.general.macports
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.macports
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.mail:
- redirect: community.general.mail
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mail
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.make:
- redirect: community.general.make
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.make
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_alert_profiles:
- redirect: community.general.manageiq_alert_profiles
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_alert_profiles
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_alerts:
- redirect: community.general.manageiq_alerts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_alerts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_group:
- redirect: community.general.manageiq_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_policies:
- redirect: community.general.manageiq_policies
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_policies
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_policies_info:
- redirect: community.general.manageiq_policies_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_policies_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_provider:
- redirect: community.general.manageiq_provider
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_provider
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_tags:
- redirect: community.general.manageiq_tags
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_tags
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_tags_info:
- redirect: community.general.manageiq_tags_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_tags_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_tenant:
- redirect: community.general.manageiq_tenant
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_tenant
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.manageiq.manageiq_user:
- redirect: community.general.manageiq_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.manageiq_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.mas:
- redirect: community.general.mas
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mas
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.matrix:
- redirect: community.general.matrix
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.matrix
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.mattermost:
- redirect: community.general.mattermost
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mattermost
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.maven_artifact:
- redirect: community.general.maven_artifact
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.maven_artifact
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.memset.memset_dns_reload:
- redirect: community.general.memset_dns_reload
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.memset_dns_reload
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
memset_memstore_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.memset_memstore_info instead.
- cloud.memset.memset_memstore_info:
- redirect: community.general.memset_memstore_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.memset_memstore_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
memset_server_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.memset_server_info instead.
- cloud.memset.memset_server_info:
- redirect: community.general.memset_server_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.memset_server_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.memset.memset_zone:
- redirect: community.general.memset_zone
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.memset_zone
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.memset.memset_zone_domain:
- redirect: community.general.memset_zone_domain
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.memset_zone_domain
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.memset.memset_zone_record:
- redirect: community.general.memset_zone_record
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.memset_zone_record
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.mksysb:
- redirect: community.general.mksysb
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mksysb
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.modprobe:
- redirect: community.general.modprobe
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.modprobe
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.monit:
- redirect: community.general.monit
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.monit
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.mqtt:
- redirect: community.general.mqtt
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mqtt
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.mssql.mssql_db:
- redirect: community.general.mssql_db
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mssql_db
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.mssql.mssql_script:
- redirect: community.general.mssql_script
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.mssql_script
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
na_cdot_aggregate:
tombstone:
removal_version: 2.0.0
@@ -2316,52 +436,10 @@ plugin_routing:
tombstone:
removal_version: 3.0.0
warning_text: Use netapp.ontap.na_ontap_info instead.
- monitoring.nagios:
- redirect: community.general.nagios
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nagios
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.netcup_dns:
- redirect: community.general.netcup_dns
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.netcup_dns
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.newrelic_deployment:
- redirect: community.general.newrelic_deployment
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.newrelic_deployment
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.nexmo:
- redirect: community.general.nexmo
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nexmo
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
nginx_status_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.nginx_status_info instead.
- web_infrastructure.nginx_status_info:
- redirect: community.general.nginx_status_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nginx_status_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.smartos.nictagadm:
- redirect: community.general.nictagadm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nictagadm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
nios_a_record:
redirect: infoblox.nios_modules.nios_a_record
nios_aaaa_record:
@@ -2394,400 +472,57 @@ plugin_routing:
redirect: infoblox.nios_modules.nios_txt_record
nios_zone:
redirect: infoblox.nios_modules.nios_zone
- net_tools.nmcli:
- redirect: community.general.nmcli
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nmcli
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.nomad.nomad_job:
- redirect: community.general.nomad_job
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nomad_job
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.nomad.nomad_job_info:
- redirect: community.general.nomad_job_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nomad_job_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.nosh:
- redirect: community.general.nosh
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nosh
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.npm:
- redirect: community.general.npm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.npm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.nsupdate:
- redirect: community.general.nsupdate
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.nsupdate
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oracle.oci_vcn:
- redirect: community.general.oci_vcn
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oci_vcn
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.odbc:
- redirect: community.general.odbc
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.odbc
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.office_365_connector_card:
- redirect: community.general.office_365_connector_card
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.office_365_connector_card
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.ohai:
- redirect: community.general.ohai
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ohai
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.omapi_host:
- redirect: community.general.omapi_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.omapi_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
ome_device_info:
redirect: dellemc.openmanage.ome_device_info
- cloud.opennebula.one_host:
- redirect: community.general.one_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.one_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.opennebula.one_image:
- redirect: community.general.one_image
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.one_image
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
one_image_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.one_image_info instead.
- cloud.opennebula.one_image_info:
- redirect: community.general.one_image_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.one_image_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.opennebula.one_service:
- redirect: community.general.one_service
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.one_service
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.opennebula.one_template:
- redirect: community.general.one_template
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.one_template
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.opennebula.one_vm:
- redirect: community.general.one_vm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.one_vm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oneandone.oneandone_firewall_policy:
- redirect: community.general.oneandone_firewall_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneandone_firewall_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oneandone.oneandone_load_balancer:
- redirect: community.general.oneandone_load_balancer
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneandone_load_balancer
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oneandone.oneandone_monitoring_policy:
- redirect: community.general.oneandone_monitoring_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneandone_monitoring_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oneandone.oneandone_private_network:
- redirect: community.general.oneandone_private_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneandone_private_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oneandone.oneandone_public_ip:
- redirect: community.general.oneandone_public_ip
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneandone_public_ip
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.oneandone.oneandone_server:
- redirect: community.general.oneandone_server
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneandone_server
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
onepassword_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.onepassword_info instead.
- identity.onepassword_info:
- redirect: community.general.onepassword_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.onepassword_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_datacenter_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_datacenter_info instead.
- remote_management.oneview.oneview_datacenter_info:
- redirect: community.general.oneview_datacenter_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_datacenter_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_enclosure_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_enclosure_info instead.
- remote_management.oneview.oneview_enclosure_info:
- redirect: community.general.oneview_enclosure_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_enclosure_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.oneview.oneview_ethernet_network:
- redirect: community.general.oneview_ethernet_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_ethernet_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_ethernet_network_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_ethernet_network_info instead.
- remote_management.oneview.oneview_ethernet_network_info:
- redirect: community.general.oneview_ethernet_network_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_ethernet_network_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.oneview.oneview_fc_network:
- redirect: community.general.oneview_fc_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_fc_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_fc_network_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_fc_network_info instead.
- remote_management.oneview.oneview_fc_network_info:
- redirect: community.general.oneview_fc_network_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_fc_network_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.oneview.oneview_fcoe_network:
- redirect: community.general.oneview_fcoe_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_fcoe_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_fcoe_network_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_fcoe_network_info instead.
- remote_management.oneview.oneview_fcoe_network_info:
- redirect: community.general.oneview_fcoe_network_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_fcoe_network_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.oneview.oneview_logical_interconnect_group:
- redirect: community.general.oneview_logical_interconnect_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_logical_interconnect_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_logical_interconnect_group_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_logical_interconnect_group_info
instead.
- remote_management.oneview.oneview_logical_interconnect_group_info:
- redirect: community.general.oneview_logical_interconnect_group_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_logical_interconnect_group_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.oneview.oneview_network_set:
- redirect: community.general.oneview_network_set
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_network_set
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_network_set_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_network_set_info instead.
- remote_management.oneview.oneview_network_set_info:
- redirect: community.general.oneview_network_set_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_network_set_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.oneview.oneview_san_manager:
- redirect: community.general.oneview_san_manager
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_san_manager
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
oneview_san_manager_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.oneview_san_manager_info instead.
- remote_management.oneview.oneview_san_manager_info:
- redirect: community.general.oneview_san_manager_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.oneview_san_manager_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
online_server_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.online_server_info instead.
- cloud.online.online_server_info:
- redirect: community.general.online_server_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.online_server_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
online_user_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.online_user_info instead.
- cloud.online.online_user_info:
- redirect: community.general.online_user_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.online_user_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.open_iscsi:
- redirect: community.general.open_iscsi
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.open_iscsi
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.openbsd_pkg:
- redirect: community.general.openbsd_pkg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.openbsd_pkg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- identity.opendj.opendj_backendprop:
- redirect: community.general.opendj_backendprop
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.opendj_backendprop
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.openwrt_init:
- redirect: community.general.openwrt_init
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.openwrt_init
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.opkg:
- redirect: community.general.opkg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.opkg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.osx_defaults:
- redirect: community.general.osx_defaults
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.osx_defaults
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.ovh.ovh_ip_failover:
- redirect: community.general.ovh_ip_failover
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ovh_ip_failover
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.ovh.ovh_ip_loadbalancing_backend:
- redirect: community.general.ovh_ip_loadbalancing_backend
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ovh_ip_loadbalancing_backend
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.ovh.ovh_monthly_billing:
- redirect: community.general.ovh_monthly_billing
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ovh_monthly_billing
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
ovirt:
tombstone:
removal_version: 3.0.0
@@ -2888,216 +623,6 @@ plugin_routing:
tombstone:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_vmpool_info instead.
- clustering.pacemaker_cluster:
- redirect: community.general.pacemaker_cluster
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pacemaker_cluster
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.packet.packet_device:
- redirect: community.general.packet_device
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.packet_device
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.packet.packet_ip_subnet:
- redirect: community.general.packet_ip_subnet
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.packet_ip_subnet
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.packet.packet_project:
- redirect: community.general.packet_project
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.packet_project
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.packet.packet_sshkey:
- redirect: community.general.packet_sshkey
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.packet_sshkey
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.packet.packet_volume:
- redirect: community.general.packet_volume
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.packet_volume
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.packet.packet_volume_attachment:
- redirect: community.general.packet_volume_attachment
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.packet_volume_attachment
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pacman:
- redirect: community.general.pacman
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pacman
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pacman_key:
- redirect: community.general.pacman_key
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pacman_key
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.pagerduty:
- redirect: community.general.pagerduty
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pagerduty
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.pagerduty_alert:
- redirect: community.general.pagerduty_alert
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pagerduty_alert
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.pagerduty_change:
- redirect: community.general.pagerduty_change
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pagerduty_change
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.pagerduty_user:
- redirect: community.general.pagerduty_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pagerduty_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.pam_limits:
- redirect: community.general.pam_limits
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pam_limits
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.pamd:
- redirect: community.general.pamd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pamd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.parted:
- redirect: community.general.parted
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.parted
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.pear:
- redirect: community.general.pear
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pear
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.pids:
- redirect: community.general.pids
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pids
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.pingdom:
- redirect: community.general.pingdom
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pingdom
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.pip_package_info:
- redirect: community.general.pip_package_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pip_package_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.pipx:
- redirect: community.general.pipx
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pipx
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.pipx_info:
- redirect: community.general.pipx_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pipx_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pkg5:
- redirect: community.general.pkg5
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pkg5
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pkg5_publisher:
- redirect: community.general.pkg5_publisher
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pkg5_publisher
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pkgin:
- redirect: community.general.pkgin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pkgin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pkgng:
- redirect: community.general.pkgng
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pkgng
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pkgutil:
- redirect: community.general.pkgutil
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pkgutil
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.pmem.pmem:
- redirect: community.general.pmem
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pmem
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.portage:
- redirect: community.general.portage
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.portage
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.portinstall:
- redirect: community.general.portinstall
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.portinstall
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
postgresql_copy:
redirect: community.postgresql.postgresql_copy
postgresql_db:
@@ -3142,167 +667,6 @@ plugin_routing:
redirect: community.postgresql.postgresql_user
postgresql_user_obj_stat_info:
redirect: community.postgresql.postgresql_user_obj_stat_info
- net_tools.pritunl.pritunl_org:
- redirect: community.general.pritunl_org
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pritunl_org
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.pritunl.pritunl_org_info:
- redirect: community.general.pritunl_org_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pritunl_org_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.pritunl.pritunl_user:
- redirect: community.general.pritunl_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pritunl_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.pritunl.pritunl_user_info:
- redirect: community.general.pritunl_user_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pritunl_user_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.profitbricks.profitbricks:
- redirect: community.general.profitbricks
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.profitbricks
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.profitbricks.profitbricks_datacenter:
- redirect: community.general.profitbricks_datacenter
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.profitbricks_datacenter
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.profitbricks.profitbricks_nic:
- redirect: community.general.profitbricks_nic
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.profitbricks_nic
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.profitbricks.profitbricks_volume:
- redirect: community.general.profitbricks_volume
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.profitbricks_volume
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.profitbricks.profitbricks_volume_attachments:
- redirect: community.general.profitbricks_volume_attachments
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.profitbricks_volume_attachments
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox:
- redirect: community.general.proxmox
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_disk:
- redirect: community.general.proxmox_disk
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_disk
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_domain_info:
- redirect: community.general.proxmox_domain_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_domain_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_group_info:
- redirect: community.general.proxmox_group_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_group_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_kvm:
- redirect: community.general.proxmox_kvm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_kvm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_nic:
- redirect: community.general.proxmox_nic
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_nic
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_snap:
- redirect: community.general.proxmox_snap
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_snap
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_storage_info:
- redirect: community.general.proxmox_storage_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_storage_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_tasks_info:
- redirect: community.general.proxmox_tasks_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_tasks_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_template:
- redirect: community.general.proxmox_template
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_template
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.proxmox_user_info:
- redirect: community.general.proxmox_user_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.proxmox_user_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.pubnub.pubnub_blocks:
- redirect: community.general.pubnub_blocks
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pubnub_blocks
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.pulp_repo:
- redirect: community.general.pulp_repo
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pulp_repo
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.puppet:
- redirect: community.general.puppet
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.puppet
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
purefa_facts:
tombstone:
removal_version: 3.0.0
@@ -3311,669 +675,46 @@ plugin_routing:
tombstone:
removal_version: 3.0.0
warning_text: Use purestorage.flashblade.purefb_info instead.
- notification.pushbullet:
- redirect: community.general.pushbullet
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pushbullet
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.pushover:
- redirect: community.general.pushover
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.pushover
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
python_requirements_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.python_requirements_info instead.
- system.python_requirements_info:
- redirect: community.general.python_requirements_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.python_requirements_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax:
- redirect: community.general.rax
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_cbs:
- redirect: community.general.rax_cbs
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_cbs
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_cbs_attachments:
- redirect: community.general.rax_cbs_attachments
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_cbs_attachments
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_cdb:
- redirect: community.general.rax_cdb
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_cdb
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_cdb_database:
- redirect: community.general.rax_cdb_database
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_cdb_database
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_cdb_user:
- redirect: community.general.rax_cdb_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_cdb_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_clb:
- redirect: community.general.rax_clb
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_clb
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_clb_nodes:
- redirect: community.general.rax_clb_nodes
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_clb_nodes
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_clb_ssl:
- redirect: community.general.rax_clb_ssl
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_clb_ssl
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_dns:
- redirect: community.general.rax_dns
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_dns
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_dns_record:
- redirect: community.general.rax_dns_record
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_dns_record
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_facts:
- redirect: community.general.rax_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_files:
- redirect: community.general.rax_files
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_files
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_files_objects:
- redirect: community.general.rax_files_objects
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_files_objects
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_identity:
- redirect: community.general.rax_identity
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_identity
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_keypair:
- redirect: community.general.rax_keypair
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_keypair
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_meta:
- redirect: community.general.rax_meta
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_meta
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_mon_alarm:
- redirect: community.general.rax_mon_alarm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_mon_alarm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_mon_check:
- redirect: community.general.rax_mon_check
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_mon_check
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_mon_entity:
- redirect: community.general.rax_mon_entity
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_mon_entity
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_mon_notification:
- redirect: community.general.rax_mon_notification
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_mon_notification
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_mon_notification_plan:
- redirect: community.general.rax_mon_notification_plan
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_mon_notification_plan
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_network:
- redirect: community.general.rax_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_queue:
- redirect: community.general.rax_queue
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_queue
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_scaling_group:
- redirect: community.general.rax_scaling_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_scaling_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.rackspace.rax_scaling_policy:
- redirect: community.general.rax_scaling_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rax_scaling_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.read_csv:
- redirect: community.general.read_csv
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.read_csv
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.redfish.redfish_command:
- redirect: community.general.redfish_command
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redfish_command
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.redfish.redfish_config:
- redirect: community.general.redfish_config
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redfish_config
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
redfish_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.redfish_info instead.
- remote_management.redfish.redfish_info:
- redirect: community.general.redfish_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redfish_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
sapcar_extract:
redirect: community.sap_libs.sapcar_extract
sap_task_list_execute:
redirect: community.sap_libs.sap_task_list_execute
- packaging.os.redhat_subscription:
- redirect: community.general.redhat_subscription
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redhat_subscription
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.redis:
- redirect: community.general.redis
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redis
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.redis_data:
- redirect: community.general.redis_data
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redis_data
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.redis_data_incr:
- redirect: community.general.redis_data_incr
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redis_data_incr
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.redis_data_info:
- redirect: community.general.redis_data_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redis_data_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.redis_info:
- redirect: community.general.redis_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.redis_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.rhevm:
- redirect: community.general.rhevm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rhevm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.rhn_channel:
- redirect: community.general.rhn_channel
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rhn_channel
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.rhn_register:
- redirect: community.general.rhn_register
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rhn_register
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.rhsm_release:
- redirect: community.general.rhsm_release
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rhsm_release
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.rhsm_repository:
- redirect: community.general.rhsm_repository
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rhsm_repository
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.misc.riak:
- redirect: community.general.riak
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.riak
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.rocketchat:
- redirect: community.general.rocketchat
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rocketchat
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.rollbar_deployment:
- redirect: community.general.rollbar_deployment
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rollbar_deployment
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.rpm_ostree_pkg:
- redirect: community.general.rpm_ostree_pkg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rpm_ostree_pkg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.rundeck_acl_policy:
- redirect: community.general.rundeck_acl_policy
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rundeck_acl_policy
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.rundeck_job_executions_info:
- redirect: community.general.rundeck_job_executions_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rundeck_job_executions_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.rundeck_job_run:
- redirect: community.general.rundeck_job_run
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rundeck_job_run
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.rundeck_project:
- redirect: community.general.rundeck_project
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.rundeck_project
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.runit:
- redirect: community.general.runit
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.runit
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.sap_task_list_execute:
- redirect: community.general.sap_task_list_execute
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sap_task_list_execute
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.sapcar_extract:
- redirect: community.general.sapcar_extract
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sapcar_extract
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.say:
- redirect: community.general.say
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.say
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_compute:
- redirect: community.general.scaleway_compute
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_compute
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_compute_private_network:
- redirect: community.general.scaleway_compute_private_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_compute_private_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_container_registry:
- redirect: community.general.scaleway_container_registry
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_container_registry
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_container_registry_info:
- redirect: community.general.scaleway_container_registry_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_container_registry_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_database_backup:
- redirect: community.general.scaleway_database_backup
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_database_backup
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_function_namespace:
- redirect: community.general.scaleway_function_namespace
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_function_namespace
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_function_namespace_info:
- redirect: community.general.scaleway_function_namespace_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_function_namespace_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_image_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_image_info instead.
- cloud.scaleway.scaleway_image_info:
- redirect: community.general.scaleway_image_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_image_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_ip:
- redirect: community.general.scaleway_ip
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_ip
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_ip_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_ip_info instead.
- cloud.scaleway.scaleway_ip_info:
- redirect: community.general.scaleway_ip_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_ip_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_lb:
- redirect: community.general.scaleway_lb
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_lb
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_organization_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_organization_info instead.
- cloud.scaleway.scaleway_organization_info:
- redirect: community.general.scaleway_organization_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_organization_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_private_network:
- redirect: community.general.scaleway_private_network
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_private_network
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_security_group:
- redirect: community.general.scaleway_security_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_security_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_security_group_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_security_group_info instead.
- cloud.scaleway.scaleway_security_group_info:
- redirect: community.general.scaleway_security_group_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_security_group_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_security_group_rule:
- redirect: community.general.scaleway_security_group_rule
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_security_group_rule
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_server_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_server_info instead.
- cloud.scaleway.scaleway_server_info:
- redirect: community.general.scaleway_server_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_server_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_snapshot_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_snapshot_info instead.
- cloud.scaleway.scaleway_snapshot_info:
- redirect: community.general.scaleway_snapshot_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_snapshot_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_sshkey:
- redirect: community.general.scaleway_sshkey
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_sshkey
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_user_data:
- redirect: community.general.scaleway_user_data
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_user_data
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.scaleway.scaleway_volume:
- redirect: community.general.scaleway_volume
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_volume
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
scaleway_volume_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_volume_info instead.
- cloud.scaleway.scaleway_volume_info:
- redirect: community.general.scaleway_volume_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.scaleway_volume_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.sefcontext:
- redirect: community.general.sefcontext
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sefcontext
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.selinux_permissive:
- redirect: community.general.selinux_permissive
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.selinux_permissive
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.selogin:
- redirect: community.general.selogin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.selogin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.sendgrid:
- redirect: community.general.sendgrid
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sendgrid
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.sensu.sensu_check:
- redirect: community.general.sensu_check
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sensu_check
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.sensu.sensu_client:
- redirect: community.general.sensu_client
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sensu_client
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.sensu.sensu_handler:
- redirect: community.general.sensu_handler
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sensu_handler
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.sensu.sensu_silence:
- redirect: community.general.sensu_silence
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sensu_silence
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.sensu.sensu_subscription:
- redirect: community.general.sensu_subscription
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sensu_subscription
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.seport:
- redirect: community.general.seport
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.seport
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.serverless:
- redirect: community.general.serverless
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.serverless
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
sf_account_manager:
tombstone:
removal_version: 2.0.0
@@ -3994,699 +735,48 @@ plugin_routing:
tombstone:
removal_version: 2.0.0
warning_text: Use netapp.elementsw.na_elementsw_volume instead.
- system.shutdown:
- redirect: community.general.shutdown
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.shutdown
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.softlayer.sl_vm:
- redirect: community.general.sl_vm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sl_vm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.slack:
- redirect: community.general.slack
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.slack
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.slackpkg:
- redirect: community.general.slackpkg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.slackpkg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
smartos_image_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.smartos_image_info instead.
- cloud.smartos.smartos_image_info:
- redirect: community.general.smartos_image_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.smartos_image_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.snap:
- redirect: community.general.snap
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.snap
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.snap_alias:
- redirect: community.general.snap_alias
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.snap_alias
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- net_tools.snmp_facts:
- redirect: community.general.snmp_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.snmp_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.solaris_zone:
- redirect: community.general.solaris_zone
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.solaris_zone
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.sorcery:
- redirect: community.general.sorcery
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sorcery
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.spectrum_device:
- redirect: community.general.spectrum_device
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.spectrum_device
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.spectrum_model_attrs:
- redirect: community.general.spectrum_model_attrs
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.spectrum_model_attrs
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.spotinst.spotinst_aws_elastigroup:
- redirect: community.general.spotinst_aws_elastigroup
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.spotinst_aws_elastigroup
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.hpe3par.ss_3par_cpg:
- redirect: community.general.ss_3par_cpg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ss_3par_cpg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.ssh_config:
- redirect: community.general.ssh_config
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ssh_config
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.stackdriver:
- redirect: community.general.stackdriver
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.stackdriver
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.stacki.stacki_host:
- redirect: community.general.stacki_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.stacki_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.statsd:
- redirect: community.general.statsd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.statsd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.statusio_maintenance:
- redirect: community.general.statusio_maintenance
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.statusio_maintenance
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.sudoers:
- redirect: community.general.sudoers
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sudoers
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.supervisorctl:
- redirect: community.general.supervisorctl
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.supervisorctl
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.svc:
- redirect: community.general.svc
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.svc
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.svr4pkg:
- redirect: community.general.svr4pkg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.svr4pkg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.swdepot:
- redirect: community.general.swdepot
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.swdepot
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.swupd:
- redirect: community.general.swupd
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.swupd
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.syslogger:
- redirect: community.general.syslogger
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.syslogger
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.syspatch:
- redirect: community.general.syspatch
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.syspatch
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.sysrc:
- redirect: community.general.sysrc
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sysrc
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.sysupgrade:
- redirect: community.general.sysupgrade
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.sysupgrade
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.taiga_issue:
- redirect: community.general.taiga_issue
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.taiga_issue
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.telegram:
- redirect: community.general.telegram
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.telegram
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.terraform:
- redirect: community.general.terraform
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.terraform
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.timezone:
- redirect: community.general.timezone
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.timezone
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.twilio:
- redirect: community.general.twilio
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.twilio
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- notification.typetalk:
- redirect: community.general.typetalk
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.typetalk
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.univention.udm_dns_record:
- redirect: community.general.udm_dns_record
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.udm_dns_record
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.univention.udm_dns_zone:
- redirect: community.general.udm_dns_zone
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.udm_dns_zone
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.univention.udm_group:
- redirect: community.general.udm_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.udm_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.univention.udm_share:
- redirect: community.general.udm_share
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.udm_share
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.univention.udm_user:
- redirect: community.general.udm_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.udm_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.ufw:
- redirect: community.general.ufw
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.ufw
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- monitoring.uptimerobot:
- redirect: community.general.uptimerobot
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.uptimerobot
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.urpmi:
- redirect: community.general.urpmi
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.urpmi
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_aaa_group:
- redirect: community.general.utm_aaa_group
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_aaa_group
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_aaa_group_info:
- redirect: community.general.utm_aaa_group_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_aaa_group_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_ca_host_key_cert:
- redirect: community.general.utm_ca_host_key_cert
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_ca_host_key_cert
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_ca_host_key_cert_info:
- redirect: community.general.utm_ca_host_key_cert_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_ca_host_key_cert_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_dns_host:
- redirect: community.general.utm_dns_host
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_dns_host
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_network_interface_address:
- redirect: community.general.utm_network_interface_address
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_network_interface_address
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_network_interface_address_info:
- redirect: community.general.utm_network_interface_address_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_network_interface_address_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_proxy_auth_profile:
- redirect: community.general.utm_proxy_auth_profile
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_proxy_auth_profile
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_proxy_exception:
- redirect: community.general.utm_proxy_exception
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_proxy_exception
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_proxy_frontend:
- redirect: community.general.utm_proxy_frontend
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_proxy_frontend
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_proxy_frontend_info:
- redirect: community.general.utm_proxy_frontend_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_proxy_frontend_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_proxy_location:
- redirect: community.general.utm_proxy_location
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_proxy_location
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- web_infrastructure.sophos_utm.utm_proxy_location_info:
- redirect: community.general.utm_proxy_location_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.utm_proxy_location_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.vdo:
- redirect: community.general.vdo
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vdo
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.vertica.vertica_configuration:
- redirect: community.general.vertica_configuration
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vertica_configuration
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
vertica_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.vertica_info instead.
- database.vertica.vertica_info:
- redirect: community.general.vertica_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vertica_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.vertica.vertica_role:
- redirect: community.general.vertica_role
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vertica_role
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.vertica.vertica_schema:
- redirect: community.general.vertica_schema
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vertica_schema
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- database.vertica.vertica_user:
- redirect: community.general.vertica_user
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vertica_user
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.vexata.vexata_eg:
- redirect: community.general.vexata_eg
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vexata_eg
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.vexata.vexata_volume:
- redirect: community.general.vexata_volume
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vexata_volume
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.smartos.vmadm:
- redirect: community.general.vmadm
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.vmadm
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.wakeonlan:
- redirect: community.general.wakeonlan
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.wakeonlan
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.redfish.wdc_redfish_command:
- redirect: community.general.wdc_redfish_command
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.wdc_redfish_command
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.redfish.wdc_redfish_info:
- redirect: community.general.wdc_redfish_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.wdc_redfish_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
webfaction_app:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore and
+ warning_text: This module relied on HTTPS APIs that do not exist anymore and
there is no clear path to update.
- cloud.webfaction.webfaction_app:
- redirect: community.general.webfaction_app
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.webfaction_app
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
webfaction_db:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore and
+ warning_text: This module relied on HTTPS APIs that do not exist anymore and
there is no clear path to update.
- cloud.webfaction.webfaction_db:
- redirect: community.general.webfaction_db
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.webfaction_db
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
webfaction_domain:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore and
+ warning_text: This module relied on HTTPS APIs that do not exist anymore and
there is no clear path to update.
- cloud.webfaction.webfaction_domain:
- redirect: community.general.webfaction_domain
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.webfaction_domain
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
webfaction_mailbox:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore and
+ warning_text: This module relied on HTTPS APIs that do not exist anymore and
there is no clear path to update.
- cloud.webfaction.webfaction_mailbox:
- redirect: community.general.webfaction_mailbox
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.webfaction_mailbox
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
webfaction_site:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module relies on HTTPS APIs that do not exist anymore and
+ warning_text: This module relied on HTTPS APIs that do not exist anymore and
there is no clear path to update.
- cloud.webfaction.webfaction_site:
- redirect: community.general.webfaction_site
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.webfaction_site
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.xattr:
- redirect: community.general.xattr
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xattr
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.xbps:
- redirect: community.general.xbps
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xbps
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- remote_management.lenovoxcc.xcc_redfish_command:
- redirect: community.general.xcc_redfish_command
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xcc_redfish_command
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.misc.xenserver_facts:
- redirect: community.general.xenserver_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xenserver_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.xenserver.xenserver_guest:
- redirect: community.general.xenserver_guest
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xenserver_guest
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
xenserver_guest_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.general.xenserver_guest_info instead.
- cloud.xenserver.xenserver_guest_info:
- redirect: community.general.xenserver_guest_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xenserver_guest_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- cloud.xenserver.xenserver_guest_powerstate:
- redirect: community.general.xenserver_guest_powerstate
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xenserver_guest_powerstate
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.xfconf:
- redirect: community.general.xfconf
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xfconf
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.xfconf_info:
- redirect: community.general.xfconf_info
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xfconf_info
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.xfs_quota:
- redirect: community.general.xfs_quota
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xfs_quota
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- files.xml:
- redirect: community.general.xml
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.xml
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.language.yarn:
- redirect: community.general.yarn
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.yarn
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.yum_versionlock:
- redirect: community.general.yum_versionlock
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.yum_versionlock
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.zfs.zfs:
- redirect: community.general.zfs
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.zfs
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.zfs.zfs_delegate_admin:
- redirect: community.general.zfs_delegate_admin
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.zfs_delegate_admin
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.zfs.zfs_facts:
- redirect: community.general.zfs_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.zfs_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- clustering.znode:
- redirect: community.general.znode
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.znode
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- storage.zfs.zpool_facts:
- redirect: community.general.zpool_facts
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.zpool_facts
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.zypper:
- redirect: community.general.zypper
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.zypper
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- packaging.os.zypper_repository:
- redirect: community.general.zypper_repository
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.zypper_repository
- modules. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
doc_fragments:
rackspace:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This doc fragment is used by rax modules, that rely on the deprecated
+ warning_text: This doc fragment was used by rax modules, that relied on the deprecated
package pyrax.
_gcp:
redirect: community.google._gcp
@@ -4704,9 +794,9 @@ plugin_routing:
redirect: community.postgresql.postgresql
module_utils:
rax:
- deprecation:
+ tombstone:
removal_version: 9.0.0
- warning_text: This module util relies on the deprecated package pyrax.
+ warning_text: This module util relied on the deprecated package pyrax.
docker.common:
redirect: community.docker.common
docker.swarm:
@@ -4746,18 +836,3 @@ plugin_routing:
# for Ansible 2.9 or earlier. Now we only will have the redirect until we
# eventually will deprecate and then remove it.
redirect: ansible.builtin.path_join
- action:
- system.iptables_state:
- redirect: community.general.iptables_state
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.iptables_state
- action. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
- system.shutdown:
- redirect: community.general.shutdown
- deprecation:
- removal_version: 9.0.0
- warning_text: You are using an internal name to access the community.general.shutdown
- action. This has never been supported or documented, and will stop working
- in community.general 9.0.0.
diff --git a/ansible_collections/community/general/plugins/become/machinectl.py b/ansible_collections/community/general/plugins/become/machinectl.py
index 9b9ac7ec5..e2773ed6a 100644
--- a/ansible_collections/community/general/plugins/become/machinectl.py
+++ b/ansible_collections/community/general/plugins/become/machinectl.py
@@ -78,12 +78,13 @@ DOCUMENTATION = '''
EXAMPLES = r'''
# A polkit rule needed to use the module with a non-root user.
# See the Notes section for details.
-60-machinectl-fast-user-auth.rules: |
- polkit.addRule(function(action, subject) {
- if(action.id == "org.freedesktop.machine1.host-shell" && subject.isInGroup("wheel")) {
- return polkit.Result.AUTH_SELF_KEEP;
- }
- });
+/etc/polkit-1/rules.d/60-machinectl-fast-user-auth.rules: |
+ polkit.addRule(function(action, subject) {
+ if(action.id == "org.freedesktop.machine1.host-shell" &&
+ subject.isInGroup("wheel")) {
+ return polkit.Result.AUTH_SELF_KEEP;
+ }
+ });
'''
from re import compile as re_compile
diff --git a/ansible_collections/community/general/plugins/become/run0.py b/ansible_collections/community/general/plugins/become/run0.py
new file mode 100644
index 000000000..a718e86f2
--- /dev/null
+++ b/ansible_collections/community/general/plugins/become/run0.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+ name: run0
+ short_description: Systemd's run0
+ description:
+ - This become plugins allows your remote/login user to execute commands as another user via the C(run0) utility.
+ author:
+ - Thomas Sjögren (@konstruktoid)
+ version_added: '9.0.0'
+ options:
+ become_user:
+ description: User you 'become' to execute the task.
+ default: root
+ ini:
+ - section: privilege_escalation
+ key: become_user
+ - section: run0_become_plugin
+ key: user
+ vars:
+ - name: ansible_become_user
+ - name: ansible_run0_user
+ env:
+ - name: ANSIBLE_BECOME_USER
+ - name: ANSIBLE_RUN0_USER
+ type: string
+ become_exe:
+ description: The C(run0) executable.
+ default: run0
+ ini:
+ - section: privilege_escalation
+ key: become_exe
+ - section: run0_become_plugin
+ key: executable
+ vars:
+ - name: ansible_become_exe
+ - name: ansible_run0_exe
+ env:
+ - name: ANSIBLE_BECOME_EXE
+ - name: ANSIBLE_RUN0_EXE
+ type: string
+ become_flags:
+ description: Options to pass to run0.
+ default: ''
+ ini:
+ - section: privilege_escalation
+ key: become_flags
+ - section: run0_become_plugin
+ key: flags
+ vars:
+ - name: ansible_become_flags
+ - name: ansible_run0_flags
+ env:
+ - name: ANSIBLE_BECOME_FLAGS
+ - name: ANSIBLE_RUN0_FLAGS
+ type: string
+ notes:
+ - This plugin will only work when a polkit rule is in place.
+"""
+
+EXAMPLES = r"""
+# An example polkit rule that allows the user 'ansible' in the 'wheel' group
+# to execute commands using run0 without authentication.
+/etc/polkit-1/rules.d/60-run0-fast-user-auth.rules: |
+ polkit.addRule(function(action, subject) {
+ if(action.id == "org.freedesktop.systemd1.manage-units" &&
+ subject.isInGroup("wheel") &&
+ subject.user == "ansible") {
+ return polkit.Result.YES;
+ }
+ });
+"""
+
+from re import compile as re_compile
+
+from ansible.plugins.become import BecomeBase
+from ansible.module_utils._text import to_bytes
+
+ansi_color_codes = re_compile(to_bytes(r"\x1B\[[0-9;]+m"))
+
+
+class BecomeModule(BecomeBase):
+
+ name = "community.general.run0"
+
+ prompt = "Password: "
+ fail = ("==== AUTHENTICATION FAILED ====",)
+ success = ("==== AUTHENTICATION COMPLETE ====",)
+ require_tty = (
+ True # see https://github.com/ansible-collections/community.general/issues/6932
+ )
+
+ @staticmethod
+ def remove_ansi_codes(line):
+ return ansi_color_codes.sub(b"", line)
+
+ def build_become_command(self, cmd, shell):
+ super().build_become_command(cmd, shell)
+
+ if not cmd:
+ return cmd
+
+ become = self.get_option("become_exe")
+ flags = self.get_option("become_flags")
+ user = self.get_option("become_user")
+
+ return (
+ f"{become} --user={user} {flags} {self._build_success_command(cmd, shell)}"
+ )
+
+ def check_success(self, b_output):
+ b_output = self.remove_ansi_codes(b_output)
+ return super().check_success(b_output)
+
+ def check_incorrect_password(self, b_output):
+ b_output = self.remove_ansi_codes(b_output)
+ return super().check_incorrect_password(b_output)
+
+ def check_missing_password(self, b_output):
+ b_output = self.remove_ansi_codes(b_output)
+ return super().check_missing_password(b_output)
diff --git a/ansible_collections/community/general/plugins/callback/opentelemetry.py b/ansible_collections/community/general/plugins/callback/opentelemetry.py
index 492e42071..58cfa057b 100644
--- a/ansible_collections/community/general/plugins/callback/opentelemetry.py
+++ b/ansible_collections/community/general/plugins/callback/opentelemetry.py
@@ -84,6 +84,33 @@ DOCUMENTATION = '''
- section: callback_opentelemetry
key: disable_attributes_in_logs
version_added: 7.1.0
+ store_spans_in_file:
+ default: None
+ type: str
+ description:
+ - It stores the exported spans in the given file
+ env:
+ - name: ANSIBLE_OPENTELEMETRY_STORE_SPANS_IN_FILE
+ ini:
+ - section: callback_opentelemetry
+ key: store_spans_in_file
+ version_added: 9.0.0
+ otel_exporter_otlp_traces_protocol:
+ type: str
+ description:
+ - E(OTEL_EXPORTER_OTLP_TRACES_PROTOCOL) represents the the transport protocol for spans.
+ - See
+ U(https://opentelemetry-python.readthedocs.io/en/latest/sdk/environment_variables.html#envvar-OTEL_EXPORTER_OTLP_TRACES_PROTOCOL).
+ default: grpc
+ choices:
+ - grpc
+ - http/protobuf
+ env:
+ - name: OTEL_EXPORTER_OTLP_TRACES_PROTOCOL
+ ini:
+ - section: callback_opentelemetry
+ key: otel_exporter_otlp_traces_protocol
+ version_added: 9.0.0
requirements:
- opentelemetry-api (Python library)
- opentelemetry-exporter-otlp (Python library)
@@ -107,6 +134,7 @@ examples: |
'''
import getpass
+import json
import os
import socket
import sys
@@ -124,15 +152,19 @@ from ansible.plugins.callback import CallbackBase
try:
from opentelemetry import trace
from opentelemetry.trace import SpanKind
- from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCOTLPSpanExporter
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPOTLPSpanExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
- BatchSpanProcessor
+ BatchSpanProcessor,
+ SimpleSpanProcessor
+ )
+ from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
+ InMemorySpanExporter
)
-
# Support for opentelemetry-api <= 1.12
try:
from opentelemetry.util._time import _time_ns
@@ -255,7 +287,16 @@ class OpenTelemetrySource(object):
task.dump = dump
task.add_host(HostData(host_uuid, host_name, status, result))
- def generate_distributed_traces(self, otel_service_name, ansible_playbook, tasks_data, status, traceparent, disable_logs, disable_attributes_in_logs):
+ def generate_distributed_traces(self,
+ otel_service_name,
+ ansible_playbook,
+ tasks_data,
+ status,
+ traceparent,
+ disable_logs,
+ disable_attributes_in_logs,
+ otel_exporter_otlp_traces_protocol,
+ store_spans_in_file):
""" generate distributed traces from the collected TaskData and HostData """
tasks = []
@@ -271,7 +312,16 @@ class OpenTelemetrySource(object):
)
)
- processor = BatchSpanProcessor(OTLPSpanExporter())
+ otel_exporter = None
+ if store_spans_in_file:
+ otel_exporter = InMemorySpanExporter()
+ processor = SimpleSpanProcessor(otel_exporter)
+ else:
+ if otel_exporter_otlp_traces_protocol == 'grpc':
+ otel_exporter = GRPCOTLPSpanExporter()
+ else:
+ otel_exporter = HTTPOTLPSpanExporter()
+ processor = BatchSpanProcessor(otel_exporter)
trace.get_tracer_provider().add_span_processor(processor)
@@ -293,6 +343,8 @@ class OpenTelemetrySource(object):
with tracer.start_as_current_span(task.name, start_time=task.start, end_on_exit=False) as span:
self.update_span_data(task, host_data, span, disable_logs, disable_attributes_in_logs)
+ return otel_exporter
+
def update_span_data(self, task_data, host_data, span, disable_logs, disable_attributes_in_logs):
""" update the span with the given TaskData and HostData """
@@ -350,7 +402,8 @@ class OpenTelemetrySource(object):
if not disable_logs:
# This will avoid populating span attributes to the logs
span.add_event(task_data.dump, attributes={} if disable_attributes_in_logs else attributes)
- span.end(end_time=host_data.finish)
+ # Close span always
+ span.end(end_time=host_data.finish)
def set_span_attributes(self, span, attributes):
""" update the span attributes with the given attributes if not None """
@@ -462,6 +515,8 @@ class CallbackModule(CallbackBase):
self.errors = 0
self.disabled = False
self.traceparent = False
+ self.store_spans_in_file = False
+ self.otel_exporter_otlp_traces_protocol = None
if OTEL_LIBRARY_IMPORT_ERROR:
raise_from(
@@ -489,6 +544,8 @@ class CallbackModule(CallbackBase):
self.disable_logs = self.get_option('disable_logs')
+ self.store_spans_in_file = self.get_option('store_spans_in_file')
+
self.otel_service_name = self.get_option('otel_service_name')
if not self.otel_service_name:
@@ -497,6 +554,14 @@ class CallbackModule(CallbackBase):
# See https://github.com/open-telemetry/opentelemetry-specification/issues/740
self.traceparent = self.get_option('traceparent')
+ self.otel_exporter_otlp_traces_protocol = self.get_option('otel_exporter_otlp_traces_protocol')
+
+ def dump_results(self, result):
+ """ dump the results if disable_logs is not enabled """
+ if self.disable_logs:
+ return ""
+ return self._dump_results(result._result)
+
def v2_playbook_on_start(self, playbook):
self.ansible_playbook = basename(playbook._file_name)
@@ -546,7 +611,7 @@ class CallbackModule(CallbackBase):
self.tasks_data,
status,
result,
- self._dump_results(result._result)
+ self.dump_results(result)
)
def v2_runner_on_ok(self, result):
@@ -554,7 +619,7 @@ class CallbackModule(CallbackBase):
self.tasks_data,
'ok',
result,
- self._dump_results(result._result)
+ self.dump_results(result)
)
def v2_runner_on_skipped(self, result):
@@ -562,7 +627,7 @@ class CallbackModule(CallbackBase):
self.tasks_data,
'skipped',
result,
- self._dump_results(result._result)
+ self.dump_results(result)
)
def v2_playbook_on_include(self, included_file):
@@ -578,15 +643,22 @@ class CallbackModule(CallbackBase):
status = Status(status_code=StatusCode.OK)
else:
status = Status(status_code=StatusCode.ERROR)
- self.opentelemetry.generate_distributed_traces(
+ otel_exporter = self.opentelemetry.generate_distributed_traces(
self.otel_service_name,
self.ansible_playbook,
self.tasks_data,
status,
self.traceparent,
self.disable_logs,
- self.disable_attributes_in_logs
+ self.disable_attributes_in_logs,
+ self.otel_exporter_otlp_traces_protocol,
+ self.store_spans_in_file
)
+ if self.store_spans_in_file:
+ spans = [json.loads(span.to_json()) for span in otel_exporter.get_finished_spans()]
+ with open(self.store_spans_in_file, "w", encoding="utf-8") as output:
+ json.dump({"spans": spans}, output, indent=4)
+
def v2_runner_on_async_failed(self, result, **kwargs):
self.errors += 1
diff --git a/ansible_collections/community/general/plugins/callback/timestamp.py b/ansible_collections/community/general/plugins/callback/timestamp.py
new file mode 100644
index 000000000..07cd8d239
--- /dev/null
+++ b/ansible_collections/community/general/plugins/callback/timestamp.py
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2024, kurokobo <kurokobo@protonmail.com>
+# Copyright (c) 2014, Michael DeHaan <michael.dehaan@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = r"""
+ name: timestamp
+ type: stdout
+ short_description: Adds simple timestamp for each header
+ version_added: 9.0.0
+ description:
+ - This callback adds simple timestamp for each header.
+ author: kurokobo (@kurokobo)
+ options:
+ timezone:
+ description:
+ - Timezone to use for the timestamp in IANA time zone format.
+ - For example C(America/New_York), C(Asia/Tokyo)). Ignored on Python < 3.9.
+ ini:
+ - section: callback_timestamp
+ key: timezone
+ env:
+ - name: ANSIBLE_CALLBACK_TIMESTAMP_TIMEZONE
+ type: string
+ format_string:
+ description:
+ - Format of the timestamp shown to user in 1989 C standard format.
+ - >
+ Refer to L(the Python documentation,https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes)
+ for the available format codes.
+ ini:
+ - section: callback_timestamp
+ key: format_string
+ env:
+ - name: ANSIBLE_CALLBACK_TIMESTAMP_FORMAT_STRING
+ default: "%H:%M:%S"
+ type: string
+ seealso:
+ - plugin: ansible.posix.profile_tasks
+ plugin_type: callback
+ description: >
+ You can use P(ansible.posix.profile_tasks#callback) callback plugin to time individual tasks and overall execution time
+ with detailed timestamps.
+ extends_documentation_fragment:
+ - ansible.builtin.default_callback
+ - ansible.builtin.result_format_callback
+"""
+
+
+from ansible.plugins.callback.default import CallbackModule as Default
+from ansible.utils.display import get_text_width
+from ansible.module_utils.common.text.converters import to_text
+from datetime import datetime
+import types
+import sys
+
+# Store whether the zoneinfo module is available
+_ZONEINFO_AVAILABLE = sys.version_info >= (3, 9)
+
+
+def get_datetime_now(tz):
+ """
+ Returns the current timestamp with the specified timezone
+ """
+ return datetime.now(tz=tz)
+
+
+def banner(self, msg, color=None, cows=True):
+ """
+ Prints a header-looking line with cowsay or stars with length depending on terminal width (3 minimum) with trailing timestamp
+
+ Based on the banner method of Display class from ansible.utils.display
+
+ https://github.com/ansible/ansible/blob/4403519afe89138042108e237aef317fd5f09c33/lib/ansible/utils/display.py#L511
+ """
+ timestamp = get_datetime_now(self.timestamp_tzinfo).strftime(self.timestamp_format_string)
+ timestamp_len = get_text_width(timestamp) + 1 # +1 for leading space
+
+ msg = to_text(msg)
+ if self.b_cowsay and cows:
+ try:
+ self.banner_cowsay("%s @ %s" % (msg, timestamp))
+ return
+ except OSError:
+ self.warning("somebody cleverly deleted cowsay or something during the PB run. heh.")
+
+ msg = msg.strip()
+ try:
+ star_len = self.columns - get_text_width(msg) - timestamp_len
+ except EnvironmentError:
+ star_len = self.columns - len(msg) - timestamp_len
+ if star_len <= 3:
+ star_len = 3
+ stars = "*" * star_len
+ self.display("\n%s %s %s" % (msg, stars, timestamp), color=color)
+
+
+class CallbackModule(Default):
+ CALLBACK_VERSION = 2.0
+ CALLBACK_TYPE = "stdout"
+ CALLBACK_NAME = "community.general.timestamp"
+
+ def __init__(self):
+ super(CallbackModule, self).__init__()
+
+ # Replace the banner method of the display object with the custom one
+ self._display.banner = types.MethodType(banner, self._display)
+
+ def set_options(self, task_keys=None, var_options=None, direct=None):
+ super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
+
+ # Store zoneinfo for specified timezone if available
+ tzinfo = None
+ if _ZONEINFO_AVAILABLE and self.get_option("timezone"):
+ from zoneinfo import ZoneInfo
+
+ tzinfo = ZoneInfo(self.get_option("timezone"))
+
+ # Inject options into the display object
+ setattr(self._display, "timestamp_tzinfo", tzinfo)
+ setattr(self._display, "timestamp_format_string", self.get_option("format_string"))
diff --git a/ansible_collections/community/general/plugins/callback/yaml.py b/ansible_collections/community/general/plugins/callback/yaml.py
index ae2c8f881..e41f69ec5 100644
--- a/ansible_collections/community/general/plugins/callback/yaml.py
+++ b/ansible_collections/community/general/plugins/callback/yaml.py
@@ -19,6 +19,16 @@ DOCUMENTATION = '''
- default_callback
requirements:
- set as stdout in configuration
+ seealso:
+ - plugin: ansible.builtin.default
+ plugin_type: callback
+ description: >
+ There is a parameter O(ansible.builtin.default#callback:result_format) in P(ansible.builtin.default#callback)
+ that allows you to change the output format to YAML.
+ notes:
+ - >
+ With ansible-core 2.13 or newer, you can instead specify V(yaml) for the parameter O(ansible.builtin.default#callback:result_format)
+ in P(ansible.builtin.default#callback).
'''
import yaml
diff --git a/ansible_collections/community/general/plugins/doc_fragments/consul.py b/ansible_collections/community/general/plugins/doc_fragments/consul.py
index fbe3f33d4..d4cf11995 100644
--- a/ansible_collections/community/general/plugins/doc_fragments/consul.py
+++ b/ansible_collections/community/general/plugins/doc_fragments/consul.py
@@ -56,5 +56,4 @@ attributes:
support: full
membership:
- community.general.consul
- version_added: 8.3.0
"""
diff --git a/ansible_collections/community/general/plugins/doc_fragments/django.py b/ansible_collections/community/general/plugins/doc_fragments/django.py
new file mode 100644
index 000000000..d92799937
--- /dev/null
+++ b/ansible_collections/community/general/plugins/doc_fragments/django.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+class ModuleDocFragment(object):
+ DOCUMENTATION = r'''
+options:
+ venv:
+ description:
+ - Use the the Python interpreter from this virtual environment.
+ - Pass the path to the root of the virtualenv, not the C(bin/) directory nor the C(python) executable.
+ type: path
+ settings:
+ description:
+ - Specifies the settings module to use.
+ - The value will be passed as is to the C(--settings) argument in C(django-admin).
+ type: str
+ required: true
+ pythonpath:
+ description:
+ - Adds the given filesystem path to the Python import search path.
+ - The value will be passed as is to the C(--pythonpath) argument in C(django-admin).
+ type: path
+ traceback:
+ description:
+ - Provides a full stack trace in the output when a C(CommandError) is raised.
+ type: bool
+ verbosity:
+ description:
+ - Specifies the amount of notification and debug information in the output of C(django-admin).
+ type: int
+ choices: [0, 1, 2, 3]
+ skip_checks:
+ description:
+ - Skips running system checks prior to running the command.
+ type: bool
+
+
+notes:
+ - The C(django-admin) command is always executed using the C(C) locale, and the option C(--no-color) is always passed.
+
+seealso:
+ - name: django-admin and manage.py in official Django documentation
+ description: >-
+ Refer to this documentation for the builtin commands and options of C(django-admin).
+ Please make sure that you select the right version of Django in the version selector on that page.
+ link: https://docs.djangoproject.com/en/5.0/ref/django-admin/
+'''
diff --git a/ansible_collections/community/general/plugins/doc_fragments/proxmox.py b/ansible_collections/community/general/plugins/doc_fragments/proxmox.py
index 4972da498..cb533fefa 100644
--- a/ansible_collections/community/general/plugins/doc_fragments/proxmox.py
+++ b/ansible_collections/community/general/plugins/doc_fragments/proxmox.py
@@ -65,3 +65,13 @@ options:
- Add the new VM to the specified pool.
type: str
'''
+
+ ACTIONGROUP_PROXMOX = r"""
+options: {}
+attributes:
+ action_group:
+ description: Use C(group/community.general.proxmox) in C(module_defaults) to set defaults for this module.
+ support: full
+ membership:
+ - community.general.proxmox
+"""
diff --git a/ansible_collections/community/general/plugins/doc_fragments/rackspace.py b/ansible_collections/community/general/plugins/doc_fragments/rackspace.py
deleted file mode 100644
index f28be777c..000000000
--- a/ansible_collections/community/general/plugins/doc_fragments/rackspace.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014, Matt Martz <matt@sivel.net>
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-
-class ModuleDocFragment(object):
-
- # Standard Rackspace only documentation fragment
- DOCUMENTATION = r'''
-options:
- api_key:
- description:
- - Rackspace API key, overrides O(credentials).
- type: str
- aliases: [ password ]
- credentials:
- description:
- - File to find the Rackspace credentials in. Ignored if O(api_key) and
- O(username) are provided.
- type: path
- aliases: [ creds_file ]
- env:
- description:
- - Environment as configured in C(~/.pyrax.cfg),
- see U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration).
- type: str
- region:
- description:
- - Region to create an instance in.
- type: str
- username:
- description:
- - Rackspace username, overrides O(credentials).
- type: str
- validate_certs:
- description:
- - Whether or not to require SSL validation of API endpoints.
- type: bool
- aliases: [ verify_ssl ]
-requirements:
- - pyrax
-notes:
- - The following environment variables can be used, E(RAX_USERNAME),
- E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
- - E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) point to a credentials file
- appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating).
- - E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file.
- - E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...).
-'''
-
- # Documentation fragment including attributes to enable communication
- # of other OpenStack clouds. Not all rax modules support this.
- OPENSTACK = r'''
-options:
- api_key:
- type: str
- description:
- - Rackspace API key, overrides O(credentials).
- aliases: [ password ]
- auth_endpoint:
- type: str
- description:
- - The URI of the authentication service.
- - If not specified will be set to U(https://identity.api.rackspacecloud.com/v2.0/).
- credentials:
- type: path
- description:
- - File to find the Rackspace credentials in. Ignored if O(api_key) and
- O(username) are provided.
- aliases: [ creds_file ]
- env:
- type: str
- description:
- - Environment as configured in C(~/.pyrax.cfg),
- see U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration).
- identity_type:
- type: str
- description:
- - Authentication mechanism to use, such as rackspace or keystone.
- default: rackspace
- region:
- type: str
- description:
- - Region to create an instance in.
- tenant_id:
- type: str
- description:
- - The tenant ID used for authentication.
- tenant_name:
- type: str
- description:
- - The tenant name used for authentication.
- username:
- type: str
- description:
- - Rackspace username, overrides O(credentials).
- validate_certs:
- description:
- - Whether or not to require SSL validation of API endpoints.
- type: bool
- aliases: [ verify_ssl ]
-deprecated:
- removed_in: 9.0.0
- why: This module relies on the deprecated package pyrax.
- alternative: Use the Openstack modules instead.
-requirements:
- - pyrax
-notes:
- - The following environment variables can be used, E(RAX_USERNAME),
- E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
- - E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) points to a credentials file
- appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating).
- - E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file.
- - E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...).
-'''
diff --git a/ansible_collections/community/general/plugins/lookup/merge_variables.py b/ansible_collections/community/general/plugins/lookup/merge_variables.py
index 4fc33014c..ce7621ad2 100644
--- a/ansible_collections/community/general/plugins/lookup/merge_variables.py
+++ b/ansible_collections/community/general/plugins/lookup/merge_variables.py
@@ -157,7 +157,9 @@ class LookupModule(LookupBase):
cross_host_merge_result = initial_value
for host in variables["hostvars"]:
if self._is_host_in_allowed_groups(variables["hostvars"][host]["group_names"]):
- cross_host_merge_result = self._merge_vars(term, cross_host_merge_result, variables["hostvars"][host])
+ host_variables = dict(variables["hostvars"].raw_get(host))
+ host_variables["hostvars"] = variables["hostvars"] # re-add hostvars
+ cross_host_merge_result = self._merge_vars(term, cross_host_merge_result, host_variables)
ret.append(cross_host_merge_result)
return ret
@@ -195,7 +197,8 @@ class LookupModule(LookupBase):
result = initial_value
for var_name in var_merge_names:
- var_value = self._templar.template(variables[var_name]) # Render jinja2 templates
+ with self._templar.set_temporary_context(available_variables=variables): # tmp. switch renderer to context of current variables
+ var_value = self._templar.template(variables[var_name]) # Render jinja2 templates
var_type = _verify_and_get_type(var_value)
if prev_var_type is None:
diff --git a/ansible_collections/community/general/plugins/module_utils/cmd_runner.py b/ansible_collections/community/general/plugins/module_utils/cmd_runner.py
index 864987120..2bf2b32e8 100644
--- a/ansible_collections/community/general/plugins/module_utils/cmd_runner.py
+++ b/ansible_collections/community/general/plugins/module_utils/cmd_runner.py
@@ -129,8 +129,15 @@ class _Format(object):
return _ArgFormat(lambda value: ["{0}={1}".format(arg, value)], ignore_none=ignore_none)
@staticmethod
- def as_list(ignore_none=None):
- return _ArgFormat(_ensure_list, ignore_none=ignore_none)
+ def as_list(ignore_none=None, min_len=0, max_len=None):
+ def func(value):
+ value = _ensure_list(value)
+ if len(value) < min_len:
+ raise ValueError("Parameter must have at least {0} element(s)".format(min_len))
+ if max_len is not None and len(value) > max_len:
+ raise ValueError("Parameter must have at most {0} element(s)".format(max_len))
+ return value
+ return _ArgFormat(func, ignore_none=ignore_none)
@staticmethod
def as_fixed(args):
diff --git a/ansible_collections/community/general/plugins/module_utils/django.py b/ansible_collections/community/general/plugins/module_utils/django.py
new file mode 100644
index 000000000..fbaf840db
--- /dev/null
+++ b/ansible_collections/community/general/plugins/module_utils/django.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
+from ansible_collections.community.general.plugins.module_utils.python_runner import PythonRunner
+from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
+
+
+django_std_args = dict(
+ # environmental options
+ venv=dict(type="path"),
+ # default options of django-admin
+ settings=dict(type="str", required=True),
+ pythonpath=dict(type="path"),
+ traceback=dict(type="bool"),
+ verbosity=dict(type="int", choices=[0, 1, 2, 3]),
+ skip_checks=dict(type="bool"),
+)
+
+_django_std_arg_fmts = dict(
+ command=cmd_runner_fmt.as_list(),
+ settings=cmd_runner_fmt.as_opt_eq_val("--settings"),
+ pythonpath=cmd_runner_fmt.as_opt_eq_val("--pythonpath"),
+ traceback=cmd_runner_fmt.as_bool("--traceback"),
+ verbosity=cmd_runner_fmt.as_opt_val("--verbosity"),
+ no_color=cmd_runner_fmt.as_fixed("--no-color"),
+ skip_checks=cmd_runner_fmt.as_bool("--skip-checks"),
+)
+
+
+class _DjangoRunner(PythonRunner):
+ def __init__(self, module, arg_formats=None, **kwargs):
+ arg_fmts = dict(arg_formats) if arg_formats else {}
+ arg_fmts.update(_django_std_arg_fmts)
+
+ super(_DjangoRunner, self).__init__(module, ["-m", "django"], arg_formats=arg_fmts, **kwargs)
+
+ def __call__(self, output_process=None, ignore_value_none=True, check_mode_skip=False, check_mode_return=None, **kwargs):
+ args_order = (
+ ("command", "no_color", "settings", "pythonpath", "traceback", "verbosity", "skip_checks") + self._prepare_args_order(self.default_args_order)
+ )
+ return super(_DjangoRunner, self).__call__(args_order, output_process, ignore_value_none, check_mode_skip, check_mode_return, **kwargs)
+
+
+class DjangoModuleHelper(ModuleHelper):
+ module = {}
+ use_old_vardict = False
+ django_admin_cmd = None
+ arg_formats = {}
+ django_admin_arg_order = ()
+ use_old_vardict = False
+
+ def __init__(self):
+ argument_spec = dict(django_std_args)
+ argument_spec.update(self.module.get("argument_spec", {}))
+ self.module["argument_spec"] = argument_spec
+ super(DjangoModuleHelper, self).__init__(self.module)
+ if self.django_admin_cmd is not None:
+ self.vars.command = self.django_admin_cmd
+
+ def __run__(self):
+ runner = _DjangoRunner(self.module,
+ default_args_order=self.django_admin_arg_order,
+ arg_formats=self.arg_formats,
+ venv=self.vars.venv,
+ check_rc=True)
+ with runner() as ctx:
+ results = ctx.run()
+ self.vars.stdout = ctx.results_out
+ self.vars.stderr = ctx.results_err
+ self.vars.cmd = ctx.cmd
+ if self.verbosity >= 3:
+ self.vars.run_info = ctx.run_info
+
+ return results
+
+ @classmethod
+ def execute(cls):
+ cls().run()
diff --git a/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py b/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py
index 53245d44d..824fea46e 100644
--- a/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py
+++ b/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py
@@ -33,6 +33,7 @@ class GandiLiveDNSAPI(object):
def __init__(self, module):
self.module = module
self.api_key = module.params['api_key']
+ self.personal_access_token = module.params['personal_access_token']
def _build_error_message(self, module, info):
s = ''
@@ -50,7 +51,12 @@ class GandiLiveDNSAPI(object):
return s
def _gandi_api_call(self, api_call, method='GET', payload=None, error_on_404=True):
- headers = {'Authorization': 'Apikey {0}'.format(self.api_key),
+ authorization_header = (
+ 'Bearer {0}'.format(self.personal_access_token)
+ if self.personal_access_token
+ else 'Apikey {0}'.format(self.api_key)
+ )
+ headers = {'Authorization': authorization_header,
'Content-Type': 'application/json'}
data = None
if payload:
diff --git a/ansible_collections/community/general/plugins/module_utils/gitlab.py b/ansible_collections/community/general/plugins/module_utils/gitlab.py
index b1354d8a9..224789a71 100644
--- a/ansible_collections/community/general/plugins/module_utils/gitlab.py
+++ b/ansible_collections/community/general/plugins/module_utils/gitlab.py
@@ -115,6 +115,11 @@ def gitlab_authentication(module, min_version=None):
# Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0
# This condition allow to still support older version of the python-gitlab library
if LooseVersion(gitlab.__version__) < LooseVersion("1.13.0"):
+ module.deprecate(
+ "GitLab basic auth is deprecated and will be removed in next major version, "
+ "using another auth method (API token or OAuth) is strongly recommended.",
+ version='10.0.0',
+ collection_name='community.general')
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=verify, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
else:
diff --git a/ansible_collections/community/general/plugins/module_utils/homebrew.py b/ansible_collections/community/general/plugins/module_utils/homebrew.py
new file mode 100644
index 000000000..281683210
--- /dev/null
+++ b/ansible_collections/community/general/plugins/module_utils/homebrew.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) Ansible project
+# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
+# SPDX-License-Identifier: BSD-2-Clause
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import os
+import re
+from ansible.module_utils.six import string_types
+
+
+def _create_regex_group_complement(s):
+ lines = (line.strip() for line in s.split("\n") if line.strip())
+ chars = filter(None, (line.split("#")[0].strip() for line in lines))
+ group = r"[^" + r"".join(chars) + r"]"
+ return re.compile(group)
+
+
+class HomebrewValidate(object):
+ # class regexes ------------------------------------------------ {{{
+ VALID_PATH_CHARS = r"""
+ \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
+ \s # spaces
+ : # colons
+ {sep} # the OS-specific path separator
+ . # dots
+ \- # dashes
+ """.format(
+ sep=os.path.sep
+ )
+
+ VALID_BREW_PATH_CHARS = r"""
+ \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
+ \s # spaces
+ {sep} # the OS-specific path separator
+ . # dots
+ \- # dashes
+ """.format(
+ sep=os.path.sep
+ )
+
+ VALID_PACKAGE_CHARS = r"""
+ \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
+ . # dots
+ / # slash (for taps)
+ \+ # plusses
+ \- # dashes
+ : # colons (for URLs)
+ @ # at-sign
+ """
+
+ INVALID_PATH_REGEX = _create_regex_group_complement(VALID_PATH_CHARS)
+ INVALID_BREW_PATH_REGEX = _create_regex_group_complement(VALID_BREW_PATH_CHARS)
+ INVALID_PACKAGE_REGEX = _create_regex_group_complement(VALID_PACKAGE_CHARS)
+ # /class regexes ----------------------------------------------- }}}
+
+ # class validations -------------------------------------------- {{{
+ @classmethod
+ def valid_path(cls, path):
+ """
+ `path` must be one of:
+ - list of paths
+ - a string containing only:
+ - alphanumeric characters
+ - dashes
+ - dots
+ - spaces
+ - colons
+ - os.path.sep
+ """
+
+ if isinstance(path, string_types):
+ return not cls.INVALID_PATH_REGEX.search(path)
+
+ try:
+ iter(path)
+ except TypeError:
+ return False
+ else:
+ paths = path
+ return all(cls.valid_brew_path(path_) for path_ in paths)
+
+ @classmethod
+ def valid_brew_path(cls, brew_path):
+ """
+ `brew_path` must be one of:
+ - None
+ - a string containing only:
+ - alphanumeric characters
+ - dashes
+ - dots
+ - spaces
+ - os.path.sep
+ """
+
+ if brew_path is None:
+ return True
+
+ return isinstance(
+ brew_path, string_types
+ ) and not cls.INVALID_BREW_PATH_REGEX.search(brew_path)
+
+ @classmethod
+ def valid_package(cls, package):
+ """A valid package is either None or alphanumeric."""
+
+ if package is None:
+ return True
+
+ return isinstance(
+ package, string_types
+ ) and not cls.INVALID_PACKAGE_REGEX.search(package)
diff --git a/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py b/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py
index 772df8c0e..dd879ff4b 100644
--- a/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py
+++ b/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py
@@ -7,13 +7,14 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-import traceback
-
-from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase
-from ansible_collections.community.general.plugins.module_utils.mh.deco import module_fails_on_exception
-
class DependencyCtxMgr(object):
+ """
+ DEPRECATION WARNING
+
+ This class is deprecated and will be removed in community.general 11.0.0
+ Modules should use plugins/module_utils/deps.py instead.
+ """
def __init__(self, name, msg=None):
self.name = name
self.msg = msg
@@ -35,39 +36,3 @@ class DependencyCtxMgr(object):
@property
def text(self):
return self.msg or str(self.exc_val)
-
-
-class DependencyMixin(ModuleHelperBase):
- """
- THIS CLASS IS BEING DEPRECATED.
- See the deprecation notice in ``DependencyMixin.fail_on_missing_deps()`` below.
-
- Mixin for mapping module options to running a CLI command with its arguments.
- """
- _dependencies = []
-
- @classmethod
- def dependency(cls, name, msg):
- cls._dependencies.append(DependencyCtxMgr(name, msg))
- return cls._dependencies[-1]
-
- def fail_on_missing_deps(self):
- if not self._dependencies:
- return
- self.module.deprecate(
- 'The DependencyMixin is being deprecated. '
- 'Modules should use community.general.plugins.module_utils.deps instead.',
- version='9.0.0',
- collection_name='community.general',
- )
- for d in self._dependencies:
- if not d.has_it:
- self.module.fail_json(changed=False,
- exception="\n".join(traceback.format_exception(d.exc_type, d.exc_val, d.exc_tb)),
- msg=d.text,
- **self.output)
-
- @module_fails_on_exception
- def run(self):
- self.fail_on_missing_deps()
- super(DependencyMixin, self).run()
diff --git a/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py b/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
index 91f4e4a18..161560973 100644
--- a/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
+++ b/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
@@ -14,7 +14,7 @@ class VarMeta(object):
"""
DEPRECATION WARNING
- This class is deprecated and will be removed in community.general 10.0.0
+ This class is deprecated and will be removed in community.general 11.0.0
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
"""
@@ -70,7 +70,7 @@ class VarDict(object):
"""
DEPRECATION WARNING
- This class is deprecated and will be removed in community.general 10.0.0
+ This class is deprecated and will be removed in community.general 11.0.0
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
"""
def __init__(self):
@@ -139,7 +139,7 @@ class VarsMixin(object):
"""
DEPRECATION WARNING
- This class is deprecated and will be removed in community.general 10.0.0
+ This class is deprecated and will be removed in community.general 11.0.0
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
"""
def __init__(self, module=None):
diff --git a/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py b/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py
index c33efb16b..ca95199d9 100644
--- a/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py
+++ b/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# (c) 2020, Alexei Znamensky <russoz@gmail.com>
-# Copyright (c) 2020, Ansible Project
+# (c) 2020-2024, Alexei Znamensky <russoz@gmail.com>
+# Copyright (c) 2020-2024, Ansible Project
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
# SPDX-License-Identifier: BSD-2-Clause
@@ -10,23 +10,40 @@ __metaclass__ = type
from ansible.module_utils.common.dict_transformations import dict_merge
+from ansible_collections.community.general.plugins.module_utils.vardict import VarDict as _NewVarDict # remove "as NewVarDict" in 11.0.0
# (TODO: remove AnsibleModule!) pylint: disable-next=unused-import
-from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase, AnsibleModule # noqa: F401
+from ansible_collections.community.general.plugins.module_utils.mh.base import AnsibleModule # noqa: F401 DEPRECATED, remove in 11.0.0
+from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase
from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyMixin
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin
+# (TODO: remove mh.mixins.vars!) pylint: disable-next=unused-import
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin, VarDict as _OldVarDict # noqa: F401 remove in 11.0.0
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprecate_attrs import DeprecateAttrsMixin
-class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelperBase):
+class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
facts_name = None
output_params = ()
diff_params = ()
change_params = ()
facts_params = ()
+ use_old_vardict = True # remove in 11.0.0
+ mute_vardict_deprecation = False
def __init__(self, module=None):
- super(ModuleHelper, self).__init__(module)
+ if self.use_old_vardict: # remove first half of the if in 11.0.0
+ self.vars = _OldVarDict()
+ super(ModuleHelper, self).__init__(module)
+ if not self.mute_vardict_deprecation:
+ self.module.deprecate(
+ "This class is using the old VarDict from ModuleHelper, which is deprecated. "
+ "Set the class variable use_old_vardict to False and make the necessary adjustments."
+ "The old VarDict class will be removed in community.general 11.0.0",
+ version="11.0.0", collection_name="community.general"
+ )
+ else:
+ self.vars = _NewVarDict()
+ super(ModuleHelper, self).__init__(module)
+
for name, value in self.module.params.items():
self.vars.set(
name, value,
@@ -36,6 +53,12 @@ class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelper
fact=name in self.facts_params,
)
+ def update_vars(self, meta=None, **kwargs):
+ if meta is None:
+ meta = {}
+ for k, v in kwargs.items():
+ self.vars.set(k, v, **meta)
+
def update_output(self, **kwargs):
self.update_vars(meta={"output": True}, **kwargs)
@@ -43,7 +66,10 @@ class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelper
self.update_vars(meta={"fact": True}, **kwargs)
def _vars_changed(self):
- return any(self.vars.has_changed(v) for v in self.vars.change_vars())
+ if self.use_old_vardict:
+ return any(self.vars.has_changed(v) for v in self.vars.change_vars())
+
+ return self.vars.has_changed
def has_changed(self):
return self.changed or self._vars_changed()
diff --git a/ansible_collections/community/general/plugins/module_utils/module_helper.py b/ansible_collections/community/general/plugins/module_utils/module_helper.py
index 5aa16c057..366699329 100644
--- a/ansible_collections/community/general/plugins/module_utils/module_helper.py
+++ b/ansible_collections/community/general/plugins/module_utils/module_helper.py
@@ -9,14 +9,14 @@ __metaclass__ = type
# pylint: disable=unused-import
-
from ansible_collections.community.general.plugins.module_utils.mh.module_helper import (
- ModuleHelper, StateModuleHelper, AnsibleModule
+ ModuleHelper, StateModuleHelper,
+ AnsibleModule # remove in 11.0.0
)
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin # noqa: F401
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr, DependencyMixin # noqa: F401
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin # noqa: F401 remove in 11.0.0
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr # noqa: F401 remove in 11.0.0
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException # noqa: F401
from ansible_collections.community.general.plugins.module_utils.mh.deco import (
cause_changes, module_fails_on_exception, check_mode_skip, check_mode_skip_returns,
)
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict, VarsMixin # noqa: F401
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict, VarsMixin # noqa: F401 remove in 11.0.0
diff --git a/ansible_collections/community/general/plugins/module_utils/puppet.py b/ansible_collections/community/general/plugins/module_utils/puppet.py
index f05b0673f..e06683b3e 100644
--- a/ansible_collections/community/general/plugins/module_utils/puppet.py
+++ b/ansible_collections/community/general/plugins/module_utils/puppet.py
@@ -103,6 +103,7 @@ def puppet_runner(module):
modulepath=cmd_runner_fmt.as_opt_eq_val("--modulepath"),
_execute=cmd_runner_fmt.as_func(execute_func),
summarize=cmd_runner_fmt.as_bool("--summarize"),
+ waitforlock=cmd_runner_fmt.as_opt_val("--waitforlock"),
debug=cmd_runner_fmt.as_bool("--debug"),
verbose=cmd_runner_fmt.as_bool("--verbose"),
),
diff --git a/ansible_collections/community/general/plugins/module_utils/python_runner.py b/ansible_collections/community/general/plugins/module_utils/python_runner.py
new file mode 100644
index 000000000..f678f247b
--- /dev/null
+++ b/ansible_collections/community/general/plugins/module_utils/python_runner.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import os
+
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, _ensure_list
+
+
+class PythonRunner(CmdRunner):
+ def __init__(self, module, command, arg_formats=None, default_args_order=(),
+ check_rc=False, force_lang="C", path_prefix=None, environ_update=None,
+ python="python", venv=None):
+ self.python = python
+ self.venv = venv
+ self.has_venv = venv is not None
+
+ if (os.path.isabs(python) or '/' in python):
+ self.python = python
+ elif self.has_venv:
+ path_prefix = os.path.join(venv, "bin")
+ if environ_update is None:
+ environ_update = {}
+ environ_update["PATH"] = "%s:%s" % (path_prefix, os.environ["PATH"])
+ environ_update["VIRTUAL_ENV"] = venv
+
+ python_cmd = [self.python] + _ensure_list(command)
+
+ super(PythonRunner, self).__init__(module, python_cmd, arg_formats, default_args_order,
+ check_rc, force_lang, path_prefix, environ_update)
diff --git a/ansible_collections/community/general/plugins/module_utils/rax.py b/ansible_collections/community/general/plugins/module_utils/rax.py
deleted file mode 100644
index 6331c0d1b..000000000
--- a/ansible_collections/community/general/plugins/module_utils/rax.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# -*- coding: utf-8 -*-
-# This code is part of Ansible, but is an independent component.
-# This particular file snippet, and this file snippet only, is BSD licensed.
-# Modules you write using this snippet, which is embedded dynamically by
-# Ansible still belong to the author of the module, and may assign their own
-# license to the complete work.
-#
-# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2012-2013
-#
-# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
-# SPDX-License-Identifier: BSD-2-Clause
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-
-import os
-import re
-from uuid import UUID
-
-from ansible.module_utils.six import text_type, binary_type
-
-FINAL_STATUSES = ('ACTIVE', 'ERROR')
-VOLUME_STATUS = ('available', 'attaching', 'creating', 'deleting', 'in-use',
- 'error', 'error_deleting')
-
-CLB_ALGORITHMS = ['RANDOM', 'LEAST_CONNECTIONS', 'ROUND_ROBIN',
- 'WEIGHTED_LEAST_CONNECTIONS', 'WEIGHTED_ROUND_ROBIN']
-CLB_PROTOCOLS = ['DNS_TCP', 'DNS_UDP', 'FTP', 'HTTP', 'HTTPS', 'IMAPS',
- 'IMAPv4', 'LDAP', 'LDAPS', 'MYSQL', 'POP3', 'POP3S', 'SMTP',
- 'TCP', 'TCP_CLIENT_FIRST', 'UDP', 'UDP_STREAM', 'SFTP']
-
-NON_CALLABLES = (text_type, binary_type, bool, dict, int, list, type(None))
-PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
-SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
-
-
-def rax_slugify(value):
- """Prepend a key with rax_ and normalize the key name"""
- return 'rax_%s' % (re.sub(r'[^\w-]', '_', value).lower().lstrip('_'))
-
-
-def rax_clb_node_to_dict(obj):
- """Function to convert a CLB Node object to a dict"""
- if not obj:
- return {}
- node = obj.to_dict()
- node['id'] = obj.id
- node['weight'] = obj.weight
- return node
-
-
-def rax_to_dict(obj, obj_type='standard'):
- """Generic function to convert a pyrax object to a dict
-
- obj_type values:
- standard
- clb
- server
-
- """
- instance = {}
- for key in dir(obj):
- value = getattr(obj, key)
- if obj_type == 'clb' and key == 'nodes':
- instance[key] = []
- for node in value:
- instance[key].append(rax_clb_node_to_dict(node))
- elif (isinstance(value, list) and len(value) > 0 and
- not isinstance(value[0], NON_CALLABLES)):
- instance[key] = []
- for item in value:
- instance[key].append(rax_to_dict(item))
- elif (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
- if obj_type == 'server':
- if key == 'image':
- if not value:
- instance['rax_boot_source'] = 'volume'
- else:
- instance['rax_boot_source'] = 'local'
- key = rax_slugify(key)
- instance[key] = value
-
- if obj_type == 'server':
- for attr in ['id', 'accessIPv4', 'name', 'status']:
- instance[attr] = instance.get(rax_slugify(attr))
-
- return instance
-
-
-def rax_find_bootable_volume(module, rax_module, server, exit=True):
- """Find a servers bootable volume"""
- cs = rax_module.cloudservers
- cbs = rax_module.cloud_blockstorage
- server_id = rax_module.utils.get_id(server)
- volumes = cs.volumes.get_server_volumes(server_id)
- bootable_volumes = []
- for volume in volumes:
- vol = cbs.get(volume)
- if module.boolean(vol.bootable):
- bootable_volumes.append(vol)
- if not bootable_volumes:
- if exit:
- module.fail_json(msg='No bootable volumes could be found for '
- 'server %s' % server_id)
- else:
- return False
- elif len(bootable_volumes) > 1:
- if exit:
- module.fail_json(msg='Multiple bootable volumes found for server '
- '%s' % server_id)
- else:
- return False
-
- return bootable_volumes[0]
-
-
-def rax_find_image(module, rax_module, image, exit=True):
- """Find a server image by ID or Name"""
- cs = rax_module.cloudservers
- try:
- UUID(image)
- except ValueError:
- try:
- image = cs.images.find(human_id=image)
- except (cs.exceptions.NotFound, cs.exceptions.NoUniqueMatch):
- try:
- image = cs.images.find(name=image)
- except (cs.exceptions.NotFound,
- cs.exceptions.NoUniqueMatch):
- if exit:
- module.fail_json(msg='No matching image found (%s)' %
- image)
- else:
- return False
-
- return rax_module.utils.get_id(image)
-
-
-def rax_find_volume(module, rax_module, name):
- """Find a Block storage volume by ID or name"""
- cbs = rax_module.cloud_blockstorage
- try:
- UUID(name)
- volume = cbs.get(name)
- except ValueError:
- try:
- volume = cbs.find(name=name)
- except rax_module.exc.NotFound:
- volume = None
- except Exception as e:
- module.fail_json(msg='%s' % e)
- return volume
-
-
-def rax_find_network(module, rax_module, network):
- """Find a cloud network by ID or name"""
- cnw = rax_module.cloud_networks
- try:
- UUID(network)
- except ValueError:
- if network.lower() == 'public':
- return cnw.get_server_networks(PUBLIC_NET_ID)
- elif network.lower() == 'private':
- return cnw.get_server_networks(SERVICE_NET_ID)
- else:
- try:
- network_obj = cnw.find_network_by_label(network)
- except (rax_module.exceptions.NetworkNotFound,
- rax_module.exceptions.NetworkLabelNotUnique):
- module.fail_json(msg='No matching network found (%s)' %
- network)
- else:
- return cnw.get_server_networks(network_obj)
- else:
- return cnw.get_server_networks(network)
-
-
-def rax_find_server(module, rax_module, server):
- """Find a Cloud Server by ID or name"""
- cs = rax_module.cloudservers
- try:
- UUID(server)
- server = cs.servers.get(server)
- except ValueError:
- servers = cs.servers.list(search_opts=dict(name='^%s$' % server))
- if not servers:
- module.fail_json(msg='No Server was matched by name, '
- 'try using the Server ID instead')
- if len(servers) > 1:
- module.fail_json(msg='Multiple servers matched by name, '
- 'try using the Server ID instead')
-
- # We made it this far, grab the first and hopefully only server
- # in the list
- server = servers[0]
- return server
-
-
-def rax_find_loadbalancer(module, rax_module, loadbalancer):
- """Find a Cloud Load Balancer by ID or name"""
- clb = rax_module.cloud_loadbalancers
- try:
- found = clb.get(loadbalancer)
- except Exception:
- found = []
- for lb in clb.list():
- if loadbalancer == lb.name:
- found.append(lb)
-
- if not found:
- module.fail_json(msg='No loadbalancer was matched')
-
- if len(found) > 1:
- module.fail_json(msg='Multiple loadbalancers matched')
-
- # We made it this far, grab the first and hopefully only item
- # in the list
- found = found[0]
-
- return found
-
-
-def rax_argument_spec():
- """Return standard base dictionary used for the argument_spec
- argument in AnsibleModule
-
- """
- return dict(
- api_key=dict(type='str', aliases=['password'], no_log=True),
- auth_endpoint=dict(type='str'),
- credentials=dict(type='path', aliases=['creds_file']),
- env=dict(type='str'),
- identity_type=dict(type='str', default='rackspace'),
- region=dict(type='str'),
- tenant_id=dict(type='str'),
- tenant_name=dict(type='str'),
- username=dict(type='str'),
- validate_certs=dict(type='bool', aliases=['verify_ssl']),
- )
-
-
-def rax_required_together():
- """Return the default list used for the required_together argument to
- AnsibleModule"""
- return [['api_key', 'username']]
-
-
-def setup_rax_module(module, rax_module, region_required=True):
- """Set up pyrax in a standard way for all modules"""
- rax_module.USER_AGENT = 'ansible/%s %s' % (module.ansible_version,
- rax_module.USER_AGENT)
-
- api_key = module.params.get('api_key')
- auth_endpoint = module.params.get('auth_endpoint')
- credentials = module.params.get('credentials')
- env = module.params.get('env')
- identity_type = module.params.get('identity_type')
- region = module.params.get('region')
- tenant_id = module.params.get('tenant_id')
- tenant_name = module.params.get('tenant_name')
- username = module.params.get('username')
- verify_ssl = module.params.get('validate_certs')
-
- if env is not None:
- rax_module.set_environment(env)
-
- rax_module.set_setting('identity_type', identity_type)
- if verify_ssl is not None:
- rax_module.set_setting('verify_ssl', verify_ssl)
- if auth_endpoint is not None:
- rax_module.set_setting('auth_endpoint', auth_endpoint)
- if tenant_id is not None:
- rax_module.set_setting('tenant_id', tenant_id)
- if tenant_name is not None:
- rax_module.set_setting('tenant_name', tenant_name)
-
- try:
- username = username or os.environ.get('RAX_USERNAME')
- if not username:
- username = rax_module.get_setting('keyring_username')
- if username:
- api_key = 'USE_KEYRING'
- if not api_key:
- api_key = os.environ.get('RAX_API_KEY')
- credentials = (credentials or os.environ.get('RAX_CREDENTIALS') or
- os.environ.get('RAX_CREDS_FILE'))
- region = (region or os.environ.get('RAX_REGION') or
- rax_module.get_setting('region'))
- except KeyError as e:
- module.fail_json(msg='Unable to load %s' % e.message)
-
- try:
- if api_key and username:
- if api_key == 'USE_KEYRING':
- rax_module.keyring_auth(username, region=region)
- else:
- rax_module.set_credentials(username, api_key=api_key,
- region=region)
- elif credentials:
- credentials = os.path.expanduser(credentials)
- rax_module.set_credential_file(credentials, region=region)
- else:
- raise Exception('No credentials supplied!')
- except Exception as e:
- if e.message:
- msg = str(e.message)
- else:
- msg = repr(e)
- module.fail_json(msg=msg)
-
- if region_required and region not in rax_module.regions:
- module.fail_json(msg='%s is not a valid region, must be one of: %s' %
- (region, ','.join(rax_module.regions)))
-
- return rax_module
-
-
-def rax_scaling_group_personality_file(module, files):
- if not files:
- return []
-
- results = []
- for rpath, lpath in files.items():
- lpath = os.path.expanduser(lpath)
- try:
- with open(lpath, 'r') as f:
- results.append({
- 'path': rpath,
- 'contents': f.read(),
- })
- except Exception as e:
- module.fail_json(msg='Failed to load %s: %s' % (lpath, str(e)))
- return results
diff --git a/ansible_collections/community/general/plugins/module_utils/redhat.py b/ansible_collections/community/general/plugins/module_utils/redhat.py
index 110159ddf..321386a0a 100644
--- a/ansible_collections/community/general/plugins/module_utils/redhat.py
+++ b/ansible_collections/community/general/plugins/module_utils/redhat.py
@@ -15,10 +15,8 @@ __metaclass__ = type
import os
-import re
import shutil
import tempfile
-import types
from ansible.module_utils.six.moves import configparser
@@ -76,241 +74,3 @@ class RegistrationBase(object):
def subscribe(self, **kwargs):
raise NotImplementedError("Must be implemented by a sub-class")
-
-
-class Rhsm(RegistrationBase):
- """
- DEPRECATION WARNING
-
- This class is deprecated and will be removed in community.general 9.0.0.
- There is no replacement for it; please contact the community.general
- maintainers in case you are using it.
- """
-
- def __init__(self, module, username=None, password=None):
- RegistrationBase.__init__(self, module, username, password)
- self.config = self._read_config()
- self.module = module
- self.module.deprecate(
- 'The Rhsm class is deprecated with no replacement.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- def _read_config(self, rhsm_conf='/etc/rhsm/rhsm.conf'):
- '''
- Load RHSM configuration from /etc/rhsm/rhsm.conf.
- Returns:
- * ConfigParser object
- '''
-
- # Read RHSM defaults ...
- cp = configparser.ConfigParser()
- cp.read(rhsm_conf)
-
- # Add support for specifying a default value w/o having to standup some configuration
- # Yeah, I know this should be subclassed ... but, oh well
- def get_option_default(self, key, default=''):
- sect, opt = key.split('.', 1)
- if self.has_section(sect) and self.has_option(sect, opt):
- return self.get(sect, opt)
- else:
- return default
-
- cp.get_option = types.MethodType(get_option_default, cp, configparser.ConfigParser)
-
- return cp
-
- def enable(self):
- '''
- Enable the system to receive updates from subscription-manager.
- This involves updating affected yum plugins and removing any
- conflicting yum repositories.
- '''
- RegistrationBase.enable(self)
- self.update_plugin_conf('rhnplugin', False)
- self.update_plugin_conf('subscription-manager', True)
-
- def configure(self, **kwargs):
- '''
- Configure the system as directed for registration with RHN
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'config']
-
- # Pass supplied **kwargs as parameters to subscription-manager. Ignore
- # non-configuration parameters and replace '_' with '.'. For example,
- # 'server_hostname' becomes '--system.hostname'.
- for k, v in kwargs.items():
- if re.search(r'^(system|rhsm)_', k):
- args.append('--%s=%s' % (k.replace('_', '.'), v))
-
- self.module.run_command(args, check_rc=True)
-
- @property
- def is_registered(self):
- '''
- Determine whether the current system
- Returns:
- * Boolean - whether the current system is currently registered to
- RHN.
- '''
- args = ['subscription-manager', 'identity']
- rc, stdout, stderr = self.module.run_command(args, check_rc=False)
- if rc == 0:
- return True
- else:
- return False
-
- def register(self, username, password, autosubscribe, activationkey):
- '''
- Register the current system to the provided RHN server
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'register']
-
- # Generate command arguments
- if activationkey:
- args.append('--activationkey "%s"' % activationkey)
- else:
- if autosubscribe:
- args.append('--autosubscribe')
- if username:
- args.extend(['--username', username])
- if password:
- args.extend(['--password', password])
-
- # Do the needful...
- rc, stderr, stdout = self.module.run_command(args, check_rc=True)
-
- def unsubscribe(self):
- '''
- Unsubscribe a system from all subscribed channels
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'unsubscribe', '--all']
- rc, stderr, stdout = self.module.run_command(args, check_rc=True)
-
- def unregister(self):
- '''
- Unregister a currently registered system
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'unregister']
- rc, stderr, stdout = self.module.run_command(args, check_rc=True)
- self.update_plugin_conf('rhnplugin', False)
- self.update_plugin_conf('subscription-manager', False)
-
- def subscribe(self, regexp):
- '''
- Subscribe current system to available pools matching the specified
- regular expression
- Raises:
- * Exception - if error occurs while running command
- '''
-
- # Available pools ready for subscription
- available_pools = RhsmPools(self.module)
-
- for pool in available_pools.filter(regexp):
- pool.subscribe()
-
-
-class RhsmPool(object):
- """
- Convenience class for housing subscription information
-
- DEPRECATION WARNING
-
- This class is deprecated and will be removed in community.general 9.0.0.
- There is no replacement for it; please contact the community.general
- maintainers in case you are using it.
- """
-
- def __init__(self, module, **kwargs):
- self.module = module
- for k, v in kwargs.items():
- setattr(self, k, v)
- self.module.deprecate(
- 'The RhsmPool class is deprecated with no replacement.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- def __str__(self):
- return str(self.__getattribute__('_name'))
-
- def subscribe(self):
- args = "subscription-manager subscribe --pool %s" % self.PoolId
- rc, stdout, stderr = self.module.run_command(args, check_rc=True)
- if rc == 0:
- return True
- else:
- return False
-
-
-class RhsmPools(object):
- """
- This class is used for manipulating pools subscriptions with RHSM
-
- DEPRECATION WARNING
-
- This class is deprecated and will be removed in community.general 9.0.0.
- There is no replacement for it; please contact the community.general
- maintainers in case you are using it.
- """
-
- def __init__(self, module):
- self.module = module
- self.products = self._load_product_list()
- self.module.deprecate(
- 'The RhsmPools class is deprecated with no replacement.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- def __iter__(self):
- return self.products.__iter__()
-
- def _load_product_list(self):
- """
- Loads list of all available pools for system in data structure
- """
- args = "subscription-manager list --available"
- rc, stdout, stderr = self.module.run_command(args, check_rc=True)
-
- products = []
- for line in stdout.split('\n'):
- # Remove leading+trailing whitespace
- line = line.strip()
- # An empty line implies the end of an output group
- if len(line) == 0:
- continue
- # If a colon ':' is found, parse
- elif ':' in line:
- (key, value) = line.split(':', 1)
- key = key.strip().replace(" ", "") # To unify
- value = value.strip()
- if key in ['ProductName', 'SubscriptionName']:
- # Remember the name for later processing
- products.append(RhsmPool(self.module, _name=value, key=value))
- elif products:
- # Associate value with most recently recorded product
- products[-1].__setattr__(key, value)
- # FIXME - log some warning?
- # else:
- # warnings.warn("Unhandled subscription key/value: %s/%s" % (key,value))
- return products
-
- def filter(self, regexp='^$'):
- '''
- Return a list of RhsmPools whose name matches the provided regular expression
- '''
- r = re.compile(regexp)
- for product in self.products:
- if r.search(product._name):
- yield product
diff --git a/ansible_collections/community/general/plugins/module_utils/rundeck.py b/ansible_collections/community/general/plugins/module_utils/rundeck.py
index 7df68a360..cffca7b4e 100644
--- a/ansible_collections/community/general/plugins/module_utils/rundeck.py
+++ b/ansible_collections/community/general/plugins/module_utils/rundeck.py
@@ -28,7 +28,7 @@ def api_argument_spec():
return api_argument_spec
-def api_request(module, endpoint, data=None, method="GET"):
+def api_request(module, endpoint, data=None, method="GET", content_type="application/json"):
"""Manages Rundeck API requests via HTTP(S)
:arg module: The AnsibleModule (used to get url, api_version, api_token, etc).
@@ -63,7 +63,7 @@ def api_request(module, endpoint, data=None, method="GET"):
data=json.dumps(data),
method=method,
headers={
- "Content-Type": "application/json",
+ "Content-Type": content_type,
"Accept": "application/json",
"X-Rundeck-Auth-Token": module.params["api_token"]
}
diff --git a/ansible_collections/community/general/plugins/module_utils/vardict.py b/ansible_collections/community/general/plugins/module_utils/vardict.py
index cfcce4d4d..51f802483 100644
--- a/ansible_collections/community/general/plugins/module_utils/vardict.py
+++ b/ansible_collections/community/general/plugins/module_utils/vardict.py
@@ -100,7 +100,7 @@ class _Variable(object):
return
def __str__(self):
- return "<_Variable: value={0!r}, initial={1!r}, diff={2}, output={3}, change={4}, verbosity={5}>".format(
+ return "<Variable: value={0!r}, initial={1!r}, diff={2}, output={3}, change={4}, verbosity={5}>".format(
self.value, self.initial_value, self.diff, self.output, self.change, self.verbosity
)
diff --git a/ansible_collections/community/general/plugins/modules/aix_lvol.py b/ansible_collections/community/general/plugins/modules/aix_lvol.py
index 1e7b42568..7d0fb1ee0 100644
--- a/ansible_collections/community/general/plugins/modules/aix_lvol.py
+++ b/ansible_collections/community/general/plugins/modules/aix_lvol.py
@@ -240,8 +240,6 @@ def main():
state = module.params['state']
pvs = module.params['pvs']
- pv_list = ' '.join(pvs)
-
if policy == 'maximum':
lv_policy = 'x'
else:
@@ -249,16 +247,16 @@ def main():
# Add echo command when running in check-mode
if module.check_mode:
- test_opt = 'echo '
+ test_opt = [module.get_bin_path("echo", required=True)]
else:
- test_opt = ''
+ test_opt = []
# check if system commands are available
lsvg_cmd = module.get_bin_path("lsvg", required=True)
lslv_cmd = module.get_bin_path("lslv", required=True)
# Get information on volume group requested
- rc, vg_info, err = module.run_command("%s %s" % (lsvg_cmd, vg))
+ rc, vg_info, err = module.run_command([lsvg_cmd, vg])
if rc != 0:
if state == 'absent':
@@ -273,8 +271,7 @@ def main():
lv_size = round_ppsize(convert_size(module, size), base=this_vg['pp_size'])
# Get information on logical volume requested
- rc, lv_info, err = module.run_command(
- "%s %s" % (lslv_cmd, lv))
+ rc, lv_info, err = module.run_command([lslv_cmd, lv])
if rc != 0:
if state == 'absent':
@@ -296,7 +293,7 @@ def main():
# create LV
mklv_cmd = module.get_bin_path("mklv", required=True)
- cmd = "%s %s -t %s -y %s -c %s -e %s %s %s %sM %s" % (test_opt, mklv_cmd, lv_type, lv, copies, lv_policy, opts, vg, lv_size, pv_list)
+ cmd = test_opt + [mklv_cmd, "-t", lv_type, "-y", lv, "-c", copies, "-e", lv_policy, opts, vg, "%sM" % (lv_size, )] + pvs
rc, out, err = module.run_command(cmd)
if rc == 0:
module.exit_json(changed=True, msg="Logical volume %s created." % lv)
@@ -306,7 +303,7 @@ def main():
if state == 'absent':
# remove LV
rmlv_cmd = module.get_bin_path("rmlv", required=True)
- rc, out, err = module.run_command("%s %s -f %s" % (test_opt, rmlv_cmd, this_lv['name']))
+ rc, out, err = module.run_command(test_opt + [rmlv_cmd, "-f", this_lv['name']])
if rc == 0:
module.exit_json(changed=True, msg="Logical volume %s deleted." % lv)
else:
@@ -315,7 +312,7 @@ def main():
if this_lv['policy'] != policy:
# change lv allocation policy
chlv_cmd = module.get_bin_path("chlv", required=True)
- rc, out, err = module.run_command("%s %s -e %s %s" % (test_opt, chlv_cmd, lv_policy, this_lv['name']))
+ rc, out, err = module.run_command(test_opt + [chlv_cmd, "-e", lv_policy, this_lv['name']])
if rc == 0:
module.exit_json(changed=True, msg="Logical volume %s policy changed: %s." % (lv, policy))
else:
@@ -331,7 +328,7 @@ def main():
# resize LV based on absolute values
if int(lv_size) > this_lv['size']:
extendlv_cmd = module.get_bin_path("extendlv", required=True)
- cmd = "%s %s %s %sM" % (test_opt, extendlv_cmd, lv, lv_size - this_lv['size'])
+ cmd = test_opt + [extendlv_cmd, lv, "%sM" % (lv_size - this_lv['size'], )]
rc, out, err = module.run_command(cmd)
if rc == 0:
module.exit_json(changed=True, msg="Logical volume %s size extended to %sMB." % (lv, lv_size))
diff --git a/ansible_collections/community/general/plugins/modules/ansible_galaxy_install.py b/ansible_collections/community/general/plugins/modules/ansible_galaxy_install.py
index 3b0a8fd47..d382ed93a 100644
--- a/ansible_collections/community/general/plugins/modules/ansible_galaxy_install.py
+++ b/ansible_collections/community/general/plugins/modules/ansible_galaxy_install.py
@@ -73,16 +73,6 @@ options:
- Using O(force=true) is mandatory when downgrading.
type: bool
default: false
- ack_ansible29:
- description:
- - This option has no longer any effect and will be removed in community.general 9.0.0.
- type: bool
- default: false
- ack_min_ansiblecore211:
- description:
- - This option has no longer any effect and will be removed in community.general 9.0.0.
- type: bool
- default: false
"""
EXAMPLES = """
@@ -181,7 +171,7 @@ RETURN = """
import re
-from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt as fmt
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper, ModuleHelperException
@@ -190,7 +180,9 @@ class AnsibleGalaxyInstall(ModuleHelper):
_RE_LIST_PATH = re.compile(r'^# (?P<path>.*)$')
_RE_LIST_COLL = re.compile(r'^(?P<elem>\w+\.\w+)\s+(?P<version>[\d\.]+)\s*$')
_RE_LIST_ROLE = re.compile(r'^- (?P<elem>\w+\.\w+),\s+(?P<version>[\d\.]+)\s*$')
- _RE_INSTALL_OUTPUT = None # Set after determining ansible version, see __init_module__()
+ _RE_INSTALL_OUTPUT = re.compile(
+ r'^(?:(?P<collection>\w+\.\w+):(?P<cversion>[\d\.]+)|- (?P<role>\w+\.\w+) \((?P<rversion>[\d\.]+)\)) was installed successfully$'
+ )
ansible_version = None
output_params = ('type', 'name', 'dest', 'requirements_file', 'force', 'no_deps')
@@ -202,35 +194,24 @@ class AnsibleGalaxyInstall(ModuleHelper):
dest=dict(type='path'),
force=dict(type='bool', default=False),
no_deps=dict(type='bool', default=False),
- ack_ansible29=dict(
- type='bool',
- default=False,
- removed_in_version='9.0.0',
- removed_from_collection='community.general',
- ),
- ack_min_ansiblecore211=dict(
- type='bool',
- default=False,
- removed_in_version='9.0.0',
- removed_from_collection='community.general',
- ),
),
mutually_exclusive=[('name', 'requirements_file')],
required_one_of=[('name', 'requirements_file')],
required_if=[('type', 'both', ['requirements_file'])],
supports_check_mode=False,
)
+ use_old_vardict = False
command = 'ansible-galaxy'
command_args_formats = dict(
- type=fmt.as_func(lambda v: [] if v == 'both' else [v]),
- galaxy_cmd=fmt.as_list(),
- requirements_file=fmt.as_opt_val('-r'),
- dest=fmt.as_opt_val('-p'),
- force=fmt.as_bool("--force"),
- no_deps=fmt.as_bool("--no-deps"),
- version=fmt.as_bool("--version"),
- name=fmt.as_list(),
+ type=cmd_runner_fmt.as_func(lambda v: [] if v == 'both' else [v]),
+ galaxy_cmd=cmd_runner_fmt.as_list(),
+ requirements_file=cmd_runner_fmt.as_opt_val('-r'),
+ dest=cmd_runner_fmt.as_opt_val('-p'),
+ force=cmd_runner_fmt.as_bool("--force"),
+ no_deps=cmd_runner_fmt.as_bool("--no-deps"),
+ version=cmd_runner_fmt.as_fixed("--version"),
+ name=cmd_runner_fmt.as_list(),
)
def _make_runner(self, lang):
@@ -254,25 +235,18 @@ class AnsibleGalaxyInstall(ModuleHelper):
try:
runner = self._make_runner("C.UTF-8")
with runner("version", check_rc=False, output_process=process) as ctx:
- return runner, ctx.run(version=True)
- except UnsupportedLocale as e:
+ return runner, ctx.run()
+ except UnsupportedLocale:
runner = self._make_runner("en_US.UTF-8")
with runner("version", check_rc=True, output_process=process) as ctx:
- return runner, ctx.run(version=True)
+ return runner, ctx.run()
def __init_module__(self):
- # self.runner = CmdRunner(self.module, command=self.command, arg_formats=self.command_args_formats, force_lang=self.force_lang)
self.runner, self.ansible_version = self._get_ansible_galaxy_version()
if self.ansible_version < (2, 11):
self.module.fail_json(
- msg="Support for Ansible 2.9 and ansible-base 2.10 has ben removed."
+ msg="Support for Ansible 2.9 and ansible-base 2.10 has been removed."
)
- # Collection install output changed:
- # ansible-base 2.10: "coll.name (x.y.z)"
- # ansible-core 2.11+: "coll.name:x.y.z"
- self._RE_INSTALL_OUTPUT = re.compile(r'^(?:(?P<collection>\w+\.\w+)(?: \(|:)(?P<cversion>[\d\.]+)\)?'
- r'|- (?P<role>\w+\.\w+) \((?P<rversion>[\d\.]+)\))'
- r' was installed successfully$')
self.vars.set("new_collections", {}, change=True)
self.vars.set("new_roles", {}, change=True)
if self.vars.type != "collection":
diff --git a/ansible_collections/community/general/plugins/modules/apt_rpm.py b/ansible_collections/community/general/plugins/modules/apt_rpm.py
index 03b87e78f..3a0b6d805 100644
--- a/ansible_collections/community/general/plugins/modules/apt_rpm.py
+++ b/ansible_collections/community/general/plugins/modules/apt_rpm.py
@@ -170,7 +170,7 @@ def local_rpm_package_name(path):
def query_package(module, name):
# rpm -q returns 0 if the package is installed,
# 1 if it is not installed
- rc, out, err = module.run_command("%s -q %s" % (RPM_PATH, name))
+ rc, out, err = module.run_command([RPM_PATH, "-q", name])
if rc == 0:
return True
else:
@@ -203,7 +203,7 @@ def query_package_provides(module, name, allow_upgrade=False):
name = local_rpm_package_name(name)
- rc, out, err = module.run_command("%s -q --provides %s" % (RPM_PATH, name))
+ rc, out, err = module.run_command([RPM_PATH, "-q", "--provides", name])
if rc == 0:
if not allow_upgrade:
return True
@@ -253,7 +253,7 @@ def remove_packages(module, packages):
if not query_package(module, package):
continue
- rc, out, err = module.run_command("%s -y remove %s" % (APT_PATH, package), environ_update={"LANG": "C"})
+ rc, out, err = module.run_command([APT_PATH, "-y", "remove", package], environ_update={"LANG": "C"})
if rc != 0:
module.fail_json(msg="failed to remove %s: %s" % (package, err))
@@ -271,14 +271,14 @@ def install_packages(module, pkgspec, allow_upgrade=False):
if pkgspec is None:
return (False, "Empty package list")
- packages = ""
+ packages = []
for package in pkgspec:
if not query_package_provides(module, package, allow_upgrade=allow_upgrade):
- packages += "'%s' " % package
+ packages.append(package)
- if len(packages) != 0:
-
- rc, out, err = module.run_command("%s -y install %s" % (APT_PATH, packages), environ_update={"LANG": "C"})
+ if packages:
+ command = [APT_PATH, "-y", "install"] + packages
+ rc, out, err = module.run_command(command, environ_update={"LANG": "C"})
installed = True
for package in pkgspec:
@@ -287,7 +287,7 @@ def install_packages(module, pkgspec, allow_upgrade=False):
# apt-rpm always have 0 for exit code if --force is used
if rc or not installed:
- module.fail_json(msg="'apt-get -y install %s' failed: %s" % (packages, err))
+ module.fail_json(msg="'%s' failed: %s" % (" ".join(command), err))
else:
return (True, "%s present(s)" % packages)
else:
@@ -310,6 +310,18 @@ def main():
module.fail_json(msg="cannot find /usr/bin/apt-get and/or /usr/bin/rpm")
p = module.params
+ if p['state'] in ['installed', 'present']:
+ module.deprecate(
+ 'state=%s currently behaves unexpectedly by always upgrading to the latest version if'
+ ' the package is already installed. This behavior is deprecated and will change in'
+ ' community.general 11.0.0. You can use state=latest to explicitly request this behavior'
+ ' or state=present_not_latest to explicitly request the behavior that state=%s will have'
+ ' in community.general 11.0.0, namely that the package will not be upgraded if it is'
+ ' already installed.' % (p['state'], p['state']),
+ version='11.0.0',
+ collection_name='community.general',
+ )
+
modified = False
output = ""
diff --git a/ansible_collections/community/general/plugins/modules/btrfs_subvolume.py b/ansible_collections/community/general/plugins/modules/btrfs_subvolume.py
index 864bb65a6..35327bfe0 100644
--- a/ansible_collections/community/general/plugins/modules/btrfs_subvolume.py
+++ b/ansible_collections/community/general/plugins/modules/btrfs_subvolume.py
@@ -572,10 +572,7 @@ class BtrfsSubvolumeModule(object):
self.__temporary_mounts[cache_key] = mountpoint
mount = self.module.get_bin_path("mount", required=True)
- command = "%s -o noatime,subvolid=%d %s %s " % (mount,
- subvolid,
- device,
- mountpoint)
+ command = [mount, "-o", "noatime,subvolid=%d" % subvolid, device, mountpoint]
result = self.module.run_command(command, check_rc=True)
return mountpoint
@@ -586,10 +583,10 @@ class BtrfsSubvolumeModule(object):
def __cleanup_mount(self, mountpoint):
umount = self.module.get_bin_path("umount", required=True)
- result = self.module.run_command("%s %s" % (umount, mountpoint))
+ result = self.module.run_command([umount, mountpoint])
if result[0] == 0:
rmdir = self.module.get_bin_path("rmdir", required=True)
- self.module.run_command("%s %s" % (rmdir, mountpoint))
+ self.module.run_command([rmdir, mountpoint])
# Format and return results
def get_results(self):
diff --git a/ansible_collections/community/general/plugins/modules/cloudflare_dns.py b/ansible_collections/community/general/plugins/modules/cloudflare_dns.py
index d2bea4266..190497644 100644
--- a/ansible_collections/community/general/plugins/modules/cloudflare_dns.py
+++ b/ansible_collections/community/general/plugins/modules/cloudflare_dns.py
@@ -148,9 +148,9 @@ options:
type:
description:
- The type of DNS record to create. Required if O(state=present).
- - Note that V(SPF) is no longer supported by CloudFlare. Support for it will be removed from community.general 9.0.0.
+ - Support for V(SPF) has been removed from community.general 9.0.0 since that record type is no longer supported by CloudFlare.
type: str
- choices: [ A, AAAA, CNAME, DS, MX, NS, SPF, SRV, SSHFP, TLSA, CAA, TXT ]
+ choices: [ A, AAAA, CNAME, DS, MX, NS, SRV, SSHFP, TLSA, CAA, TXT ]
value:
description:
- The record value.
@@ -674,7 +674,7 @@ class CloudflareAPI(object):
if (params['type'] is None) or (params['record'] is None):
self.module.fail_json(msg="You must provide a type and a record to create a new record")
- if (params['type'] in ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS', 'SPF']):
+ if (params['type'] in ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS']):
if not params['value']:
self.module.fail_json(msg="You must provide a non-empty value to create this record type")
@@ -869,7 +869,7 @@ def main():
state=dict(type='str', default='present', choices=['absent', 'present']),
timeout=dict(type='int', default=30),
ttl=dict(type='int', default=1),
- type=dict(type='str', choices=['A', 'AAAA', 'CNAME', 'DS', 'MX', 'NS', 'SPF', 'SRV', 'SSHFP', 'TLSA', 'CAA', 'TXT']),
+ type=dict(type='str', choices=['A', 'AAAA', 'CNAME', 'DS', 'MX', 'NS', 'SRV', 'SSHFP', 'TLSA', 'CAA', 'TXT']),
value=dict(type='str', aliases=['content']),
weight=dict(type='int', default=1),
zone=dict(type='str', required=True, aliases=['domain']),
diff --git a/ansible_collections/community/general/plugins/modules/consul_policy.py b/ansible_collections/community/general/plugins/modules/consul_policy.py
index f020622a0..2ed6021b0 100644
--- a/ansible_collections/community/general/plugins/modules/consul_policy.py
+++ b/ansible_collections/community/general/plugins/modules/consul_policy.py
@@ -33,6 +33,8 @@ attributes:
version_added: 8.3.0
details:
- In check mode the diff will miss operational attributes.
+ action_group:
+ version_added: 8.3.0
options:
state:
description:
diff --git a/ansible_collections/community/general/plugins/modules/consul_role.py b/ansible_collections/community/general/plugins/modules/consul_role.py
index 0da71507a..e07e2036f 100644
--- a/ansible_collections/community/general/plugins/modules/consul_role.py
+++ b/ansible_collections/community/general/plugins/modules/consul_role.py
@@ -32,6 +32,8 @@ attributes:
details:
- In check mode the diff will miss operational attributes.
version_added: 8.3.0
+ action_group:
+ version_added: 8.3.0
options:
name:
description:
diff --git a/ansible_collections/community/general/plugins/modules/consul_session.py b/ansible_collections/community/general/plugins/modules/consul_session.py
index bd03b561a..87a5f1914 100644
--- a/ansible_collections/community/general/plugins/modules/consul_session.py
+++ b/ansible_collections/community/general/plugins/modules/consul_session.py
@@ -29,6 +29,8 @@ attributes:
support: none
diff_mode:
support: none
+ action_group:
+ version_added: 8.3.0
options:
id:
description:
diff --git a/ansible_collections/community/general/plugins/modules/consul_token.py b/ansible_collections/community/general/plugins/modules/consul_token.py
index eee419863..02bc544da 100644
--- a/ansible_collections/community/general/plugins/modules/consul_token.py
+++ b/ansible_collections/community/general/plugins/modules/consul_token.py
@@ -31,6 +31,8 @@ attributes:
support: partial
details:
- In check mode the diff will miss operational attributes.
+ action_group:
+ version_added: 8.3.0
options:
state:
description:
diff --git a/ansible_collections/community/general/plugins/modules/cpanm.py b/ansible_collections/community/general/plugins/modules/cpanm.py
index 20ac3e714..3beae895d 100644
--- a/ansible_collections/community/general/plugins/modules/cpanm.py
+++ b/ansible_collections/community/general/plugins/modules/cpanm.py
@@ -68,9 +68,10 @@ options:
mode:
description:
- Controls the module behavior. See notes below for more details.
- - Default is V(compatibility) but that behavior is deprecated and will be changed to V(new) in community.general 9.0.0.
+ - The default changed from V(compatibility) to V(new) in community.general 9.0.0.
type: str
choices: [compatibility, new]
+ default: new
version_added: 3.0.0
name_check:
description:
@@ -80,12 +81,16 @@ options:
notes:
- Please note that U(http://search.cpan.org/dist/App-cpanminus/bin/cpanm, cpanm) must be installed on the remote host.
- "This module now comes with a choice of execution O(mode): V(compatibility) or V(new)."
- - "O(mode=compatibility): When using V(compatibility) mode, the module will keep backward compatibility. This is the default mode.
+ - >
+ O(mode=compatibility): When using V(compatibility) mode, the module will keep backward compatibility.
+ This was the default mode before community.general 9.0.0.
O(name) must be either a module name or a distribution file. If the perl module given by O(name) is installed (at the exact O(version)
when specified), then nothing happens. Otherwise, it will be installed using the C(cpanm) executable. O(name) cannot be an URL, or a git URL.
- C(cpanm) version specifiers do not work in this mode."
- - "O(mode=new): When using V(new) mode, the module will behave differently. The O(name) parameter may refer to a module name, a distribution file,
- a HTTP URL or a git repository URL as described in C(cpanminus) documentation. C(cpanm) version specifiers are recognized."
+ C(cpanm) version specifiers do not work in this mode.
+ - >
+ O(mode=new): When using V(new) mode, the module will behave differently. The O(name) parameter may refer to a module name, a distribution file,
+ a HTTP URL or a git repository URL as described in C(cpanminus) documentation. C(cpanm) version specifiers are recognized.
+ This is the default mode from community.general 9.0.0 onwards.
author:
- "Franck Cuny (@fcuny)"
- "Alexei Znamensky (@russoz)"
@@ -150,7 +155,7 @@ class CPANMinus(ModuleHelper):
mirror_only=dict(type='bool', default=False),
installdeps=dict(type='bool', default=False),
executable=dict(type='path'),
- mode=dict(type='str', choices=['compatibility', 'new']),
+ mode=dict(type='str', default='new', choices=['compatibility', 'new']),
name_check=dict(type='str')
),
required_one_of=[('name', 'from_path')],
@@ -165,17 +170,10 @@ class CPANMinus(ModuleHelper):
installdeps=cmd_runner_fmt.as_bool("--installdeps"),
pkg_spec=cmd_runner_fmt.as_list(),
)
+ use_old_vardict = False
def __init_module__(self):
v = self.vars
- if v.mode is None:
- self.deprecate(
- "The default value 'compatibility' for parameter 'mode' is being deprecated "
- "and it will be replaced by 'new'",
- version="9.0.0",
- collection_name="community.general"
- )
- v.mode = "compatibility"
if v.mode == "compatibility":
if v.name_check:
self.do_raise("Parameter name_check can only be used with mode=new")
diff --git a/ansible_collections/community/general/plugins/modules/django_command.py b/ansible_collections/community/general/plugins/modules/django_command.py
new file mode 100644
index 000000000..788f4a100
--- /dev/null
+++ b/ansible_collections/community/general/plugins/modules/django_command.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: django_command
+author:
+ - Alexei Znamensky (@russoz)
+short_description: Run Django admin commands
+version_added: 9.0.0
+description:
+ - This module allows the execution of arbitrary Django admin commands.
+extends_documentation_fragment:
+ - community.general.attributes
+ - community.general.django
+attributes:
+ check_mode:
+ support: none
+ diff_mode:
+ support: none
+options:
+ command:
+ description:
+ - Django admin command. It must be a valid command accepted by C(python -m django) at the target system.
+ type: str
+ required: true
+ extra_args:
+ type: list
+ elements: str
+ description:
+ - List of extra arguments passed to the django admin command.
+"""
+
+EXAMPLES = """
+- name: Check the project
+ community.general.django_command:
+ command: check
+ settings: myproject.settings
+
+- name: Check the project in specified python path, using virtual environment
+ community.general.django_command:
+ command: check
+ settings: fancysite.settings
+ pythonpath: /home/joedoe/project/fancysite
+ venv: /home/joedoe/project/fancysite/venv
+"""
+
+RETURN = """
+run_info:
+ description: Command-line execution information.
+ type: dict
+ returned: success and O(verbosity) >= 3
+"""
+
+from ansible_collections.community.general.plugins.module_utils.django import DjangoModuleHelper
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
+
+
+class DjangoCommand(DjangoModuleHelper):
+ module = dict(
+ argument_spec=dict(
+ command=dict(type="str", required=True),
+ extra_args=dict(type="list", elements="str"),
+ ),
+ supports_check_mode=False,
+ )
+ arg_formats = dict(
+ extra_args=cmd_runner_fmt.as_list(),
+ )
+ django_admin_arg_order = "extra_args"
+
+
+def main():
+ DjangoCommand.execute()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/plugins/modules/django_manage.py b/ansible_collections/community/general/plugins/modules/django_manage.py
index 114ec0353..352bfe4b5 100644
--- a/ansible_collections/community/general/plugins/modules/django_manage.py
+++ b/ansible_collections/community/general/plugins/modules/django_manage.py
@@ -28,23 +28,16 @@ options:
command:
description:
- The name of the Django management command to run. The commands listed below are built in this module and have some basic parameter validation.
- - >
- V(cleanup) - clean up old data from the database (deprecated in Django 1.5). This parameter will be
- removed in community.general 9.0.0. Use V(clearsessions) instead.
- V(collectstatic) - Collects the static files into C(STATIC_ROOT).
- V(createcachetable) - Creates the cache tables for use with the database cache backend.
- V(flush) - Removes all data from the database.
- V(loaddata) - Searches for and loads the contents of the named O(fixtures) into the database.
- V(migrate) - Synchronizes the database state with models and migrations.
- - >
- V(syncdb) - Synchronizes the database state with models and migrations (deprecated in Django 1.7).
- This parameter will be removed in community.general 9.0.0. Use V(migrate) instead.
- V(test) - Runs tests for all installed apps.
- - >
- V(validate) - Validates all installed models (deprecated in Django 1.7). This parameter will be
- removed in community.general 9.0.0. Use V(check) instead.
- - Other commands can be entered, but will fail if they are unknown to Django. Other commands that may
+ - Other commands can be entered, but will fail if they are unknown to Django. Other commands that may
prompt for user input should be run with the C(--noinput) flag.
+ - Support for the values V(cleanup), V(syncdb), V(validate) was removed in community.general 9.0.0.
+ See note about supported versions of Django.
type: str
required: true
project_path:
@@ -69,6 +62,7 @@ options:
virtualenv:
description:
- An optional path to a C(virtualenv) installation to use while running the manage application.
+ - The virtual environment must exist, otherwise the module will fail.
type: path
aliases: [virtual_env]
apps:
@@ -132,31 +126,24 @@ options:
aliases: [test_runner]
ack_venv_creation_deprecation:
description:
- - >-
- When a O(virtualenv) is set but the virtual environment does not exist, the current behavior is
- to create a new virtual environment. That behavior is deprecated and if that case happens it will
- generate a deprecation warning. Set this flag to V(true) to suppress the deprecation warning.
- - Please note that you will receive no further warning about this being removed until the module
- will start failing in such cases from community.general 9.0.0 on.
+ - This option no longer has any effect since community.general 9.0.0.
+ - It will be removed from community.general 11.0.0.
type: bool
version_added: 5.8.0
notes:
- >
- B(ATTENTION - DEPRECATION): Support for Django releases older than 4.1 will be removed in
- community.general version 9.0.0 (estimated to be released in May 2024).
- Please notice that Django 4.1 requires Python 3.8 or greater.
- - C(virtualenv) (U(http://www.virtualenv.org)) must be installed on the remote host if the O(virtualenv) parameter
- is specified. This requirement is deprecated and will be removed in community.general version 9.0.0.
- - This module will create a virtualenv if the O(virtualenv) parameter is specified and a virtual environment does not already
- exist at the given location. This behavior is deprecated and will be removed in community.general version 9.0.0.
- - The parameter O(virtualenv) will remain in use, but it will require the specified virtualenv to exist.
- The recommended way to create one in Ansible is by using M(ansible.builtin.pip).
+ B(ATTENTION): Support for Django releases older than 4.1 has been removed in
+ community.general version 9.0.0. While the module allows for free-form commands
+ does not verify the version of Django being used, it is B(strongly recommended)
+ to use a more recent version of Django.
+ - Please notice that Django 4.1 requires Python 3.8 or greater.
+ - This module will not create a virtualenv if the O(virtualenv) parameter is specified and a virtual environment
+ does not already exist at the given location. This behavior changed in community.general version 9.0.0.
+ - The recommended way to create a virtual environment in Ansible is by using M(ansible.builtin.pip).
- This module assumes English error messages for the V(createcachetable) command to detect table existence,
unfortunately.
- - To be able to use the V(migrate) command with django versions < 1.7, you must have C(south) installed and added
- as an app in your settings.
- - To be able to use the V(collectstatic) command, you must have enabled staticfiles in your settings.
+ - To be able to use the V(collectstatic) command, you must have enabled C(staticfiles) in your settings.
- Your C(manage.py) application must be executable (C(rwxr-xr-x)), and must have a valid shebang,
for example C(#!/usr/bin/env python), for invoking the appropriate Python interpreter.
seealso:
@@ -169,7 +156,7 @@ seealso:
- name: What Python version can I use with Django?
description: From the Django FAQ, the response to Python requirements for the framework.
link: https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
-requirements: [ "virtualenv", "django" ]
+requirements: [ "django >= 4.1" ]
author:
- Alexei Znamensky (@russoz)
- Scott Anderson (@tastychutney)
@@ -178,7 +165,7 @@ author:
EXAMPLES = """
- name: Run cleanup on the application installed in django_dir
community.general.django_manage:
- command: cleanup
+ command: clearsessions
project_path: "{{ django_dir }}"
- name: Load the initial_data fixture into the application
@@ -189,7 +176,7 @@ EXAMPLES = """
- name: Run syncdb on the application
community.general.django_manage:
- command: syncdb
+ command: migrate
project_path: "{{ django_dir }}"
settings: "{{ settings_app_name }}"
pythonpath: "{{ settings_dir }}"
@@ -233,22 +220,7 @@ def _ensure_virtualenv(module):
activate = os.path.join(vbin, 'activate')
if not os.path.exists(activate):
- # In version 9.0.0, if the venv is not found, it should fail_json() here.
- if not module.params['ack_venv_creation_deprecation']:
- module.deprecate(
- 'The behavior of "creating the virtual environment when missing" is being '
- 'deprecated and will be removed in community.general version 9.0.0. '
- 'Set the module parameter `ack_venv_creation_deprecation: true` to '
- 'prevent this message from showing up when creating a virtualenv.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- virtualenv = module.get_bin_path('virtualenv', True)
- vcmd = [virtualenv, venv_param]
- rc, out_venv, err_venv = module.run_command(vcmd)
- if rc != 0:
- _fail(module, vcmd, out_venv, err_venv)
+ module.fail_json(msg='%s does not point to a valid virtual environment' % venv_param)
os.environ["PATH"] = "%s:%s" % (vbin, os.environ["PATH"])
os.environ["VIRTUAL_ENV"] = venv_param
@@ -266,11 +238,6 @@ def loaddata_filter_output(line):
return "Installed" in line and "Installed 0 object" not in line
-def syncdb_filter_output(line):
- return ("Creating table " in line) \
- or ("Installed" in line and "Installed 0 object" not in line)
-
-
def migrate_filter_output(line):
return ("Migrating forwards " in line) \
or ("Installed" in line and "Installed 0 object" not in line) \
@@ -283,13 +250,10 @@ def collectstatic_filter_output(line):
def main():
command_allowed_param_map = dict(
- cleanup=(),
createcachetable=('cache_table', 'database', ),
flush=('database', ),
loaddata=('database', 'fixtures', ),
- syncdb=('database', ),
test=('failfast', 'testrunner', 'apps', ),
- validate=(),
migrate=('apps', 'skip', 'merge', 'database',),
collectstatic=('clear', 'link', ),
)
@@ -301,7 +265,6 @@ def main():
# forces --noinput on every command that needs it
noinput_commands = (
'flush',
- 'syncdb',
'migrate',
'test',
'collectstatic',
@@ -333,7 +296,7 @@ def main():
skip=dict(type='bool'),
merge=dict(type='bool'),
link=dict(type='bool'),
- ack_venv_creation_deprecation=dict(type='bool'),
+ ack_venv_creation_deprecation=dict(type='bool', removed_in_version='11.0.0', removed_from_collection='community.general'),
),
)
@@ -342,21 +305,6 @@ def main():
project_path = module.params['project_path']
virtualenv = module.params['virtualenv']
- try:
- _deprecation = dict(
- cleanup="clearsessions",
- syncdb="migrate",
- validate="check",
- )
- module.deprecate(
- 'The command {0} has been deprecated as it is no longer supported in recent Django versions.'
- 'Please use the command {1} instead that provide similar capability.'.format(command_bin, _deprecation[command_bin]),
- version='9.0.0',
- collection_name='community.general'
- )
- except KeyError:
- pass
-
for param in specific_params:
value = module.params[param]
if value and param not in command_allowed_param_map[command_bin]:
diff --git a/ansible_collections/community/general/plugins/modules/flowdock.py b/ansible_collections/community/general/plugins/modules/flowdock.py
deleted file mode 100644
index 0e8a7461d..000000000
--- a/ansible_collections/community/general/plugins/modules/flowdock.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright 2013 Matt Coddington <coddington@gmail.com>
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: flowdock
-author: "Matt Coddington (@mcodd)"
-short_description: Send a message to a flowdock
-description:
- - Send a message to a flowdock team inbox or chat using the push API (see https://www.flowdock.com/api/team-inbox and https://www.flowdock.com/api/chat)
-extends_documentation_fragment:
- - community.general.attributes
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-options:
- token:
- type: str
- description:
- - API token.
- required: true
- type:
- type: str
- description:
- - Whether to post to 'inbox' or 'chat'
- required: true
- choices: [ "inbox", "chat" ]
- msg:
- type: str
- description:
- - Content of the message
- required: true
- tags:
- type: str
- description:
- - tags of the message, separated by commas
- required: false
- external_user_name:
- type: str
- description:
- - (chat only - required) Name of the "user" sending the message
- required: false
- from_address:
- type: str
- description:
- - (inbox only - required) Email address of the message sender
- required: false
- source:
- type: str
- description:
- - (inbox only - required) Human readable identifier of the application that uses the Flowdock API
- required: false
- subject:
- type: str
- description:
- - (inbox only - required) Subject line of the message
- required: false
- from_name:
- type: str
- description:
- - (inbox only) Name of the message sender
- required: false
- reply_to:
- type: str
- description:
- - (inbox only) Email address for replies
- required: false
- project:
- type: str
- description:
- - (inbox only) Human readable identifier for more detailed message categorization
- required: false
- link:
- type: str
- description:
- - (inbox only) Link associated with the message. This will be used to link the message subject in Team Inbox.
- required: false
- validate_certs:
- description:
- - If V(false), SSL certificates will not be validated. This should only be used
- on personally controlled sites using self-signed certificates.
- required: false
- default: true
- type: bool
-
-requirements: [ ]
-'''
-
-EXAMPLES = '''
-- name: Send a message to a flowdock
- community.general.flowdock:
- type: inbox
- token: AAAAAA
- from_address: user@example.com
- source: my cool app
- msg: test from ansible
- subject: test subject
-
-- name: Send a message to a flowdock
- community.general.flowdock:
- type: chat
- token: AAAAAA
- external_user_name: testuser
- msg: test from ansible
- tags: tag1,tag2,tag3
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves.urllib.parse import urlencode
-from ansible.module_utils.urls import fetch_url
-
-
-# ===========================================
-# Module execution.
-#
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict(
- token=dict(required=True, no_log=True),
- msg=dict(required=True),
- type=dict(required=True, choices=["inbox", "chat"]),
- external_user_name=dict(required=False),
- from_address=dict(required=False),
- source=dict(required=False),
- subject=dict(required=False),
- from_name=dict(required=False),
- reply_to=dict(required=False),
- project=dict(required=False),
- tags=dict(required=False),
- link=dict(required=False),
- validate_certs=dict(default=True, type='bool'),
- ),
- supports_check_mode=True
- )
-
- type = module.params["type"]
- token = module.params["token"]
- if type == 'inbox':
- url = "https://api.flowdock.com/v1/messages/team_inbox/%s" % (token)
- else:
- url = "https://api.flowdock.com/v1/messages/chat/%s" % (token)
-
- params = {}
-
- # required params
- params['content'] = module.params["msg"]
-
- # required params for the 'chat' type
- if module.params['external_user_name']:
- if type == 'inbox':
- module.fail_json(msg="external_user_name is not valid for the 'inbox' type")
- else:
- params['external_user_name'] = module.params["external_user_name"]
- elif type == 'chat':
- module.fail_json(msg="external_user_name is required for the 'chat' type")
-
- # required params for the 'inbox' type
- for item in ['from_address', 'source', 'subject']:
- if module.params[item]:
- if type == 'chat':
- module.fail_json(msg="%s is not valid for the 'chat' type" % item)
- else:
- params[item] = module.params[item]
- elif type == 'inbox':
- module.fail_json(msg="%s is required for the 'inbox' type" % item)
-
- # optional params
- if module.params["tags"]:
- params['tags'] = module.params["tags"]
-
- # optional params for the 'inbox' type
- for item in ['from_name', 'reply_to', 'project', 'link']:
- if module.params[item]:
- if type == 'chat':
- module.fail_json(msg="%s is not valid for the 'chat' type" % item)
- else:
- params[item] = module.params[item]
-
- # If we're in check mode, just exit pretending like we succeeded
- if module.check_mode:
- module.exit_json(changed=False)
-
- # Send the data to Flowdock
- data = urlencode(params)
- response, info = fetch_url(module, url, data=data)
- if info['status'] != 200:
- module.fail_json(msg="unable to send msg: %s" % info['msg'])
-
- module.exit_json(changed=True, msg=module.params["msg"])
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/gandi_livedns.py b/ansible_collections/community/general/plugins/modules/gandi_livedns.py
index fdb7993a5..ad2e96fd1 100644
--- a/ansible_collections/community/general/plugins/modules/gandi_livedns.py
+++ b/ansible_collections/community/general/plugins/modules/gandi_livedns.py
@@ -25,11 +25,19 @@ attributes:
diff_mode:
support: none
options:
+ personal_access_token:
+ description:
+ - Scoped API token.
+ - One of O(personal_access_token) and O(api_key) must be specified.
+ type: str
+ version_added: 9.0.0
api_key:
description:
- Account API token.
+ - Note that these type of keys are deprecated and might stop working at some point.
+ Use personal access tokens instead.
+ - One of O(personal_access_token) and O(api_key) must be specified.
type: str
- required: true
record:
description:
- Record to add.
@@ -73,7 +81,7 @@ EXAMPLES = r'''
values:
- 127.0.0.1
ttl: 7200
- api_key: dummyapitoken
+ personal_access_token: dummytoken
register: record
- name: Create a mail CNAME record to www.my.com domain
@@ -84,7 +92,7 @@ EXAMPLES = r'''
values:
- www
ttl: 7200
- api_key: dummyapitoken
+ personal_access_token: dummytoken
state: present
- name: Change its TTL
@@ -95,7 +103,7 @@ EXAMPLES = r'''
values:
- www
ttl: 10800
- api_key: dummyapitoken
+ personal_access_token: dummytoken
state: present
- name: Delete the record
@@ -103,8 +111,18 @@ EXAMPLES = r'''
domain: my.com
type: CNAME
record: mail
- api_key: dummyapitoken
+ personal_access_token: dummytoken
state: absent
+
+- name: Use a (deprecated) API Key
+ community.general.gandi_livedns:
+ domain: my.com
+ record: test
+ type: A
+ values:
+ - 127.0.0.1
+ ttl: 7200
+ api_key: dummyapikey
'''
RETURN = r'''
@@ -151,7 +169,8 @@ from ansible_collections.community.general.plugins.module_utils.gandi_livedns_ap
def main():
module = AnsibleModule(
argument_spec=dict(
- api_key=dict(type='str', required=True, no_log=True),
+ api_key=dict(type='str', no_log=True),
+ personal_access_token=dict(type='str', no_log=True),
record=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['absent', 'present']),
ttl=dict(type='int'),
@@ -163,6 +182,12 @@ def main():
required_if=[
('state', 'present', ['values', 'ttl']),
],
+ mutually_exclusive=[
+ ('api_key', 'personal_access_token'),
+ ],
+ required_one_of=[
+ ('api_key', 'personal_access_token'),
+ ],
)
gandi_api = GandiLiveDNSAPI(module)
diff --git a/ansible_collections/community/general/plugins/modules/gconftool2.py b/ansible_collections/community/general/plugins/modules/gconftool2.py
index a40304a16..db7c6dc88 100644
--- a/ansible_collections/community/general/plugins/modules/gconftool2.py
+++ b/ansible_collections/community/general/plugins/modules/gconftool2.py
@@ -123,6 +123,7 @@ class GConftool(StateModuleHelper):
],
supports_check_mode=True,
)
+ use_old_vardict = False
def __init_module__(self):
self.runner = gconftool2_runner(self.module, check_rc=True)
diff --git a/ansible_collections/community/general/plugins/modules/gconftool2_info.py b/ansible_collections/community/general/plugins/modules/gconftool2_info.py
index 282065b95..f66e2da8f 100644
--- a/ansible_collections/community/general/plugins/modules/gconftool2_info.py
+++ b/ansible_collections/community/general/plugins/modules/gconftool2_info.py
@@ -60,6 +60,7 @@ class GConftoolInfo(ModuleHelper):
),
supports_check_mode=True,
)
+ use_old_vardict = False
def __init_module__(self):
self.runner = gconftool2_runner(self.module, check_rc=True)
diff --git a/ansible_collections/community/general/plugins/modules/gitlab_runner.py b/ansible_collections/community/general/plugins/modules/gitlab_runner.py
index e6163a6b6..96b3eb3fa 100644
--- a/ansible_collections/community/general/plugins/modules/gitlab_runner.py
+++ b/ansible_collections/community/general/plugins/modules/gitlab_runner.py
@@ -15,17 +15,20 @@ DOCUMENTATION = '''
module: gitlab_runner
short_description: Create, modify and delete GitLab Runners
description:
- - Register, update and delete runners with the GitLab API.
+ - Register, update and delete runners on GitLab Server side with the GitLab API.
- All operations are performed using the GitLab API v4.
- - For details, consult the full API documentation at U(https://docs.gitlab.com/ee/api/runners.html).
+ - For details, consult the full API documentation at U(https://docs.gitlab.com/ee/api/runners.html)
+ and U(https://docs.gitlab.com/ee/api/users.html#create-a-runner-linked-to-a-user).
- A valid private API token is required for all operations. You can create as many tokens as you like using the GitLab web interface at
U(https://$GITLAB_URL/profile/personal_access_tokens).
- A valid registration token is required for registering a new runner.
To create shared runners, you need to ask your administrator to give you this token.
It can be found at U(https://$GITLAB_URL/admin/runners/).
+ - This module does not handle the C(gitlab-runner) process part, but only manages the runner on GitLab Server side through its API.
+ Once the module has created the runner, you may use the generated token to run C(gitlab-runner register) command
notes:
- To create a new runner at least the O(api_token), O(description) and O(api_url) options are required.
- - Runners need to have unique descriptions.
+ - Runners need to have unique descriptions, since this attribute is used as key for idempotency
author:
- Samy Coenen (@SamyCoenen)
- Guillaume Martinez (@Lunik)
@@ -153,7 +156,45 @@ options:
'''
EXAMPLES = '''
-- name: "Register runner"
+- name: Create an instance-level runner
+ community.general.gitlab_runner:
+ api_url: https://gitlab.example.com/
+ api_token: "{{ access_token }}"
+ description: Docker Machine t1
+ state: present
+ active: true
+ tag_list: ['docker']
+ run_untagged: false
+ locked: false
+ register: runner # Register module output to run C(gitlab-runner register) command in another task
+
+- name: Create a group-level runner
+ community.general.gitlab_runner:
+ api_url: https://gitlab.example.com/
+ api_token: "{{ access_token }}"
+ description: Docker Machine t1
+ state: present
+ active: true
+ tag_list: ['docker']
+ run_untagged: false
+ locked: false
+ group: top-level-group/subgroup
+ register: runner # Register module output to run C(gitlab-runner register) command in another task
+
+- name: Create a project-level runner
+ community.general.gitlab_runner:
+ api_url: https://gitlab.example.com/
+ api_token: "{{ access_token }}"
+ description: Docker Machine t1
+ state: present
+ active: true
+ tag_list: ['docker']
+ run_untagged: false
+ locked: false
+ project: top-level-group/subgroup/project
+ register: runner # Register module output to run C(gitlab-runner register) command in another task
+
+- name: "Register instance-level runner with registration token (deprecated)"
community.general.gitlab_runner:
api_url: https://gitlab.example.com/
api_token: "{{ access_token }}"
@@ -164,6 +205,7 @@ EXAMPLES = '''
tag_list: ['docker']
run_untagged: false
locked: false
+ register: runner # Register module output to run C(gitlab-runner register) command in another task
- name: "Delete runner"
community.general.gitlab_runner:
@@ -180,7 +222,7 @@ EXAMPLES = '''
owned: true
state: absent
-- name: Register runner for a specific project
+- name: "Register a project-level runner with registration token (deprecated)"
community.general.gitlab_runner:
api_url: https://gitlab.example.com/
api_token: "{{ access_token }}"
@@ -188,6 +230,7 @@ EXAMPLES = '''
description: MyProject runner
state: present
project: mygroup/mysubgroup/myproject
+ register: runner # Register module output to run C(gitlab-runner register) command in another task
'''
RETURN = '''
diff --git a/ansible_collections/community/general/plugins/modules/homebrew.py b/ansible_collections/community/general/plugins/modules/homebrew.py
index 5d471797a..2b60846b4 100644
--- a/ansible_collections/community/general/plugins/modules/homebrew.py
+++ b/ansible_collections/community/general/plugins/modules/homebrew.py
@@ -76,6 +76,13 @@ options:
type: list
elements: str
version_added: '0.2.0'
+ force_formula:
+ description:
+ - Force the package(s) to be treated as a formula (equivalent to C(brew --formula)).
+ - To install a cask, use the M(community.general.homebrew_cask) module.
+ type: bool
+ default: false
+ version_added: 9.0.0
notes:
- When used with a C(loop:) each package will be processed individually,
it is much more efficient to pass the list directly to the O(name) option.
@@ -141,6 +148,12 @@ EXAMPLES = '''
community.general.homebrew:
upgrade_all: true
upgrade_options: ignore-pinned
+
+- name: Force installing a formula whose name is also a cask name
+ community.general.homebrew:
+ name: ambiguous_formula
+ state: present
+ force_formula: true
'''
RETURN = '''
@@ -166,9 +179,10 @@ changed_pkgs:
'''
import json
-import os.path
import re
+from ansible_collections.community.general.plugins.module_utils.homebrew import HomebrewValidate
+
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems, string_types
@@ -195,99 +209,8 @@ def _check_package_in_json(json_output, package_type):
class Homebrew(object):
'''A class to manage Homebrew packages.'''
- # class regexes ------------------------------------------------ {{{
- VALID_PATH_CHARS = r'''
- \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
- \s # spaces
- : # colons
- {sep} # the OS-specific path separator
- . # dots
- \- # dashes
- '''.format(sep=os.path.sep)
-
- VALID_BREW_PATH_CHARS = r'''
- \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
- \s # spaces
- {sep} # the OS-specific path separator
- . # dots
- \- # dashes
- '''.format(sep=os.path.sep)
-
- VALID_PACKAGE_CHARS = r'''
- \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
- . # dots
- / # slash (for taps)
- \+ # plusses
- \- # dashes
- : # colons (for URLs)
- @ # at-sign
- '''
-
- INVALID_PATH_REGEX = _create_regex_group_complement(VALID_PATH_CHARS)
- INVALID_BREW_PATH_REGEX = _create_regex_group_complement(VALID_BREW_PATH_CHARS)
- INVALID_PACKAGE_REGEX = _create_regex_group_complement(VALID_PACKAGE_CHARS)
- # /class regexes ----------------------------------------------- }}}
-
# class validations -------------------------------------------- {{{
@classmethod
- def valid_path(cls, path):
- '''
- `path` must be one of:
- - list of paths
- - a string containing only:
- - alphanumeric characters
- - dashes
- - dots
- - spaces
- - colons
- - os.path.sep
- '''
-
- if isinstance(path, string_types):
- return not cls.INVALID_PATH_REGEX.search(path)
-
- try:
- iter(path)
- except TypeError:
- return False
- else:
- paths = path
- return all(cls.valid_brew_path(path_) for path_ in paths)
-
- @classmethod
- def valid_brew_path(cls, brew_path):
- '''
- `brew_path` must be one of:
- - None
- - a string containing only:
- - alphanumeric characters
- - dashes
- - dots
- - spaces
- - os.path.sep
- '''
-
- if brew_path is None:
- return True
-
- return (
- isinstance(brew_path, string_types)
- and not cls.INVALID_BREW_PATH_REGEX.search(brew_path)
- )
-
- @classmethod
- def valid_package(cls, package):
- '''A valid package is either None or alphanumeric.'''
-
- if package is None:
- return True
-
- return (
- isinstance(package, string_types)
- and not cls.INVALID_PACKAGE_REGEX.search(package)
- )
-
- @classmethod
def valid_state(cls, state):
'''
A valid state is one of:
@@ -346,7 +269,7 @@ class Homebrew(object):
@path.setter
def path(self, path):
- if not self.valid_path(path):
+ if not HomebrewValidate.valid_path(path):
self._path = []
self.failed = True
self.message = 'Invalid path: {0}.'.format(path)
@@ -366,7 +289,7 @@ class Homebrew(object):
@brew_path.setter
def brew_path(self, brew_path):
- if not self.valid_brew_path(brew_path):
+ if not HomebrewValidate.valid_brew_path(brew_path):
self._brew_path = None
self.failed = True
self.message = 'Invalid brew_path: {0}.'.format(brew_path)
@@ -391,7 +314,7 @@ class Homebrew(object):
@current_package.setter
def current_package(self, package):
- if not self.valid_package(package):
+ if not HomebrewValidate.valid_package(package):
self._current_package = None
self.failed = True
self.message = 'Invalid package: {0}.'.format(package)
@@ -404,7 +327,8 @@ class Homebrew(object):
def __init__(self, module, path, packages=None, state=None,
update_homebrew=False, upgrade_all=False,
- install_options=None, upgrade_options=None):
+ install_options=None, upgrade_options=None,
+ force_formula=False):
if not install_options:
install_options = list()
if not upgrade_options:
@@ -414,7 +338,8 @@ class Homebrew(object):
state=state, update_homebrew=update_homebrew,
upgrade_all=upgrade_all,
install_options=install_options,
- upgrade_options=upgrade_options,)
+ upgrade_options=upgrade_options,
+ force_formula=force_formula)
self._prep()
@@ -476,7 +401,7 @@ class Homebrew(object):
# checks ------------------------------------------------------- {{{
def _current_package_is_installed(self):
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
self.failed = True
self.message = 'Invalid package: {0}.'.format(self.current_package)
raise HomebrewException(self.message)
@@ -487,17 +412,19 @@ class Homebrew(object):
"--json=v2",
self.current_package,
]
+ if self.force_formula:
+ cmd.append("--formula")
rc, out, err = self.module.run_command(cmd)
- if err:
+ if rc != 0:
self.failed = True
- self.message = err.strip()
+ self.message = err.strip() or ("Unknown failure with exit code %d" % rc)
raise HomebrewException(self.message)
data = json.loads(out)
return _check_package_in_json(data, "formulae") or _check_package_in_json(data, "casks")
def _current_package_is_outdated(self):
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
return False
rc, out, err = self.module.run_command([
@@ -509,7 +436,7 @@ class Homebrew(object):
return rc != 0
def _current_package_is_installed_from_head(self):
- if not Homebrew.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
return False
elif not self._current_package_is_installed():
return False
@@ -607,7 +534,7 @@ class Homebrew(object):
# installed ------------------------------ {{{
def _install_current_package(self):
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
self.failed = True
self.message = 'Invalid package: {0}.'.format(self.current_package)
raise HomebrewException(self.message)
@@ -632,10 +559,15 @@ class Homebrew(object):
else:
head = None
+ if self.force_formula:
+ formula = '--formula'
+ else:
+ formula = None
+
opts = (
[self.brew_path, 'install']
+ self.install_options
- + [self.current_package, head]
+ + [self.current_package, head, formula]
)
cmd = [opt for opt in opts if opt]
rc, out, err = self.module.run_command(cmd)
@@ -663,7 +595,7 @@ class Homebrew(object):
def _upgrade_current_package(self):
command = 'upgrade'
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
self.failed = True
self.message = 'Invalid package: {0}.'.format(self.current_package)
raise HomebrewException(self.message)
@@ -734,7 +666,7 @@ class Homebrew(object):
# uninstalled ---------------------------- {{{
def _uninstall_current_package(self):
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
self.failed = True
self.message = 'Invalid package: {0}.'.format(self.current_package)
raise HomebrewException(self.message)
@@ -783,7 +715,7 @@ class Homebrew(object):
# linked --------------------------------- {{{
def _link_current_package(self):
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
self.failed = True
self.message = 'Invalid package: {0}.'.format(self.current_package)
raise HomebrewException(self.message)
@@ -830,7 +762,7 @@ class Homebrew(object):
# unlinked ------------------------------- {{{
def _unlink_current_package(self):
- if not self.valid_package(self.current_package):
+ if not HomebrewValidate.valid_package(self.current_package):
self.failed = True
self.message = 'Invalid package: {0}.'.format(self.current_package)
raise HomebrewException(self.message)
@@ -919,7 +851,11 @@ def main():
default=None,
type='list',
elements='str',
- )
+ ),
+ force_formula=dict(
+ default=False,
+ type='bool',
+ ),
),
supports_check_mode=True,
)
@@ -951,6 +887,7 @@ def main():
if state in ('absent', 'removed', 'uninstalled'):
state = 'absent'
+ force_formula = p['force_formula']
update_homebrew = p['update_homebrew']
if not update_homebrew:
module.run_command_environ_update.update(
@@ -967,7 +904,7 @@ def main():
brew = Homebrew(module=module, path=path, packages=packages,
state=state, update_homebrew=update_homebrew,
upgrade_all=upgrade_all, install_options=install_options,
- upgrade_options=upgrade_options)
+ upgrade_options=upgrade_options, force_formula=force_formula)
(failed, changed, message) = brew.run()
changed_pkgs = brew.changed_pkgs
unchanged_pkgs = brew.unchanged_pkgs
diff --git a/ansible_collections/community/general/plugins/modules/homebrew_cask.py b/ansible_collections/community/general/plugins/modules/homebrew_cask.py
index c992693b6..dc9aea5db 100644
--- a/ansible_collections/community/general/plugins/modules/homebrew_cask.py
+++ b/ansible_collections/community/general/plugins/modules/homebrew_cask.py
@@ -158,6 +158,7 @@ import re
import tempfile
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
+from ansible_collections.community.general.plugins.module_utils.homebrew import HomebrewValidate
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.basic import AnsibleModule
@@ -183,23 +184,6 @@ class HomebrewCask(object):
'''A class to manage Homebrew casks.'''
# class regexes ------------------------------------------------ {{{
- VALID_PATH_CHARS = r'''
- \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
- \s # spaces
- : # colons
- {sep} # the OS-specific path separator
- . # dots
- \- # dashes
- '''.format(sep=os.path.sep)
-
- VALID_BREW_PATH_CHARS = r'''
- \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
- \s # spaces
- {sep} # the OS-specific path separator
- . # dots
- \- # dashes
- '''.format(sep=os.path.sep)
-
VALID_CASK_CHARS = r'''
\w # alphanumeric characters (i.e., [a-zA-Z0-9_])
. # dots
@@ -208,59 +192,11 @@ class HomebrewCask(object):
@ # at symbol
'''
- INVALID_PATH_REGEX = _create_regex_group_complement(VALID_PATH_CHARS)
- INVALID_BREW_PATH_REGEX = _create_regex_group_complement(VALID_BREW_PATH_CHARS)
INVALID_CASK_REGEX = _create_regex_group_complement(VALID_CASK_CHARS)
# /class regexes ----------------------------------------------- }}}
# class validations -------------------------------------------- {{{
@classmethod
- def valid_path(cls, path):
- '''
- `path` must be one of:
- - list of paths
- - a string containing only:
- - alphanumeric characters
- - dashes
- - dots
- - spaces
- - colons
- - os.path.sep
- '''
-
- if isinstance(path, (string_types)):
- return not cls.INVALID_PATH_REGEX.search(path)
-
- try:
- iter(path)
- except TypeError:
- return False
- else:
- paths = path
- return all(cls.valid_brew_path(path_) for path_ in paths)
-
- @classmethod
- def valid_brew_path(cls, brew_path):
- '''
- `brew_path` must be one of:
- - None
- - a string containing only:
- - alphanumeric characters
- - dashes
- - dots
- - spaces
- - os.path.sep
- '''
-
- if brew_path is None:
- return True
-
- return (
- isinstance(brew_path, string_types)
- and not cls.INVALID_BREW_PATH_REGEX.search(brew_path)
- )
-
- @classmethod
def valid_cask(cls, cask):
'''A valid cask is either None or alphanumeric + backslashes.'''
@@ -321,7 +257,7 @@ class HomebrewCask(object):
@path.setter
def path(self, path):
- if not self.valid_path(path):
+ if not HomebrewValidate.valid_path(path):
self._path = []
self.failed = True
self.message = 'Invalid path: {0}.'.format(path)
@@ -341,7 +277,7 @@ class HomebrewCask(object):
@brew_path.setter
def brew_path(self, brew_path):
- if not self.valid_brew_path(brew_path):
+ if not HomebrewValidate.valid_brew_path(brew_path):
self._brew_path = None
self.failed = True
self.message = 'Invalid brew_path: {0}.'.format(brew_path)
diff --git a/ansible_collections/community/general/plugins/modules/hponcfg.py b/ansible_collections/community/general/plugins/modules/hponcfg.py
index 612a20d92..206565a23 100644
--- a/ansible_collections/community/general/plugins/modules/hponcfg.py
+++ b/ansible_collections/community/general/plugins/modules/hponcfg.py
@@ -98,6 +98,7 @@ class HPOnCfg(ModuleHelper):
verbose=cmd_runner_fmt.as_bool("-v"),
minfw=cmd_runner_fmt.as_opt_val("-m"),
)
+ use_old_vardict = False
def __run__(self):
runner = CmdRunner(
diff --git a/ansible_collections/community/general/plugins/modules/installp.py b/ansible_collections/community/general/plugins/modules/installp.py
index 4b5a6949c..1531d2cad 100644
--- a/ansible_collections/community/general/plugins/modules/installp.py
+++ b/ansible_collections/community/general/plugins/modules/installp.py
@@ -106,7 +106,7 @@ def _check_new_pkg(module, package, repository_path):
if os.path.isdir(repository_path):
installp_cmd = module.get_bin_path('installp', True)
- rc, package_result, err = module.run_command("%s -l -MR -d %s" % (installp_cmd, repository_path))
+ rc, package_result, err = module.run_command([installp_cmd, "-l", "-MR", "-d", repository_path])
if rc != 0:
module.fail_json(msg="Failed to run installp.", rc=rc, err=err)
@@ -142,7 +142,7 @@ def _check_installed_pkg(module, package, repository_path):
"""
lslpp_cmd = module.get_bin_path('lslpp', True)
- rc, lslpp_result, err = module.run_command("%s -lcq %s*" % (lslpp_cmd, package))
+ rc, lslpp_result, err = module.run_command([lslpp_cmd, "-lcq", "%s*" % (package, )])
if rc == 1:
package_state = ' '.join(err.split()[-2:])
@@ -173,7 +173,7 @@ def remove(module, installp_cmd, packages):
if pkg_check:
if not module.check_mode:
- rc, remove_out, err = module.run_command("%s -u %s" % (installp_cmd, package))
+ rc, remove_out, err = module.run_command([installp_cmd, "-u", package])
if rc != 0:
module.fail_json(msg="Failed to run installp.", rc=rc, err=err)
remove_count += 1
@@ -202,8 +202,8 @@ def install(module, installp_cmd, packages, repository_path, accept_license):
already_installed_pkgs = {}
accept_license_param = {
- True: '-Y',
- False: '',
+ True: ['-Y'],
+ False: [],
}
# Validate if package exists on repository path.
@@ -230,7 +230,8 @@ def install(module, installp_cmd, packages, repository_path, accept_license):
else:
if not module.check_mode:
- rc, out, err = module.run_command("%s -a %s -X -d %s %s" % (installp_cmd, accept_license_param[accept_license], repository_path, package))
+ rc, out, err = module.run_command(
+ [installp_cmd, "-a"] + accept_license_param[accept_license] + ["-X", "-d", repository_path, package])
if rc != 0:
module.fail_json(msg="Failed to run installp", rc=rc, err=err)
installed_pkgs.append(package)
diff --git a/ansible_collections/community/general/plugins/modules/irc.py b/ansible_collections/community/general/plugins/modules/irc.py
index 00ff299ee..e40ba2d0b 100644
--- a/ansible_collections/community/general/plugins/modules/irc.py
+++ b/ansible_collections/community/general/plugins/modules/irc.py
@@ -85,8 +85,10 @@ options:
was exlusively called O(use_ssl). The latter is now an alias of O(use_tls).
- B(Note:) for security reasons, you should always set O(use_tls=true) and
O(validate_certs=true) whenever possible.
+ - The option currently defaults to V(false). The default has been B(deprecated) and will
+ change to V(true) in community.general 10.0.0. To avoid deprecation warnings, explicitly
+ set this option to a value (preferably V(true)).
type: bool
- default: false
aliases:
- use_ssl
part:
@@ -108,7 +110,9 @@ options:
if the network between between Ansible and the IRC server is known to be safe.
- B(Note:) for security reasons, you should always set O(use_tls=true) and
O(validate_certs=true) whenever possible.
- default: false
+ - The option currently defaults to V(false). The default has been B(deprecated) and will
+ change to V(true) in community.general 10.0.0. To avoid deprecation warnings, explicitly
+ set this option to a value (preferably V(true)).
type: bool
version_added: 8.1.0
@@ -309,8 +313,8 @@ def main():
passwd=dict(no_log=True),
timeout=dict(type='int', default=30),
part=dict(type='bool', default=True),
- use_tls=dict(type='bool', default=False, aliases=['use_ssl']),
- validate_certs=dict(type='bool', default=False),
+ use_tls=dict(type='bool', aliases=['use_ssl']),
+ validate_certs=dict(type='bool'),
),
supports_check_mode=True,
required_one_of=[['channel', 'nick_to']]
@@ -334,6 +338,25 @@ def main():
style = module.params["style"]
validate_certs = module.params["validate_certs"]
+ if use_tls is None:
+ module.deprecate(
+ 'The default of use_tls will change to true in community.general 10.0.0.'
+ ' Set a value now (preferably true, if possible) to avoid the deprecation warning.',
+ version='10.0.0',
+ collection_name='community.general',
+ )
+ use_tls = False
+
+ if validate_certs is None:
+ if use_tls:
+ module.deprecate(
+ 'The default of validate_certs will change to true in community.general 10.0.0.'
+ ' Set a value now (prefarably true, if possible) to avoid the deprecation warning.',
+ version='10.0.0',
+ collection_name='community.general',
+ )
+ validate_certs = False
+
try:
send_msg(msg, server, port, channel, nick_to, key, topic, nick, color, passwd, timeout, use_tls, validate_certs, part, style)
except Exception as e:
diff --git a/ansible_collections/community/general/plugins/modules/kernel_blacklist.py b/ansible_collections/community/general/plugins/modules/kernel_blacklist.py
index b5bd90403..224b5bba8 100644
--- a/ansible_collections/community/general/plugins/modules/kernel_blacklist.py
+++ b/ansible_collections/community/general/plugins/modules/kernel_blacklist.py
@@ -67,6 +67,7 @@ class Blacklist(StateModuleHelper):
),
supports_check_mode=True,
)
+ use_old_vardict = False
def __init_module__(self):
self.pattern = re.compile(r'^blacklist\s+{0}$'.format(re.escape(self.vars.name)))
diff --git a/ansible_collections/community/general/plugins/modules/keycloak_client.py b/ansible_collections/community/general/plugins/modules/keycloak_client.py
index cd9c60bac..3628e5a51 100644
--- a/ansible_collections/community/general/plugins/modules/keycloak_client.py
+++ b/ansible_collections/community/general/plugins/modules/keycloak_client.py
@@ -775,8 +775,9 @@ def sanitize_cr(clientrep):
if 'secret' in result:
result['secret'] = 'no_log'
if 'attributes' in result:
- if 'saml.signing.private.key' in result['attributes']:
- result['attributes']['saml.signing.private.key'] = 'no_log'
+ attributes = result['attributes']
+ if isinstance(attributes, dict) and 'saml.signing.private.key' in attributes:
+ attributes['saml.signing.private.key'] = 'no_log'
return normalise_cr(result)
diff --git a/ansible_collections/community/general/plugins/modules/keycloak_identity_provider.py b/ansible_collections/community/general/plugins/modules/keycloak_identity_provider.py
index 588f553e8..2eca3a06d 100644
--- a/ansible_collections/community/general/plugins/modules/keycloak_identity_provider.py
+++ b/ansible_collections/community/general/plugins/modules/keycloak_identity_provider.py
@@ -437,7 +437,7 @@ def sanitize(idp):
idpcopy = deepcopy(idp)
if 'config' in idpcopy:
if 'clientSecret' in idpcopy['config']:
- idpcopy['clientSecret'] = '**********'
+ idpcopy['config']['clientSecret'] = '**********'
return idpcopy
diff --git a/ansible_collections/community/general/plugins/modules/keycloak_user_federation.py b/ansible_collections/community/general/plugins/modules/keycloak_user_federation.py
index fee0d1265..f87ef936c 100644
--- a/ansible_collections/community/general/plugins/modules/keycloak_user_federation.py
+++ b/ansible_collections/community/general/plugins/modules/keycloak_user_federation.py
@@ -719,6 +719,9 @@ def sanitize(comp):
compcopy['config'] = dict((k, v[0]) for k, v in compcopy['config'].items())
if 'bindCredential' in compcopy['config']:
compcopy['config']['bindCredential'] = '**********'
+ # an empty string is valid for krbPrincipalAttribute but is filtered out in diff
+ if 'krbPrincipalAttribute' not in compcopy['config']:
+ compcopy['config']['krbPrincipalAttribute'] = ''
if 'mappers' in compcopy:
for mapper in compcopy['mappers']:
if 'config' in mapper:
diff --git a/ansible_collections/community/general/plugins/modules/ldap_search.py b/ansible_collections/community/general/plugins/modules/ldap_search.py
index 45744e634..7958f86e0 100644
--- a/ansible_collections/community/general/plugins/modules/ldap_search.py
+++ b/ansible_collections/community/general/plugins/modules/ldap_search.py
@@ -44,6 +44,8 @@ options:
type: str
description:
- The LDAP scope to use.
+ - V(subordinate) requires the LDAPv3 subordinate feature extension.
+ - V(children) is equivalent to a "subtree" scope.
filter:
default: '(objectClass=*)'
type: str
diff --git a/ansible_collections/community/general/plugins/modules/locale_gen.py b/ansible_collections/community/general/plugins/modules/locale_gen.py
index 0dd76c9ab..fe501e023 100644
--- a/ansible_collections/community/general/plugins/modules/locale_gen.py
+++ b/ansible_collections/community/general/plugins/modules/locale_gen.py
@@ -79,6 +79,7 @@ class LocaleGen(StateModuleHelper):
),
supports_check_mode=True,
)
+ use_old_vardict = False
def __init_module__(self):
self.vars.set("ubuntu_mode", False)
diff --git a/ansible_collections/community/general/plugins/modules/lvg.py b/ansible_collections/community/general/plugins/modules/lvg.py
index 8a6384369..7ff7e3a2e 100644
--- a/ansible_collections/community/general/plugins/modules/lvg.py
+++ b/ansible_collections/community/general/plugins/modules/lvg.py
@@ -179,7 +179,7 @@ def parse_vgs(data):
def find_mapper_device_name(module, dm_device):
dmsetup_cmd = module.get_bin_path('dmsetup', True)
mapper_prefix = '/dev/mapper/'
- rc, dm_name, err = module.run_command("%s info -C --noheadings -o name %s" % (dmsetup_cmd, dm_device))
+ rc, dm_name, err = module.run_command([dmsetup_cmd, "info", "-C", "--noheadings", "-o", "name", dm_device])
if rc != 0:
module.fail_json(msg="Failed executing dmsetup command.", rc=rc, err=err)
mapper_device = mapper_prefix + dm_name.rstrip()
@@ -204,7 +204,7 @@ def find_vg(module, vg):
if not vg:
return None
vgs_cmd = module.get_bin_path('vgs', True)
- dummy, current_vgs, dummy = module.run_command("%s --noheadings -o vg_name,pv_count,lv_count --separator ';'" % vgs_cmd, check_rc=True)
+ dummy, current_vgs, dummy = module.run_command([vgs_cmd, "--noheadings", "-o", "vg_name,pv_count,lv_count", "--separator", ";"], check_rc=True)
vgs = parse_vgs(current_vgs)
@@ -431,10 +431,10 @@ def main():
for x in itertools.chain(dev_list, module.params['pvs'])
)
pvs_filter_vg_name = 'vg_name = {0}'.format(vg)
- pvs_filter = "--select '{0} || {1}' ".format(pvs_filter_pv_name, pvs_filter_vg_name)
+ pvs_filter = ["--select", "{0} || {1}".format(pvs_filter_pv_name, pvs_filter_vg_name)]
else:
- pvs_filter = ''
- rc, current_pvs, err = module.run_command("%s --noheadings -o pv_name,vg_name --separator ';' %s" % (pvs_cmd, pvs_filter))
+ pvs_filter = []
+ rc, current_pvs, err = module.run_command([pvs_cmd, "--noheadings", "-o", "pv_name,vg_name", "--separator", ";"] + pvs_filter)
if rc != 0:
module.fail_json(msg="Failed executing pvs command.", rc=rc, err=err)
@@ -473,7 +473,7 @@ def main():
if this_vg['lv_count'] == 0 or force:
# remove VG
vgremove_cmd = module.get_bin_path('vgremove', True)
- rc, dummy, err = module.run_command("%s --force %s" % (vgremove_cmd, vg))
+ rc, dummy, err = module.run_command([vgremove_cmd, "--force", vg])
if rc == 0:
module.exit_json(changed=True)
else:
@@ -509,7 +509,6 @@ def main():
changed = True
else:
if devs_to_add:
- devs_to_add_string = ' '.join(devs_to_add)
# create PV
pvcreate_cmd = module.get_bin_path('pvcreate', True)
for current_dev in devs_to_add:
@@ -520,21 +519,20 @@ def main():
module.fail_json(msg="Creating physical volume '%s' failed" % current_dev, rc=rc, err=err)
# add PV to our VG
vgextend_cmd = module.get_bin_path('vgextend', True)
- rc, dummy, err = module.run_command("%s %s %s" % (vgextend_cmd, vg, devs_to_add_string))
+ rc, dummy, err = module.run_command([vgextend_cmd, vg] + devs_to_add)
if rc == 0:
changed = True
else:
- module.fail_json(msg="Unable to extend %s by %s." % (vg, devs_to_add_string), rc=rc, err=err)
+ module.fail_json(msg="Unable to extend %s by %s." % (vg, ' '.join(devs_to_add)), rc=rc, err=err)
# remove some PV from our VG
if devs_to_remove:
- devs_to_remove_string = ' '.join(devs_to_remove)
vgreduce_cmd = module.get_bin_path('vgreduce', True)
- rc, dummy, err = module.run_command("%s --force %s %s" % (vgreduce_cmd, vg, devs_to_remove_string))
+ rc, dummy, err = module.run_command([vgreduce_cmd, "--force", vg] + devs_to_remove)
if rc == 0:
changed = True
else:
- module.fail_json(msg="Unable to reduce %s by %s." % (vg, devs_to_remove_string), rc=rc, err=err)
+ module.fail_json(msg="Unable to reduce %s by %s." % (vg, ' '.join(devs_to_remove)), rc=rc, err=err)
module.exit_json(changed=changed)
diff --git a/ansible_collections/community/general/plugins/modules/lvol.py b/ansible_collections/community/general/plugins/modules/lvol.py
index a2a870260..3a2f5c7cd 100644
--- a/ansible_collections/community/general/plugins/modules/lvol.py
+++ b/ansible_collections/community/general/plugins/modules/lvol.py
@@ -236,6 +236,7 @@ EXAMPLES = '''
'''
import re
+import shlex
from ansible.module_utils.basic import AnsibleModule
@@ -281,7 +282,7 @@ def parse_vgs(data):
def get_lvm_version(module):
ver_cmd = module.get_bin_path("lvm", required=True)
- rc, out, err = module.run_command("%s version" % (ver_cmd))
+ rc, out, err = module.run_command([ver_cmd, "version"])
if rc != 0:
return None
m = re.search(r"LVM version:\s+(\d+)\.(\d+)\.(\d+).*(\d{4}-\d{2}-\d{2})", out)
@@ -320,14 +321,14 @@ def main():
module.fail_json(msg="Failed to get LVM version number")
version_yesopt = mkversion(2, 2, 99) # First LVM with the "--yes" option
if version_found >= version_yesopt:
- yesopt = "--yes"
+ yesopt = ["--yes"]
else:
- yesopt = ""
+ yesopt = []
vg = module.params['vg']
lv = module.params['lv']
size = module.params['size']
- opts = module.params['opts']
+ opts = shlex.split(module.params['opts'] or '')
state = module.params['state']
force = module.boolean(module.params['force'])
shrink = module.boolean(module.params['shrink'])
@@ -338,21 +339,13 @@ def main():
size_unit = 'm'
size_operator = None
snapshot = module.params['snapshot']
- pvs = module.params['pvs']
-
- if pvs is None:
- pvs = ""
- else:
- pvs = " ".join(pvs)
-
- if opts is None:
- opts = ""
+ pvs = module.params['pvs'] or []
# Add --test option when running in check-mode
if module.check_mode:
- test_opt = ' --test'
+ test_opt = ['--test']
else:
- test_opt = ''
+ test_opt = []
if size:
# LVEXTEND(8)/LVREDUCE(8) -l, -L options: Check for relative value for resizing
@@ -400,7 +393,7 @@ def main():
# Get information on volume group requested
vgs_cmd = module.get_bin_path("vgs", required=True)
rc, current_vgs, err = module.run_command(
- "%s --noheadings --nosuffix -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s" % (vgs_cmd, unit.lower(), vg))
+ [vgs_cmd, "--noheadings", "--nosuffix", "-o", "vg_name,size,free,vg_extent_size", "--units", unit.lower(), "--separator", ";", vg])
if rc != 0:
if state == 'absent':
@@ -414,7 +407,7 @@ def main():
# Get information on logical volume requested
lvs_cmd = module.get_bin_path("lvs", required=True)
rc, current_lvs, err = module.run_command(
- "%s -a --noheadings --nosuffix -o lv_name,size,lv_attr --units %s --separator ';' %s" % (lvs_cmd, unit.lower(), vg))
+ [lvs_cmd, "-a", "--noheadings", "--nosuffix", "-o", "lv_name,size,lv_attr", "--units", unit.lower(), "--separator", ";", vg])
if rc != 0:
if state == 'absent':
@@ -474,20 +467,23 @@ def main():
# create LV
lvcreate_cmd = module.get_bin_path("lvcreate", required=True)
+ cmd = [lvcreate_cmd] + test_opt + yesopt
if snapshot is not None:
if size:
- cmd = "%s %s %s -%s %s%s -s -n %s %s %s/%s" % (lvcreate_cmd, test_opt, yesopt, size_opt, size, size_unit, snapshot, opts, vg, lv)
- else:
- cmd = "%s %s %s -s -n %s %s %s/%s" % (lvcreate_cmd, test_opt, yesopt, snapshot, opts, vg, lv)
- elif thinpool and lv:
- if size_opt == 'l':
- module.fail_json(changed=False, msg="Thin volume sizing with percentage not supported.")
- size_opt = 'V'
- cmd = "%s %s %s -n %s -%s %s%s %s -T %s/%s" % (lvcreate_cmd, test_opt, yesopt, lv, size_opt, size, size_unit, opts, vg, thinpool)
- elif thinpool and not lv:
- cmd = "%s %s %s -%s %s%s %s -T %s/%s" % (lvcreate_cmd, test_opt, yesopt, size_opt, size, size_unit, opts, vg, thinpool)
+ cmd += ["-%s" % size_opt, "%s%s" % (size, size_unit)]
+ cmd += ["-s", "-n", snapshot] + opts + ["%s/%s" % (vg, lv)]
+ elif thinpool:
+ if lv:
+ if size_opt == 'l':
+ module.fail_json(changed=False, msg="Thin volume sizing with percentage not supported.")
+ size_opt = 'V'
+ cmd += ["-n", lv]
+ cmd += ["-%s" % size_opt, "%s%s" % (size, size_unit)]
+ cmd += opts + ["-T", "%s/%s" % (vg, thinpool)]
else:
- cmd = "%s %s %s -n %s -%s %s%s %s %s %s" % (lvcreate_cmd, test_opt, yesopt, lv, size_opt, size, size_unit, opts, vg, pvs)
+ cmd += ["-n", lv]
+ cmd += ["-%s" % size_opt, "%s%s" % (size, size_unit)]
+ cmd += opts + [vg] + pvs
rc, dummy, err = module.run_command(cmd)
if rc == 0:
changed = True
@@ -499,7 +495,7 @@ def main():
if not force:
module.fail_json(msg="Sorry, no removal of logical volume %s without force=true." % (this_lv['name']))
lvremove_cmd = module.get_bin_path("lvremove", required=True)
- rc, dummy, err = module.run_command("%s %s --force %s/%s" % (lvremove_cmd, test_opt, vg, this_lv['name']))
+ rc, dummy, err = module.run_command([lvremove_cmd] + test_opt + ["--force", "%s/%s" % (vg, this_lv['name'])])
if rc == 0:
module.exit_json(changed=True)
else:
@@ -527,7 +523,7 @@ def main():
if this_lv['size'] < size_requested:
if (size_free > 0) and (size_free >= (size_requested - this_lv['size'])):
- tool = module.get_bin_path("lvextend", required=True)
+ tool = [module.get_bin_path("lvextend", required=True)]
else:
module.fail_json(
msg="Logical Volume %s could not be extended. Not enough free space left (%s%s required / %s%s available)" %
@@ -539,16 +535,17 @@ def main():
elif not force:
module.fail_json(msg="Sorry, no shrinking of %s without force=true" % (this_lv['name']))
else:
- tool = module.get_bin_path("lvreduce", required=True)
- tool = '%s %s' % (tool, '--force')
+ tool = [module.get_bin_path("lvreduce", required=True), '--force']
if tool:
if resizefs:
- tool = '%s %s' % (tool, '--resizefs')
+ tool += ['--resizefs']
+ cmd = tool + test_opt
if size_operator:
- cmd = "%s %s -%s %s%s%s %s/%s %s" % (tool, test_opt, size_opt, size_operator, size, size_unit, vg, this_lv['name'], pvs)
+ cmd += ["-%s" % size_opt, "%s%s%s" % (size_operator, size, size_unit)]
else:
- cmd = "%s %s -%s %s%s %s/%s %s" % (tool, test_opt, size_opt, size, size_unit, vg, this_lv['name'], pvs)
+ cmd += ["-%s" % size_opt, "%s%s" % (size, size_unit)]
+ cmd += ["%s/%s" % (vg, this_lv['name'])] + pvs
rc, out, err = module.run_command(cmd)
if "Reached maximum COW size" in out:
module.fail_json(msg="Unable to resize %s to %s%s" % (lv, size, size_unit), rc=rc, err=err, out=out)
@@ -566,23 +563,24 @@ def main():
# resize LV based on absolute values
tool = None
if float(size) > this_lv['size'] or size_operator == '+':
- tool = module.get_bin_path("lvextend", required=True)
+ tool = [module.get_bin_path("lvextend", required=True)]
elif shrink and float(size) < this_lv['size'] or size_operator == '-':
if float(size) == 0:
module.fail_json(msg="Sorry, no shrinking of %s to 0 permitted." % (this_lv['name']))
if not force:
module.fail_json(msg="Sorry, no shrinking of %s without force=true." % (this_lv['name']))
else:
- tool = module.get_bin_path("lvreduce", required=True)
- tool = '%s %s' % (tool, '--force')
+ tool = [module.get_bin_path("lvreduce", required=True), '--force']
if tool:
if resizefs:
- tool = '%s %s' % (tool, '--resizefs')
+ tool += ['--resizefs']
+ cmd = tool + test_opt
if size_operator:
- cmd = "%s %s -%s %s%s%s %s/%s %s" % (tool, test_opt, size_opt, size_operator, size, size_unit, vg, this_lv['name'], pvs)
+ cmd += ["-%s" % size_opt, "%s%s%s" % (size_operator, size, size_unit)]
else:
- cmd = "%s %s -%s %s%s %s/%s %s" % (tool, test_opt, size_opt, size, size_unit, vg, this_lv['name'], pvs)
+ cmd += ["-%s" % size_opt, "%s%s" % (size, size_unit)]
+ cmd += ["%s/%s" % (vg, this_lv['name'])] + pvs
rc, out, err = module.run_command(cmd)
if "Reached maximum COW size" in out:
module.fail_json(msg="Unable to resize %s to %s%s" % (lv, size, size_unit), rc=rc, err=err, out=out)
@@ -598,14 +596,14 @@ def main():
if this_lv is not None:
if active:
lvchange_cmd = module.get_bin_path("lvchange", required=True)
- rc, dummy, err = module.run_command("%s -ay %s/%s" % (lvchange_cmd, vg, this_lv['name']))
+ rc, dummy, err = module.run_command([lvchange_cmd, "-ay", "%s/%s" % (vg, this_lv['name'])])
if rc == 0:
module.exit_json(changed=((not this_lv['active']) or changed), vg=vg, lv=this_lv['name'], size=this_lv['size'])
else:
module.fail_json(msg="Failed to activate logical volume %s" % (lv), rc=rc, err=err)
else:
lvchange_cmd = module.get_bin_path("lvchange", required=True)
- rc, dummy, err = module.run_command("%s -an %s/%s" % (lvchange_cmd, vg, this_lv['name']))
+ rc, dummy, err = module.run_command([lvchange_cmd, "-an", "%s/%s" % (vg, this_lv['name'])])
if rc == 0:
module.exit_json(changed=(this_lv['active'] or changed), vg=vg, lv=this_lv['name'], size=this_lv['size'])
else:
diff --git a/ansible_collections/community/general/plugins/modules/lxd_container.py b/ansible_collections/community/general/plugins/modules/lxd_container.py
index b82e2be9b..f44523a75 100644
--- a/ansible_collections/community/general/plugins/modules/lxd_container.py
+++ b/ansible_collections/community/general/plugins/modules/lxd_container.py
@@ -400,7 +400,7 @@ EXAMPLES = '''
protocol: simplestreams
type: image
mode: pull
- server: https://images.linuxcontainers.org
+ server: [...] # URL to the image server
alias: debian/11
timeout: 600
'''
diff --git a/ansible_collections/community/general/plugins/modules/macports.py b/ansible_collections/community/general/plugins/modules/macports.py
index e81fb9142..cd620687d 100644
--- a/ansible_collections/community/general/plugins/modules/macports.py
+++ b/ansible_collections/community/general/plugins/modules/macports.py
@@ -111,7 +111,7 @@ from ansible.module_utils.basic import AnsibleModule
def selfupdate(module, port_path):
""" Update Macports and the ports tree. """
- rc, out, err = module.run_command("%s -v selfupdate" % port_path)
+ rc, out, err = module.run_command([port_path, "-v", "selfupdate"])
if rc == 0:
updated = any(
@@ -135,7 +135,7 @@ def selfupdate(module, port_path):
def upgrade(module, port_path):
""" Upgrade outdated ports. """
- rc, out, err = module.run_command("%s upgrade outdated" % port_path)
+ rc, out, err = module.run_command([port_path, "upgrade", "outdated"])
# rc is 1 when nothing to upgrade so check stdout first.
if out.strip() == "Nothing to upgrade.":
@@ -182,7 +182,7 @@ def remove_ports(module, port_path, ports, stdout, stderr):
if not query_port(module, port_path, port):
continue
- rc, out, err = module.run_command("%s uninstall %s" % (port_path, port))
+ rc, out, err = module.run_command([port_path, "uninstall", port])
stdout += out
stderr += err
if query_port(module, port_path, port):
@@ -206,7 +206,7 @@ def install_ports(module, port_path, ports, variant, stdout, stderr):
if query_port(module, port_path, port):
continue
- rc, out, err = module.run_command("%s install %s %s" % (port_path, port, variant))
+ rc, out, err = module.run_command([port_path, "install", port, variant])
stdout += out
stderr += err
if not query_port(module, port_path, port):
@@ -232,7 +232,7 @@ def activate_ports(module, port_path, ports, stdout, stderr):
if query_port(module, port_path, port, state="active"):
continue
- rc, out, err = module.run_command("%s activate %s" % (port_path, port))
+ rc, out, err = module.run_command([port_path, "activate", port])
stdout += out
stderr += err
@@ -259,7 +259,7 @@ def deactivate_ports(module, port_path, ports, stdout, stderr):
if not query_port(module, port_path, port, state="active"):
continue
- rc, out, err = module.run_command("%s deactivate %s" % (port_path, port))
+ rc, out, err = module.run_command([port_path, "deactivate", port])
stdout += out
stderr += err
if query_port(module, port_path, port, state="active"):
diff --git a/ansible_collections/community/general/plugins/modules/mksysb.py b/ansible_collections/community/general/plugins/modules/mksysb.py
index 8272dbf7d..1280f04d5 100644
--- a/ansible_collections/community/general/plugins/modules/mksysb.py
+++ b/ansible_collections/community/general/plugins/modules/mksysb.py
@@ -138,6 +138,7 @@ class MkSysB(ModuleHelper):
backup_dmapi_fs=cmd_runner_fmt.as_bool("-A"),
combined_path=cmd_runner_fmt.as_func(cmd_runner_fmt.unpack_args(lambda p, n: ["%s/%s" % (p, n)])),
)
+ use_old_vardict = False
def __init_module__(self):
if not os.path.isdir(self.vars.storage_path):
diff --git a/ansible_collections/community/general/plugins/modules/opkg.py b/ansible_collections/community/general/plugins/modules/opkg.py
index 757c88c5d..2f9794ab8 100644
--- a/ansible_collections/community/general/plugins/modules/opkg.py
+++ b/ansible_collections/community/general/plugins/modules/opkg.py
@@ -127,6 +127,7 @@ class Opkg(StateModuleHelper):
executable=dict(type="path"),
),
)
+ use_old_vardict = False
def __init_module__(self):
self.vars.set("install_c", 0, output=False, change=True)
diff --git a/ansible_collections/community/general/plugins/modules/parted.py b/ansible_collections/community/general/plugins/modules/parted.py
index 382e47a47..b3616a8ec 100644
--- a/ansible_collections/community/general/plugins/modules/parted.py
+++ b/ansible_collections/community/general/plugins/modules/parted.py
@@ -480,12 +480,12 @@ def get_device_info(device, unit):
if label_needed:
return get_unlabeled_device_info(device, unit)
- command = "%s -s -m %s -- unit '%s' print" % (parted_exec, device, unit)
+ command = [parted_exec, "-s", "-m", device, "--", "unit", unit, "print"]
rc, out, err = module.run_command(command)
if rc != 0 and 'unrecognised disk label' not in err:
module.fail_json(msg=(
"Error while getting device information with parted "
- "script: '%s'" % command),
+ "script: '%s'" % " ".join(command)),
rc=rc, out=out, err=err
)
@@ -506,7 +506,7 @@ def check_parted_label(device):
return False
# Older parted versions return a message in the stdout and RC > 0.
- rc, out, err = module.run_command("%s -s -m %s print" % (parted_exec, device))
+ rc, out, err = module.run_command([parted_exec, "-s", "-m", device, "print"])
if rc != 0 and 'unrecognised disk label' in out.lower():
return True
@@ -546,7 +546,7 @@ def parted_version():
"""
global module, parted_exec # pylint: disable=global-variable-not-assigned
- rc, out, err = module.run_command("%s --version" % parted_exec)
+ rc, out, err = module.run_command([parted_exec, "--version"])
if rc != 0:
module.fail_json(
msg="Failed to get parted version.", rc=rc, out=out, err=err
@@ -580,6 +580,7 @@ def parted(script, device, align):
script_option = '-s'
if script and not module.check_mode:
+ # TODO: convert run_comand() argument to list!
command = "%s %s -m %s %s -- %s" % (parted_exec, script_option, align_option, device, script)
rc, out, err = module.run_command(command)
diff --git a/ansible_collections/community/general/plugins/modules/pipx.py b/ansible_collections/community/general/plugins/modules/pipx.py
index 705cc71a7..e82e4c32a 100644
--- a/ansible_collections/community/general/plugins/modules/pipx.py
+++ b/ansible_collections/community/general/plugins/modules/pipx.py
@@ -201,6 +201,7 @@ class PipX(StateModuleHelper):
],
supports_check_mode=True,
)
+ use_old_vardict = False
def _retrieve_installed(self):
def process_list(rc, out, err):
diff --git a/ansible_collections/community/general/plugins/modules/pipx_info.py b/ansible_collections/community/general/plugins/modules/pipx_info.py
index 34f9681b0..992ca7941 100644
--- a/ansible_collections/community/general/plugins/modules/pipx_info.py
+++ b/ansible_collections/community/general/plugins/modules/pipx_info.py
@@ -150,6 +150,7 @@ class PipXInfo(ModuleHelper):
),
supports_check_mode=True,
)
+ use_old_vardict = False
def __init_module__(self):
if self.vars.executable:
diff --git a/ansible_collections/community/general/plugins/modules/pkg5.py b/ansible_collections/community/general/plugins/modules/pkg5.py
index c4aace9f2..08fa9272f 100644
--- a/ansible_collections/community/general/plugins/modules/pkg5.py
+++ b/ansible_collections/community/general/plugins/modules/pkg5.py
@@ -54,6 +54,12 @@ options:
- Refresh publishers before execution.
type: bool
default: true
+ verbose:
+ description:
+ - Set to V(true) to disable quiet execution.
+ type: bool
+ default: false
+ version_added: 9.0.0
'''
EXAMPLES = '''
- name: Install Vim
@@ -90,6 +96,7 @@ def main():
accept_licenses=dict(type='bool', default=False, aliases=['accept', 'accept_licences']),
be_name=dict(type='str'),
refresh=dict(type='bool', default=True),
+ verbose=dict(type='bool', default=False),
),
supports_check_mode=True,
)
@@ -156,9 +163,15 @@ def ensure(module, state, packages, params):
else:
no_refresh = ['--no-refresh']
+ if params['verbose']:
+ verbosity = []
+ else:
+ verbosity = ['-q']
+
to_modify = list(filter(behaviour[state]['filter'], packages))
if to_modify:
- rc, out, err = module.run_command(['pkg', behaviour[state]['subcommand']] + dry_run + accept_licenses + beadm + no_refresh + ['-q', '--'] + to_modify)
+ rc, out, err = module.run_command(
+ ['pkg', behaviour[state]['subcommand']] + dry_run + accept_licenses + beadm + no_refresh + verbosity + ['--'] + to_modify)
response['rc'] = rc
response['results'].append(out)
response['msg'] += err
diff --git a/ansible_collections/community/general/plugins/modules/pkgin.py b/ansible_collections/community/general/plugins/modules/pkgin.py
index 5b2e478b8..8b29655d3 100644
--- a/ansible_collections/community/general/plugins/modules/pkgin.py
+++ b/ansible_collections/community/general/plugins/modules/pkgin.py
@@ -145,18 +145,18 @@ def query_package(module, name):
"""
# test whether '-p' (parsable) flag is supported.
- rc, out, err = module.run_command("%s -p -v" % PKGIN_PATH)
+ rc, out, err = module.run_command([PKGIN_PATH, "-p", "-v"])
if rc == 0:
- pflag = '-p'
+ pflag = ['-p']
splitchar = ';'
else:
- pflag = ''
+ pflag = []
splitchar = ' '
# Use "pkgin search" to find the package. The regular expression will
# only match on the complete name.
- rc, out, err = module.run_command("%s %s search \"^%s$\"" % (PKGIN_PATH, pflag, name))
+ rc, out, err = module.run_command([PKGIN_PATH] + pflag + ["search", "^%s$" % name])
# rc will not be 0 unless the search was a success
if rc == 0:
@@ -234,22 +234,19 @@ def format_pkgin_command(module, command, package=None):
# an empty string. Some commands (e.g. 'update') will ignore extra
# arguments, however this behaviour cannot be relied on for others.
if package is None:
- package = ""
+ packages = []
+ else:
+ packages = [package]
if module.params["force"]:
- force = "-F"
+ force = ["-F"]
else:
- force = ""
-
- vars = {"pkgin": PKGIN_PATH,
- "command": command,
- "package": package,
- "force": force}
+ force = []
if module.check_mode:
- return "%(pkgin)s -n %(command)s %(package)s" % vars
+ return [PKGIN_PATH, "-n", command] + packages
else:
- return "%(pkgin)s -y %(force)s %(command)s %(package)s" % vars
+ return [PKGIN_PATH, "-y"] + force + [command] + packages
def remove_packages(module, packages):
diff --git a/ansible_collections/community/general/plugins/modules/portinstall.py b/ansible_collections/community/general/plugins/modules/portinstall.py
index e263b7181..59dafb1eb 100644
--- a/ansible_collections/community/general/plugins/modules/portinstall.py
+++ b/ansible_collections/community/general/plugins/modules/portinstall.py
@@ -79,12 +79,13 @@ def query_package(module, name):
if pkg_info_path:
pkgng = False
pkg_glob_path = module.get_bin_path('pkg_glob', True)
+ # TODO: convert run_comand() argument to list!
rc, out, err = module.run_command("%s -e `pkg_glob %s`" % (pkg_info_path, shlex_quote(name)), use_unsafe_shell=True)
+ pkg_info_path = [pkg_info_path]
else:
pkgng = True
- pkg_info_path = module.get_bin_path('pkg', True)
- pkg_info_path = pkg_info_path + " info"
- rc, out, err = module.run_command("%s %s" % (pkg_info_path, name))
+ pkg_info_path = [module.get_bin_path('pkg', True), "info"]
+ rc, out, err = module.run_command(pkg_info_path + [name])
found = rc == 0
@@ -94,10 +95,7 @@ def query_package(module, name):
# some package is installed
name_without_digits = re.sub('[0-9]', '', name)
if name != name_without_digits:
- if pkgng:
- rc, out, err = module.run_command("%s %s" % (pkg_info_path, name_without_digits))
- else:
- rc, out, err = module.run_command("%s %s" % (pkg_info_path, name_without_digits))
+ rc, out, err = module.run_command(pkg_info_path + [name_without_digits])
found = rc == 0
@@ -107,13 +105,13 @@ def query_package(module, name):
def matching_packages(module, name):
ports_glob_path = module.get_bin_path('ports_glob', True)
- rc, out, err = module.run_command("%s %s" % (ports_glob_path, name))
+ rc, out, err = module.run_command([ports_glob_path, name])
# counts the number of packages found
occurrences = out.count('\n')
if occurrences == 0:
name_without_digits = re.sub('[0-9]', '', name)
if name != name_without_digits:
- rc, out, err = module.run_command("%s %s" % (ports_glob_path, name_without_digits))
+ rc, out, err = module.run_command([ports_glob_path, name_without_digits])
occurrences = out.count('\n')
return occurrences
@@ -135,10 +133,12 @@ def remove_packages(module, packages):
if not query_package(module, package):
continue
+ # TODO: convert run_comand() argument to list!
rc, out, err = module.run_command("%s `%s %s`" % (pkg_delete_path, pkg_glob_path, shlex_quote(package)), use_unsafe_shell=True)
if query_package(module, package):
name_without_digits = re.sub('[0-9]', '', package)
+ # TODO: convert run_comand() argument to list!
rc, out, err = module.run_command("%s `%s %s`" % (pkg_delete_path, pkg_glob_path,
shlex_quote(name_without_digits)),
use_unsafe_shell=True)
@@ -163,13 +163,13 @@ def install_packages(module, packages, use_packages):
if not portinstall_path:
pkg_path = module.get_bin_path('pkg', False)
if pkg_path:
- module.run_command("pkg install -y portupgrade")
+ module.run_command([pkg_path, "install", "-y", "portupgrade"])
portinstall_path = module.get_bin_path('portinstall', True)
if use_packages:
- portinstall_params = "--use-packages"
+ portinstall_params = ["--use-packages"]
else:
- portinstall_params = ""
+ portinstall_params = []
for package in packages:
if query_package(module, package):
@@ -178,7 +178,7 @@ def install_packages(module, packages, use_packages):
# TODO: check how many match
matches = matching_packages(module, package)
if matches == 1:
- rc, out, err = module.run_command("%s --batch %s %s" % (portinstall_path, portinstall_params, package))
+ rc, out, err = module.run_command([portinstall_path, "--batch"] + portinstall_params + [package])
if not query_package(module, package):
module.fail_json(msg="failed to install %s: %s" % (package, out))
elif matches == 0:
diff --git a/ansible_collections/community/general/plugins/modules/proxmox.py b/ansible_collections/community/general/plugins/modules/proxmox.py
index 47f3faa4f..73afd952e 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox.py
@@ -15,12 +15,14 @@ short_description: Management of instances in Proxmox VE cluster
description:
- Allows you to create/delete/stop instances in Proxmox VE cluster.
- The module automatically detects containerization type (lxc for PVE 4, openvz for older).
- - Since community.general 4.0.0 on, there are no more default values, see O(proxmox_default_behavior).
+ - Since community.general 4.0.0 on, there are no more default values.
attributes:
check_mode:
support: none
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
password:
description:
@@ -47,28 +49,23 @@ options:
comma-delimited list C([volume=]<volume> [,acl=<1|0>] [,mountoptions=<opt[;opt...]>] [,quota=<1|0>]
[,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=<DiskSize>])."
- See U(https://pve.proxmox.com/wiki/Linux_Container) for a full description.
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(3).
- Should not be used in conjunction with O(storage).
type: str
cores:
description:
- Specify number of cores per socket.
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(1).
type: int
cpus:
description:
- numbers of allocated cpus for instance
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(1).
type: int
memory:
description:
- memory size in MB for instance
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(512).
type: int
swap:
description:
- swap memory size in MB for instance
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(0).
type: int
netif:
description:
@@ -101,7 +98,6 @@ options:
onboot:
description:
- specifies whether a VM will be started during system bootup
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(false).
type: bool
storage:
description:
@@ -120,7 +116,6 @@ options:
cpuunits:
description:
- CPU weight for a VM
- - This option has no default unless O(proxmox_default_behavior) is set to V(compatibility); then the default is V(1000).
type: int
nameserver:
description:
@@ -200,25 +195,6 @@ options:
- The special value V(host) configures the same timezone used by Proxmox host.
type: str
version_added: '7.1.0'
- proxmox_default_behavior:
- description:
- - As of community.general 4.0.0, various options no longer have default values.
- These default values caused problems when users expected different behavior from Proxmox
- by default or filled options which caused problems when set.
- - The value V(compatibility) (default before community.general 4.0.0) will ensure that the default values
- are used when the values are not explicitly specified by the user. The new default is V(no_defaults),
- which makes sure these options have no defaults.
- - This affects the O(disk), O(cores), O(cpus), O(memory), O(onboot), O(swap), and O(cpuunits) options.
- - >
- This parameter is now B(deprecated) and it will be removed in community.general 10.0.0.
- By then, the module's behavior should be to not set default values, equivalent to V(no_defaults).
- If a consistent set of defaults is needed, the playbook or role should be responsible for setting it.
- type: str
- default: no_defaults
- choices:
- - compatibility
- - no_defaults
- version_added: "1.3.0"
clone:
description:
- ID of the container to be cloned.
@@ -242,6 +218,7 @@ author: Sergei Antipov (@UnderGreen)
seealso:
- module: community.general.proxmox_vm_info
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.proxmox.selection
- community.general.attributes
@@ -785,8 +762,6 @@ def main():
description=dict(type='str'),
hookscript=dict(type='str'),
timezone=dict(type='str'),
- proxmox_default_behavior=dict(type='str', default='no_defaults', choices=['compatibility', 'no_defaults'],
- removed_in_version='9.0.0', removed_from_collection='community.general'),
clone=dict(type='int'),
clone_type=dict(default='opportunistic', choices=['full', 'linked', 'opportunistic']),
tags=dict(type='list', elements='str')
@@ -827,20 +802,6 @@ def main():
timeout = module.params['timeout']
clone = module.params['clone']
- if module.params['proxmox_default_behavior'] == 'compatibility':
- old_default_values = dict(
- disk="3",
- cores=1,
- cpus=1,
- memory=512,
- swap=0,
- onboot=False,
- cpuunits=1000,
- )
- for param, value in old_default_values.items():
- if module.params[param] is None:
- module.params[param] = value
-
# If vmid not set get the Next VM id from ProxmoxAPI
# If hostname is set get the VM id from ProxmoxAPI
if not vmid and state == 'present':
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_disk.py b/ansible_collections/community/general/plugins/modules/proxmox_disk.py
index 69a7300df..83cdbeee5 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_disk.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_disk.py
@@ -21,6 +21,8 @@ attributes:
support: none
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
name:
description:
@@ -325,6 +327,7 @@ options:
- The drive's worldwide name, encoded as 16 bytes hex string, prefixed by V(0x).
type: str
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
'''
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_domain_info.py b/ansible_collections/community/general/plugins/modules/proxmox_domain_info.py
index 7435695a9..f3ff212bf 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_domain_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_domain_info.py
@@ -16,6 +16,9 @@ short_description: Retrieve information about one or more Proxmox VE domains
version_added: 1.3.0
description:
- Retrieve information about one or more Proxmox VE domains.
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
domain:
description:
@@ -24,6 +27,7 @@ options:
type: str
author: Tristan Le Guern (@tleguern)
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
- community.general.attributes.info_module
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_group_info.py b/ansible_collections/community/general/plugins/modules/proxmox_group_info.py
index 531a9dae7..eda1fe04d 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_group_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_group_info.py
@@ -16,6 +16,9 @@ short_description: Retrieve information about one or more Proxmox VE groups
version_added: 1.3.0
description:
- Retrieve information about one or more Proxmox VE groups
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
group:
description:
@@ -24,6 +27,7 @@ options:
type: str
author: Tristan Le Guern (@tleguern)
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
- community.general.attributes.info_module
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_kvm.py b/ansible_collections/community/general/plugins/modules/proxmox_kvm.py
index 8779dcdc1..9fe805c7a 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_kvm.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_kvm.py
@@ -21,6 +21,8 @@ attributes:
support: none
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
archive:
description:
@@ -517,6 +519,16 @@ options:
default: '2.0'
type: dict
version_added: 7.1.0
+ usb:
+ description:
+ - A hash/dictionary of USB devices for the VM. O(usb='{"key":"value", "key":"value"}').
+ - Keys allowed are - C(usb[n]) where 0 ≤ n ≤ N.
+ - Values allowed are - C(host="value|spice",mapping="value",usb3="1|0").
+ - host is either C(spice) or the USB id/port.
+ - Option C(mapping) is the mapped USB device name.
+ - Option C(usb3) enables USB 3 support.
+ type: dict
+ version_added: 9.0.0
update:
description:
- If V(true), the VM will be updated with new value.
@@ -579,6 +591,7 @@ options:
seealso:
- module: community.general.proxmox_vm_info
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.proxmox.selection
- community.general.attributes
@@ -1091,7 +1104,7 @@ class ProxmoxKvmAnsible(ProxmoxAnsible):
)
# Convert all dict in kwargs to elements.
- # For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n], ipconfig[n]
+ # For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n], ipconfig[n], usb[n]
for k in list(kwargs.keys()):
if isinstance(kwargs[k], dict):
kwargs.update(kwargs[k])
@@ -1308,6 +1321,7 @@ def main():
storage=dict(type='str', required=True),
version=dict(type='str', choices=['2.0', '1.2'], default='2.0')
)),
+ usb=dict(type='dict'),
update=dict(type='bool', default=False),
update_unsafe=dict(type='bool', default=False),
vcpus=dict(type='int'),
@@ -1513,6 +1527,7 @@ def main():
tdf=module.params['tdf'],
template=module.params['template'],
tpmstate0=module.params['tpmstate0'],
+ usb=module.params['usb'],
vcpus=module.params['vcpus'],
vga=module.params['vga'],
virtio=module.params['virtio'],
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_nic.py b/ansible_collections/community/general/plugins/modules/proxmox_nic.py
index 9afe49447..6e94ed0bb 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_nic.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_nic.py
@@ -21,6 +21,8 @@ attributes:
support: full
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
bridge:
description:
@@ -94,6 +96,7 @@ options:
- Specifies the instance ID.
type: int
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
'''
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_node_info.py b/ansible_collections/community/general/plugins/modules/proxmox_node_info.py
index 82ef7aa38..51d8745c0 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_node_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_node_info.py
@@ -17,7 +17,11 @@ version_added: 8.2.0
description:
- Retrieve information about one or more Proxmox VE nodes.
author: John Berninger (@jwbernin)
+attributes:
+ action_group:
+ version_added: 9.0.0
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
- community.general.attributes.info_module
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_pool.py b/ansible_collections/community/general/plugins/modules/proxmox_pool.py
index 704632070..5089ec3be 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_pool.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_pool.py
@@ -21,6 +21,8 @@ attributes:
support: full
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
poolid:
description:
@@ -42,8 +44,9 @@ options:
type: str
extends_documentation_fragment:
- - community.general.proxmox.documentation
- - community.general.attributes
+ - community.general.proxmox.actiongroup_proxmox
+ - community.general.proxmox.documentation
+ - community.general.attributes
"""
EXAMPLES = """
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_pool_member.py b/ansible_collections/community/general/plugins/modules/proxmox_pool_member.py
index 7d6b24949..b26082f97 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_pool_member.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_pool_member.py
@@ -20,6 +20,8 @@ attributes:
support: full
diff_mode:
support: full
+ action_group:
+ version_added: 9.0.0
options:
poolid:
description:
@@ -48,8 +50,9 @@ options:
type: str
extends_documentation_fragment:
- - community.general.proxmox.documentation
- - community.general.attributes
+ - community.general.proxmox.actiongroup_proxmox
+ - community.general.proxmox.documentation
+ - community.general.attributes
"""
EXAMPLES = """
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_snap.py b/ansible_collections/community/general/plugins/modules/proxmox_snap.py
index 4991423c2..4f7b345b8 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_snap.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_snap.py
@@ -21,6 +21,8 @@ attributes:
support: full
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
hostname:
description:
@@ -89,8 +91,9 @@ notes:
requirements: [ "proxmoxer", "requests" ]
author: Jeffrey van Pelt (@Thulium-Drake)
extends_documentation_fragment:
- - community.general.proxmox.documentation
- - community.general.attributes
+ - community.general.proxmox.actiongroup_proxmox
+ - community.general.proxmox.documentation
+ - community.general.attributes
'''
EXAMPLES = r'''
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_storage_contents_info.py b/ansible_collections/community/general/plugins/modules/proxmox_storage_contents_info.py
index 498490fe4..b777870e5 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_storage_contents_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_storage_contents_info.py
@@ -17,6 +17,9 @@ short_description: List content from a Proxmox VE storage
version_added: 8.2.0
description:
- Retrieves information about stored objects on a specific storage attached to a node.
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
storage:
description:
@@ -41,6 +44,7 @@ options:
type: int
author: Julian Vanden Broeck (@l00ptr)
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
- community.general.attributes.info_module
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_storage_info.py b/ansible_collections/community/general/plugins/modules/proxmox_storage_info.py
index 3c29e59cf..fd5a6ee0d 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_storage_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_storage_info.py
@@ -16,6 +16,9 @@ short_description: Retrieve information about one or more Proxmox VE storages
version_added: 2.2.0
description:
- Retrieve information about one or more Proxmox VE storages.
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
storage:
description:
@@ -28,6 +31,7 @@ options:
type: str
author: Tristan Le Guern (@tleguern)
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
- community.general.attributes.info_module
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_tasks_info.py b/ansible_collections/community/general/plugins/modules/proxmox_tasks_info.py
index d31a04980..65a07566a 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_tasks_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_tasks_info.py
@@ -17,6 +17,9 @@ version_added: 3.8.0
description:
- Retrieve information about one or more Proxmox VE tasks.
author: 'Andreas Botzner (@paginabianca) <andreas at botzner dot com>'
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
node:
description:
@@ -29,9 +32,10 @@ options:
aliases: ['upid', 'name']
type: str
extends_documentation_fragment:
- - community.general.proxmox.documentation
- - community.general.attributes
- - community.general.attributes.info_module
+ - community.general.proxmox.actiongroup_proxmox
+ - community.general.proxmox.documentation
+ - community.general.attributes
+ - community.general.attributes.info_module
'''
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_template.py b/ansible_collections/community/general/plugins/modules/proxmox_template.py
index 615bfc182..f73109931 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_template.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_template.py
@@ -20,6 +20,8 @@ attributes:
support: none
diff_mode:
support: none
+ action_group:
+ version_added: 9.0.0
options:
node:
description:
@@ -69,6 +71,7 @@ notes:
- C(proxmoxer) >= 1.2.0 requires C(requests_toolbelt) to upload files larger than 256 MB.
author: Sergei Antipov (@UnderGreen)
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
'''
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_user_info.py b/ansible_collections/community/general/plugins/modules/proxmox_user_info.py
index 20154528a..8680dec7c 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_user_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_user_info.py
@@ -16,6 +16,9 @@ short_description: Retrieve information about one or more Proxmox VE users
version_added: 1.3.0
description:
- Retrieve information about one or more Proxmox VE users
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
domain:
description:
@@ -33,6 +36,7 @@ options:
type: str
author: Tristan Le Guern (@tleguern)
extends_documentation_fragment:
+ - community.general.proxmox.actiongroup_proxmox
- community.general.proxmox.documentation
- community.general.attributes
- community.general.attributes.info_module
diff --git a/ansible_collections/community/general/plugins/modules/proxmox_vm_info.py b/ansible_collections/community/general/plugins/modules/proxmox_vm_info.py
index 30342b684..39d8307a4 100644
--- a/ansible_collections/community/general/plugins/modules/proxmox_vm_info.py
+++ b/ansible_collections/community/general/plugins/modules/proxmox_vm_info.py
@@ -17,6 +17,9 @@ version_added: 7.2.0
description:
- Retrieve information about one or more Proxmox VE virtual machines.
author: 'Sergei Antipov (@UnderGreen) <greendayonfire at gmail dot com>'
+attributes:
+ action_group:
+ version_added: 9.0.0
options:
node:
description:
@@ -55,9 +58,10 @@ options:
default: none
version_added: 8.1.0
extends_documentation_fragment:
- - community.general.proxmox.documentation
- - community.general.attributes
- - community.general.attributes.info_module
+ - community.general.proxmox.actiongroup_proxmox
+ - community.general.proxmox.documentation
+ - community.general.attributes
+ - community.general.attributes.info_module
"""
EXAMPLES = """
diff --git a/ansible_collections/community/general/plugins/modules/puppet.py b/ansible_collections/community/general/plugins/modules/puppet.py
index b28583fe0..073a08324 100644
--- a/ansible_collections/community/general/plugins/modules/puppet.py
+++ b/ansible_collections/community/general/plugins/modules/puppet.py
@@ -101,6 +101,12 @@ options:
- Whether to print a transaction summary.
type: bool
default: false
+ waitforlock:
+ description:
+ - The maximum amount of time C(puppet) should wait for an already running C(puppet) agent to finish before starting.
+ - If a number without unit is provided, it is assumed to be a number of seconds. Allowed units are V(m) for minutes and V(h) for hours.
+ type: str
+ version_added: 9.0.0
verbose:
description:
- Print extra information.
@@ -159,6 +165,14 @@ EXAMPLES = r'''
skip_tags:
- service
+- name: Wait 30 seconds for any current puppet runs to finish
+ community.general.puppet:
+ waitforlock: 30
+
+- name: Wait 5 minutes for any current puppet runs to finish
+ community.general.puppet:
+ waitforlock: 5m
+
- name: Run puppet agent in noop mode
community.general.puppet:
noop: true
@@ -214,6 +228,7 @@ def main():
skip_tags=dict(type='list', elements='str'),
execute=dict(type='str'),
summarize=dict(type='bool', default=False),
+ waitforlock=dict(type='str'),
debug=dict(type='bool', default=False),
verbose=dict(type='bool', default=False),
use_srv_records=dict(type='bool'),
@@ -247,11 +262,11 @@ def main():
runner = puppet_utils.puppet_runner(module)
if not p['manifest'] and not p['execute']:
- args_order = "_agent_fixed puppetmaster show_diff confdir environment tags skip_tags certname noop use_srv_records"
+ args_order = "_agent_fixed puppetmaster show_diff confdir environment tags skip_tags certname noop use_srv_records waitforlock"
with runner(args_order) as ctx:
rc, stdout, stderr = ctx.run()
else:
- args_order = "_apply_fixed logdest modulepath environment certname tags skip_tags noop _execute summarize debug verbose"
+ args_order = "_apply_fixed logdest modulepath environment certname tags skip_tags noop _execute summarize debug verbose waitforlock"
with runner(args_order) as ctx:
rc, stdout, stderr = ctx.run(_execute=[p['execute'], p['manifest']])
diff --git a/ansible_collections/community/general/plugins/modules/rax.py b/ansible_collections/community/general/plugins/modules/rax.py
deleted file mode 100644
index 76e429944..000000000
--- a/ansible_collections/community/general/plugins/modules/rax.py
+++ /dev/null
@@ -1,903 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax
-short_description: Create / delete an instance in Rackspace Public Cloud
-description:
- - creates / deletes a Rackspace Public Cloud instance and optionally
- waits for it to be 'running'.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- auto_increment:
- description:
- - Whether or not to increment a single number with the name of the
- created servers. Only applicable when used with the O(group) attribute
- or meta key.
- type: bool
- default: true
- boot_from_volume:
- description:
- - Whether or not to boot the instance from a Cloud Block Storage volume.
- If V(true) and O(image) is specified a new volume will be created at
- boot time. O(boot_volume_size) is required with O(image) to create a
- new volume at boot time.
- type: bool
- default: false
- boot_volume:
- type: str
- description:
- - Cloud Block Storage ID or Name to use as the boot volume of the
- instance
- boot_volume_size:
- type: int
- description:
- - Size of the volume to create in Gigabytes. This is only required with
- O(image) and O(boot_from_volume).
- default: 100
- boot_volume_terminate:
- description:
- - Whether the O(boot_volume) or newly created volume from O(image) will
- be terminated when the server is terminated
- type: bool
- default: false
- config_drive:
- description:
- - Attach read-only configuration drive to server as label config-2
- type: bool
- default: false
- count:
- type: int
- description:
- - number of instances to launch
- default: 1
- count_offset:
- type: int
- description:
- - number count to start at
- default: 1
- disk_config:
- type: str
- description:
- - Disk partitioning strategy
- - If not specified it will assume the value V(auto).
- choices:
- - auto
- - manual
- exact_count:
- description:
- - Explicitly ensure an exact count of instances, used with
- state=active/present. If specified as V(true) and O(count) is less than
- the servers matched, servers will be deleted to match the count. If
- the number of matched servers is fewer than specified in O(count)
- additional servers will be added.
- type: bool
- default: false
- extra_client_args:
- type: dict
- default: {}
- description:
- - A hash of key/value pairs to be used when creating the cloudservers
- client. This is considered an advanced option, use it wisely and
- with caution.
- extra_create_args:
- type: dict
- default: {}
- description:
- - A hash of key/value pairs to be used when creating a new server.
- This is considered an advanced option, use it wisely and with caution.
- files:
- type: dict
- default: {}
- description:
- - Files to insert into the instance. remotefilename:localcontent
- flavor:
- type: str
- description:
- - flavor to use for the instance
- group:
- type: str
- description:
- - host group to assign to server, is also used for idempotent operations
- to ensure a specific number of instances
- image:
- type: str
- description:
- - image to use for the instance. Can be an C(id), C(human_id) or C(name).
- With O(boot_from_volume), a Cloud Block Storage volume will be created
- with this image
- instance_ids:
- type: list
- elements: str
- description:
- - list of instance ids, currently only used when state='absent' to
- remove instances
- key_name:
- type: str
- description:
- - key pair to use on the instance
- aliases:
- - keypair
- meta:
- type: dict
- default: {}
- description:
- - A hash of metadata to associate with the instance
- name:
- type: str
- description:
- - Name to give the instance
- networks:
- type: list
- elements: str
- description:
- - The network to attach to the instances. If specified, you must include
- ALL networks including the public and private interfaces. Can be C(id)
- or C(label).
- default:
- - public
- - private
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- user_data:
- type: str
- description:
- - Data to be uploaded to the servers config drive. This option implies
- O(config_drive). Can be a file path or a string
- wait:
- description:
- - wait for the instance to be in state 'running' before returning
- type: bool
- default: false
- wait_timeout:
- type: int
- description:
- - how long before wait gives up, in seconds
- default: 300
-author:
- - "Jesse Keating (@omgjlk)"
- - "Matt Martz (@sivel)"
-notes:
- - O(exact_count) can be "destructive" if the number of running servers in
- the O(group) is larger than that specified in O(count). In such a case, the
- O(state) is effectively set to V(absent) and the extra servers are deleted.
- In the case of deletion, the returned data structure will have RV(ignore:action)
- set to V(delete), and the oldest servers in the group will be deleted.
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a Cloud Server
- gather_facts: false
- tasks:
- - name: Server build request
- local_action:
- module: rax
- credentials: ~/.raxpub
- name: rax-test1
- flavor: 5
- image: b11d9567-e412-4255-96b9-bd63ab23bcfe
- key_name: my_rackspace_key
- files:
- /root/test.txt: /home/localuser/test.txt
- wait: true
- state: present
- networks:
- - private
- - public
- register: rax
-
-- name: Build an exact count of cloud servers with incremented names
- hosts: local
- gather_facts: false
- tasks:
- - name: Server build requests
- local_action:
- module: rax
- credentials: ~/.raxpub
- name: test%03d.example.org
- flavor: performance1-1
- image: ubuntu-1204-lts-precise-pangolin
- state: present
- count: 10
- count_offset: 10
- exact_count: true
- group: test
- wait: true
- register: rax
-'''
-
-import json
-import os
-import re
-import time
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (FINAL_STATUSES, rax_argument_spec, rax_find_bootable_volume,
- rax_find_image, rax_find_network, rax_find_volume,
- rax_required_together, rax_to_dict, setup_rax_module)
-from ansible.module_utils.six.moves import xrange
-from ansible.module_utils.six import string_types
-
-
-def rax_find_server_image(module, server, image, boot_volume):
- if not image and boot_volume:
- vol = rax_find_bootable_volume(module, pyrax, server,
- exit=False)
- if not vol:
- return None
- volume_image_metadata = vol.volume_image_metadata
- vol_image_id = volume_image_metadata.get('image_id')
- if vol_image_id:
- server_image = rax_find_image(module, pyrax,
- vol_image_id, exit=False)
- if server_image:
- server.image = dict(id=server_image)
-
- # Match image IDs taking care of boot from volume
- if image and not server.image:
- vol = rax_find_bootable_volume(module, pyrax, server)
- volume_image_metadata = vol.volume_image_metadata
- vol_image_id = volume_image_metadata.get('image_id')
- if not vol_image_id:
- return None
- server_image = rax_find_image(module, pyrax,
- vol_image_id, exit=False)
- if image != server_image:
- return None
-
- server.image = dict(id=server_image)
- elif image and server.image['id'] != image:
- return None
-
- return server.image
-
-
-def create(module, names=None, flavor=None, image=None, meta=None, key_name=None,
- files=None, wait=True, wait_timeout=300, disk_config=None,
- group=None, nics=None, extra_create_args=None, user_data=None,
- config_drive=False, existing=None, block_device_mapping_v2=None):
- names = [] if names is None else names
- meta = {} if meta is None else meta
- files = {} if files is None else files
- nics = [] if nics is None else nics
- extra_create_args = {} if extra_create_args is None else extra_create_args
- existing = [] if existing is None else existing
- block_device_mapping_v2 = [] if block_device_mapping_v2 is None else block_device_mapping_v2
-
- cs = pyrax.cloudservers
- changed = False
-
- if user_data:
- config_drive = True
-
- if user_data and os.path.isfile(os.path.expanduser(user_data)):
- try:
- user_data = os.path.expanduser(user_data)
- f = open(user_data)
- user_data = f.read()
- f.close()
- except Exception as e:
- module.fail_json(msg='Failed to load %s' % user_data)
-
- # Handle the file contents
- for rpath in files.keys():
- lpath = os.path.expanduser(files[rpath])
- try:
- fileobj = open(lpath, 'r')
- files[rpath] = fileobj.read()
- fileobj.close()
- except Exception as e:
- module.fail_json(msg='Failed to load %s' % lpath)
- try:
- servers = []
- bdmv2 = block_device_mapping_v2
- for name in names:
- servers.append(cs.servers.create(name=name, image=image,
- flavor=flavor, meta=meta,
- key_name=key_name,
- files=files, nics=nics,
- disk_config=disk_config,
- config_drive=config_drive,
- userdata=user_data,
- block_device_mapping_v2=bdmv2,
- **extra_create_args))
- except Exception as e:
- if e.message:
- msg = str(e.message)
- else:
- msg = repr(e)
- module.fail_json(msg=msg)
- else:
- changed = True
-
- if wait:
- end_time = time.time() + wait_timeout
- infinite = wait_timeout == 0
- while infinite or time.time() < end_time:
- for server in servers:
- try:
- server.get()
- except Exception:
- server.status = 'ERROR'
-
- if not filter(lambda s: s.status not in FINAL_STATUSES,
- servers):
- break
- time.sleep(5)
-
- success = []
- error = []
- timeout = []
- for server in servers:
- try:
- server.get()
- except Exception:
- server.status = 'ERROR'
- instance = rax_to_dict(server, 'server')
- if server.status == 'ACTIVE' or not wait:
- success.append(instance)
- elif server.status == 'ERROR':
- error.append(instance)
- elif wait:
- timeout.append(instance)
-
- untouched = [rax_to_dict(s, 'server') for s in existing]
- instances = success + untouched
-
- results = {
- 'changed': changed,
- 'action': 'create',
- 'instances': instances,
- 'success': success,
- 'error': error,
- 'timeout': timeout,
- 'instance_ids': {
- 'instances': [i['id'] for i in instances],
- 'success': [i['id'] for i in success],
- 'error': [i['id'] for i in error],
- 'timeout': [i['id'] for i in timeout]
- }
- }
-
- if timeout:
- results['msg'] = 'Timeout waiting for all servers to build'
- elif error:
- results['msg'] = 'Failed to build all servers'
-
- if 'msg' in results:
- module.fail_json(**results)
- else:
- module.exit_json(**results)
-
-
-def delete(module, instance_ids=None, wait=True, wait_timeout=300, kept=None):
- instance_ids = [] if instance_ids is None else instance_ids
- kept = [] if kept is None else kept
-
- cs = pyrax.cloudservers
-
- changed = False
- instances = {}
- servers = []
-
- for instance_id in instance_ids:
- servers.append(cs.servers.get(instance_id))
-
- for server in servers:
- try:
- server.delete()
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- changed = True
-
- instance = rax_to_dict(server, 'server')
- instances[instance['id']] = instance
-
- # If requested, wait for server deletion
- if wait:
- end_time = time.time() + wait_timeout
- infinite = wait_timeout == 0
- while infinite or time.time() < end_time:
- for server in servers:
- instance_id = server.id
- try:
- server.get()
- except Exception:
- instances[instance_id]['status'] = 'DELETED'
- instances[instance_id]['rax_status'] = 'DELETED'
-
- if not filter(lambda s: s['status'] not in ('', 'DELETED',
- 'ERROR'),
- instances.values()):
- break
-
- time.sleep(5)
-
- timeout = filter(lambda s: s['status'] not in ('', 'DELETED', 'ERROR'),
- instances.values())
- error = filter(lambda s: s['status'] in ('ERROR'),
- instances.values())
- success = filter(lambda s: s['status'] in ('', 'DELETED'),
- instances.values())
-
- instances = [rax_to_dict(s, 'server') for s in kept]
-
- results = {
- 'changed': changed,
- 'action': 'delete',
- 'instances': instances,
- 'success': success,
- 'error': error,
- 'timeout': timeout,
- 'instance_ids': {
- 'instances': [i['id'] for i in instances],
- 'success': [i['id'] for i in success],
- 'error': [i['id'] for i in error],
- 'timeout': [i['id'] for i in timeout]
- }
- }
-
- if timeout:
- results['msg'] = 'Timeout waiting for all servers to delete'
- elif error:
- results['msg'] = 'Failed to delete all servers'
-
- if 'msg' in results:
- module.fail_json(**results)
- else:
- module.exit_json(**results)
-
-
-def cloudservers(module, state=None, name=None, flavor=None, image=None,
- meta=None, key_name=None, files=None, wait=True, wait_timeout=300,
- disk_config=None, count=1, group=None, instance_ids=None,
- exact_count=False, networks=None, count_offset=0,
- auto_increment=False, extra_create_args=None, user_data=None,
- config_drive=False, boot_from_volume=False,
- boot_volume=None, boot_volume_size=None,
- boot_volume_terminate=False):
- meta = {} if meta is None else meta
- files = {} if files is None else files
- instance_ids = [] if instance_ids is None else instance_ids
- networks = [] if networks is None else networks
- extra_create_args = {} if extra_create_args is None else extra_create_args
-
- cs = pyrax.cloudservers
- cnw = pyrax.cloud_networks
- if not cnw:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if state == 'present' or (state == 'absent' and instance_ids is None):
- if not boot_from_volume and not boot_volume and not image:
- module.fail_json(msg='image is required for the "rax" module')
-
- for arg, value in dict(name=name, flavor=flavor).items():
- if not value:
- module.fail_json(msg='%s is required for the "rax" module' %
- arg)
-
- if boot_from_volume and not image and not boot_volume:
- module.fail_json(msg='image or boot_volume are required for the '
- '"rax" with boot_from_volume')
-
- if boot_from_volume and image and not boot_volume_size:
- module.fail_json(msg='boot_volume_size is required for the "rax" '
- 'module with boot_from_volume and image')
-
- if boot_from_volume and image and boot_volume:
- image = None
-
- servers = []
-
- # Add the group meta key
- if group and 'group' not in meta:
- meta['group'] = group
- elif 'group' in meta and group is None:
- group = meta['group']
-
- # Normalize and ensure all metadata values are strings
- for k, v in meta.items():
- if isinstance(v, list):
- meta[k] = ','.join(['%s' % i for i in v])
- elif isinstance(v, dict):
- meta[k] = json.dumps(v)
- elif not isinstance(v, string_types):
- meta[k] = '%s' % v
-
- # When using state=absent with group, the absent block won't match the
- # names properly. Use the exact_count functionality to decrease the count
- # to the desired level
- was_absent = False
- if group is not None and state == 'absent':
- exact_count = True
- state = 'present'
- was_absent = True
-
- if image:
- image = rax_find_image(module, pyrax, image)
-
- nics = []
- if networks:
- for network in networks:
- nics.extend(rax_find_network(module, pyrax, network))
-
- # act on the state
- if state == 'present':
- # Idempotent ensurance of a specific count of servers
- if exact_count is not False:
- # See if we can find servers that match our options
- if group is None:
- module.fail_json(msg='"group" must be provided when using '
- '"exact_count"')
-
- if auto_increment:
- numbers = set()
-
- # See if the name is a printf like string, if not append
- # %d to the end
- try:
- name % 0
- except TypeError as e:
- if e.message.startswith('not all'):
- name = '%s%%d' % name
- else:
- module.fail_json(msg=e.message)
-
- # regex pattern to match printf formatting
- pattern = re.sub(r'%\d*[sd]', r'(\d+)', name)
- for server in cs.servers.list():
- # Ignore DELETED servers
- if server.status == 'DELETED':
- continue
- if server.metadata.get('group') == group:
- servers.append(server)
- match = re.search(pattern, server.name)
- if match:
- number = int(match.group(1))
- numbers.add(number)
-
- number_range = xrange(count_offset, count_offset + count)
- available_numbers = list(set(number_range)
- .difference(numbers))
- else: # Not auto incrementing
- for server in cs.servers.list():
- # Ignore DELETED servers
- if server.status == 'DELETED':
- continue
- if server.metadata.get('group') == group:
- servers.append(server)
- # available_numbers not needed here, we inspect auto_increment
- # again later
-
- # If state was absent but the count was changed,
- # assume we only wanted to remove that number of instances
- if was_absent:
- diff = len(servers) - count
- if diff < 0:
- count = 0
- else:
- count = diff
-
- if len(servers) > count:
- # We have more servers than we need, set state='absent'
- # and delete the extras, this should delete the oldest
- state = 'absent'
- kept = servers[:count]
- del servers[:count]
- instance_ids = []
- for server in servers:
- instance_ids.append(server.id)
- delete(module, instance_ids=instance_ids, wait=wait,
- wait_timeout=wait_timeout, kept=kept)
- elif len(servers) < count:
- # we have fewer servers than we need
- if auto_increment:
- # auto incrementing server numbers
- names = []
- name_slice = count - len(servers)
- numbers_to_use = available_numbers[:name_slice]
- for number in numbers_to_use:
- names.append(name % number)
- else:
- # We are not auto incrementing server numbers,
- # create a list of 'name' that matches how many we need
- names = [name] * (count - len(servers))
- else:
- # we have the right number of servers, just return info
- # about all of the matched servers
- instances = []
- instance_ids = []
- for server in servers:
- instances.append(rax_to_dict(server, 'server'))
- instance_ids.append(server.id)
- module.exit_json(changed=False, action=None,
- instances=instances,
- success=[], error=[], timeout=[],
- instance_ids={'instances': instance_ids,
- 'success': [], 'error': [],
- 'timeout': []})
- else: # not called with exact_count=True
- if group is not None:
- if auto_increment:
- # we are auto incrementing server numbers, but not with
- # exact_count
- numbers = set()
-
- # See if the name is a printf like string, if not append
- # %d to the end
- try:
- name % 0
- except TypeError as e:
- if e.message.startswith('not all'):
- name = '%s%%d' % name
- else:
- module.fail_json(msg=e.message)
-
- # regex pattern to match printf formatting
- pattern = re.sub(r'%\d*[sd]', r'(\d+)', name)
- for server in cs.servers.list():
- # Ignore DELETED servers
- if server.status == 'DELETED':
- continue
- if server.metadata.get('group') == group:
- servers.append(server)
- match = re.search(pattern, server.name)
- if match:
- number = int(match.group(1))
- numbers.add(number)
-
- number_range = xrange(count_offset,
- count_offset + count + len(numbers))
- available_numbers = list(set(number_range)
- .difference(numbers))
- names = []
- numbers_to_use = available_numbers[:count]
- for number in numbers_to_use:
- names.append(name % number)
- else:
- # Not auto incrementing
- names = [name] * count
- else:
- # No group was specified, and not using exact_count
- # Perform more simplistic matching
- search_opts = {
- 'name': '^%s$' % name,
- 'flavor': flavor
- }
- servers = []
- for server in cs.servers.list(search_opts=search_opts):
- # Ignore DELETED servers
- if server.status == 'DELETED':
- continue
-
- if not rax_find_server_image(module, server, image,
- boot_volume):
- continue
-
- # Ignore servers with non matching metadata
- if server.metadata != meta:
- continue
- servers.append(server)
-
- if len(servers) >= count:
- # We have more servers than were requested, don't do
- # anything. Not running with exact_count=True, so we assume
- # more is OK
- instances = []
- for server in servers:
- instances.append(rax_to_dict(server, 'server'))
-
- instance_ids = [i['id'] for i in instances]
- module.exit_json(changed=False, action=None,
- instances=instances, success=[], error=[],
- timeout=[],
- instance_ids={'instances': instance_ids,
- 'success': [], 'error': [],
- 'timeout': []})
-
- # We need more servers to reach out target, create names for
- # them, we aren't performing auto_increment here
- names = [name] * (count - len(servers))
-
- block_device_mapping_v2 = []
- if boot_from_volume:
- mapping = {
- 'boot_index': '0',
- 'delete_on_termination': boot_volume_terminate,
- 'destination_type': 'volume',
- }
- if image:
- mapping.update({
- 'uuid': image,
- 'source_type': 'image',
- 'volume_size': boot_volume_size,
- })
- image = None
- elif boot_volume:
- volume = rax_find_volume(module, pyrax, boot_volume)
- mapping.update({
- 'uuid': pyrax.utils.get_id(volume),
- 'source_type': 'volume',
- })
- block_device_mapping_v2.append(mapping)
-
- create(module, names=names, flavor=flavor, image=image,
- meta=meta, key_name=key_name, files=files, wait=wait,
- wait_timeout=wait_timeout, disk_config=disk_config, group=group,
- nics=nics, extra_create_args=extra_create_args,
- user_data=user_data, config_drive=config_drive,
- existing=servers,
- block_device_mapping_v2=block_device_mapping_v2)
-
- elif state == 'absent':
- if instance_ids is None:
- # We weren't given an explicit list of server IDs to delete
- # Let's match instead
- search_opts = {
- 'name': '^%s$' % name,
- 'flavor': flavor
- }
- for server in cs.servers.list(search_opts=search_opts):
- # Ignore DELETED servers
- if server.status == 'DELETED':
- continue
-
- if not rax_find_server_image(module, server, image,
- boot_volume):
- continue
-
- # Ignore servers with non matching metadata
- if meta != server.metadata:
- continue
-
- servers.append(server)
-
- # Build a list of server IDs to delete
- instance_ids = []
- for server in servers:
- if len(instance_ids) < count:
- instance_ids.append(server.id)
- else:
- break
-
- if not instance_ids:
- # No server IDs were matched for deletion, or no IDs were
- # explicitly provided, just exit and don't do anything
- module.exit_json(changed=False, action=None, instances=[],
- success=[], error=[], timeout=[],
- instance_ids={'instances': [],
- 'success': [], 'error': [],
- 'timeout': []})
-
- delete(module, instance_ids=instance_ids, wait=wait,
- wait_timeout=wait_timeout)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- auto_increment=dict(default=True, type='bool'),
- boot_from_volume=dict(default=False, type='bool'),
- boot_volume=dict(type='str'),
- boot_volume_size=dict(type='int', default=100),
- boot_volume_terminate=dict(type='bool', default=False),
- config_drive=dict(default=False, type='bool'),
- count=dict(default=1, type='int'),
- count_offset=dict(default=1, type='int'),
- disk_config=dict(choices=['auto', 'manual']),
- exact_count=dict(default=False, type='bool'),
- extra_client_args=dict(type='dict', default={}),
- extra_create_args=dict(type='dict', default={}),
- files=dict(type='dict', default={}),
- flavor=dict(),
- group=dict(),
- image=dict(),
- instance_ids=dict(type='list', elements='str'),
- key_name=dict(aliases=['keypair']),
- meta=dict(type='dict', default={}),
- name=dict(),
- networks=dict(type='list', elements='str', default=['public', 'private']),
- state=dict(default='present', choices=['present', 'absent']),
- user_data=dict(no_log=True),
- wait=dict(default=False, type='bool'),
- wait_timeout=dict(default=300, type='int'),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- auto_increment = module.params.get('auto_increment')
- boot_from_volume = module.params.get('boot_from_volume')
- boot_volume = module.params.get('boot_volume')
- boot_volume_size = module.params.get('boot_volume_size')
- boot_volume_terminate = module.params.get('boot_volume_terminate')
- config_drive = module.params.get('config_drive')
- count = module.params.get('count')
- count_offset = module.params.get('count_offset')
- disk_config = module.params.get('disk_config')
- if disk_config:
- disk_config = disk_config.upper()
- exact_count = module.params.get('exact_count', False)
- extra_client_args = module.params.get('extra_client_args')
- extra_create_args = module.params.get('extra_create_args')
- files = module.params.get('files')
- flavor = module.params.get('flavor')
- group = module.params.get('group')
- image = module.params.get('image')
- instance_ids = module.params.get('instance_ids')
- key_name = module.params.get('key_name')
- meta = module.params.get('meta')
- name = module.params.get('name')
- networks = module.params.get('networks')
- state = module.params.get('state')
- user_data = module.params.get('user_data')
- wait = module.params.get('wait')
- wait_timeout = int(module.params.get('wait_timeout'))
-
- setup_rax_module(module, pyrax)
-
- if extra_client_args:
- pyrax.cloudservers = pyrax.connect_to_cloudservers(
- region=pyrax.cloudservers.client.region_name,
- **extra_client_args)
- client = pyrax.cloudservers.client
- if 'bypass_url' in extra_client_args:
- client.management_url = extra_client_args['bypass_url']
-
- if pyrax.cloudservers is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- cloudservers(module, state=state, name=name, flavor=flavor,
- image=image, meta=meta, key_name=key_name, files=files,
- wait=wait, wait_timeout=wait_timeout, disk_config=disk_config,
- count=count, group=group, instance_ids=instance_ids,
- exact_count=exact_count, networks=networks,
- count_offset=count_offset, auto_increment=auto_increment,
- extra_create_args=extra_create_args, user_data=user_data,
- config_drive=config_drive, boot_from_volume=boot_from_volume,
- boot_volume=boot_volume, boot_volume_size=boot_volume_size,
- boot_volume_terminate=boot_volume_terminate)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_cbs.py b/ansible_collections/community/general/plugins/modules/rax_cbs.py
deleted file mode 100644
index 77e7cebad..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_cbs.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_cbs
-short_description: Manipulate Rackspace Cloud Block Storage Volumes
-description:
- - Manipulate Rackspace Cloud Block Storage Volumes
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- description:
- type: str
- description:
- - Description to give the volume being created.
- image:
- type: str
- description:
- - Image to use for bootable volumes. Can be an C(id), C(human_id) or
- C(name). This option requires C(pyrax>=1.9.3).
- meta:
- type: dict
- default: {}
- description:
- - A hash of metadata to associate with the volume.
- name:
- type: str
- description:
- - Name to give the volume being created.
- required: true
- size:
- type: int
- description:
- - Size of the volume to create in Gigabytes.
- default: 100
- snapshot_id:
- type: str
- description:
- - The id of the snapshot to create the volume from.
- state:
- type: str
- description:
- - Indicate desired state of the resource.
- choices:
- - present
- - absent
- default: present
- volume_type:
- type: str
- description:
- - Type of the volume being created.
- choices:
- - SATA
- - SSD
- default: SATA
- wait:
- description:
- - Wait for the volume to be in state C(available) before returning.
- type: bool
- default: false
- wait_timeout:
- type: int
- description:
- - how long before wait gives up, in seconds.
- default: 300
-author:
- - "Christopher H. Laco (@claco)"
- - "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a Block Storage Volume
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Storage volume create request
- local_action:
- module: rax_cbs
- credentials: ~/.raxpub
- name: my-volume
- description: My Volume
- volume_type: SSD
- size: 150
- region: DFW
- wait: true
- state: present
- meta:
- app: my-cool-app
- register: my_volume
-'''
-
-from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (VOLUME_STATUS, rax_argument_spec, rax_find_image, rax_find_volume,
- rax_required_together, rax_to_dict, setup_rax_module)
-
-
-def cloud_block_storage(module, state, name, description, meta, size,
- snapshot_id, volume_type, wait, wait_timeout,
- image):
- changed = False
- volume = None
- instance = {}
-
- cbs = pyrax.cloud_blockstorage
-
- if cbs is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if image:
- # pyrax<1.9.3 did not have support for specifying an image when
- # creating a volume which is required for bootable volumes
- if LooseVersion(pyrax.version.version) < LooseVersion('1.9.3'):
- module.fail_json(msg='Creating a bootable volume requires '
- 'pyrax>=1.9.3')
- image = rax_find_image(module, pyrax, image)
-
- volume = rax_find_volume(module, pyrax, name)
-
- if state == 'present':
- if not volume:
- kwargs = dict()
- if image:
- kwargs['image'] = image
- try:
- volume = cbs.create(name, size=size, volume_type=volume_type,
- description=description,
- metadata=meta,
- snapshot_id=snapshot_id, **kwargs)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- if wait:
- attempts = wait_timeout // 5
- pyrax.utils.wait_for_build(volume, interval=5,
- attempts=attempts)
-
- volume.get()
- instance = rax_to_dict(volume)
-
- result = dict(changed=changed, volume=instance)
-
- if volume.status == 'error':
- result['msg'] = '%s failed to build' % volume.id
- elif wait and volume.status not in VOLUME_STATUS:
- result['msg'] = 'Timeout waiting on %s' % volume.id
-
- if 'msg' in result:
- module.fail_json(**result)
- else:
- module.exit_json(**result)
-
- elif state == 'absent':
- if volume:
- instance = rax_to_dict(volume)
- try:
- volume.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, volume=instance)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- description=dict(type='str'),
- image=dict(type='str'),
- meta=dict(type='dict', default={}),
- name=dict(required=True),
- size=dict(type='int', default=100),
- snapshot_id=dict(),
- state=dict(default='present', choices=['present', 'absent']),
- volume_type=dict(choices=['SSD', 'SATA'], default='SATA'),
- wait=dict(type='bool', default=False),
- wait_timeout=dict(type='int', default=300)
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- description = module.params.get('description')
- image = module.params.get('image')
- meta = module.params.get('meta')
- name = module.params.get('name')
- size = module.params.get('size')
- snapshot_id = module.params.get('snapshot_id')
- state = module.params.get('state')
- volume_type = module.params.get('volume_type')
- wait = module.params.get('wait')
- wait_timeout = module.params.get('wait_timeout')
-
- setup_rax_module(module, pyrax)
-
- cloud_block_storage(module, state, name, description, meta, size,
- snapshot_id, volume_type, wait, wait_timeout,
- image)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_cbs_attachments.py b/ansible_collections/community/general/plugins/modules/rax_cbs_attachments.py
deleted file mode 100644
index 00b860a90..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_cbs_attachments.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_cbs_attachments
-short_description: Manipulate Rackspace Cloud Block Storage Volume Attachments
-description:
- - Manipulate Rackspace Cloud Block Storage Volume Attachments
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- device:
- type: str
- description:
- - The device path to attach the volume to, e.g. /dev/xvde.
- - Before 2.4 this was a required field. Now it can be left to null to auto assign the device name.
- volume:
- type: str
- description:
- - Name or id of the volume to attach/detach
- required: true
- server:
- type: str
- description:
- - Name or id of the server to attach/detach
- required: true
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- wait:
- description:
- - wait for the volume to be in 'in-use'/'available' state before returning
- type: bool
- default: false
- wait_timeout:
- type: int
- description:
- - how long before wait gives up, in seconds
- default: 300
-author:
- - "Christopher H. Laco (@claco)"
- - "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Attach a Block Storage Volume
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Storage volume attach request
- local_action:
- module: rax_cbs_attachments
- credentials: ~/.raxpub
- volume: my-volume
- server: my-server
- device: /dev/xvdd
- region: DFW
- wait: true
- state: present
- register: my_volume
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (NON_CALLABLES,
- rax_argument_spec,
- rax_find_server,
- rax_find_volume,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def cloud_block_storage_attachments(module, state, volume, server, device,
- wait, wait_timeout):
- cbs = pyrax.cloud_blockstorage
- cs = pyrax.cloudservers
-
- if cbs is None or cs is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- changed = False
- instance = {}
-
- volume = rax_find_volume(module, pyrax, volume)
-
- if not volume:
- module.fail_json(msg='No matching storage volumes were found')
-
- if state == 'present':
- server = rax_find_server(module, pyrax, server)
-
- if (volume.attachments and
- volume.attachments[0]['server_id'] == server.id):
- changed = False
- elif volume.attachments:
- module.fail_json(msg='Volume is attached to another server')
- else:
- try:
- volume.attach_to_instance(server, mountpoint=device)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- volume.get()
-
- for key, value in vars(volume).items():
- if (isinstance(value, NON_CALLABLES) and
- not key.startswith('_')):
- instance[key] = value
-
- result = dict(changed=changed)
-
- if volume.status == 'error':
- result['msg'] = '%s failed to build' % volume.id
- elif wait:
- attempts = wait_timeout // 5
- pyrax.utils.wait_until(volume, 'status', 'in-use',
- interval=5, attempts=attempts)
-
- volume.get()
- result['volume'] = rax_to_dict(volume)
-
- if 'msg' in result:
- module.fail_json(**result)
- else:
- module.exit_json(**result)
-
- elif state == 'absent':
- server = rax_find_server(module, pyrax, server)
-
- if (volume.attachments and
- volume.attachments[0]['server_id'] == server.id):
- try:
- volume.detach()
- if wait:
- pyrax.utils.wait_until(volume, 'status', 'available',
- interval=3, attempts=0,
- verbose=False)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- volume.get()
- changed = True
- elif volume.attachments:
- module.fail_json(msg='Volume is attached to another server')
-
- result = dict(changed=changed, volume=rax_to_dict(volume))
-
- if volume.status == 'error':
- result['msg'] = '%s failed to build' % volume.id
-
- if 'msg' in result:
- module.fail_json(**result)
- else:
- module.exit_json(**result)
-
- module.exit_json(changed=changed, volume=instance)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- device=dict(required=False),
- volume=dict(required=True),
- server=dict(required=True),
- state=dict(default='present', choices=['present', 'absent']),
- wait=dict(type='bool', default=False),
- wait_timeout=dict(type='int', default=300)
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- device = module.params.get('device')
- volume = module.params.get('volume')
- server = module.params.get('server')
- state = module.params.get('state')
- wait = module.params.get('wait')
- wait_timeout = module.params.get('wait_timeout')
-
- setup_rax_module(module, pyrax)
-
- cloud_block_storage_attachments(module, state, volume, server, device,
- wait, wait_timeout)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_cdb.py b/ansible_collections/community/general/plugins/modules/rax_cdb.py
deleted file mode 100644
index 9538579fa..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_cdb.py
+++ /dev/null
@@ -1,266 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_cdb
-short_description: Create/delete or resize a Rackspace Cloud Databases instance
-description:
- - creates / deletes or resize a Rackspace Cloud Databases instance
- and optionally waits for it to be 'running'. The name option needs to be
- unique since it's used to identify the instance.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- name:
- type: str
- description:
- - Name of the databases server instance
- required: true
- flavor:
- type: int
- description:
- - flavor to use for the instance 1 to 6 (i.e. 512MB to 16GB)
- default: 1
- volume:
- type: int
- description:
- - Volume size of the database 1-150GB
- default: 2
- cdb_type:
- type: str
- description:
- - type of instance (i.e. MySQL, MariaDB, Percona)
- default: MySQL
- aliases: ['type']
- cdb_version:
- type: str
- description:
- - version of database (MySQL supports 5.1 and 5.6, MariaDB supports 10, Percona supports 5.6)
- - "The available choices are: V(5.1), V(5.6) and V(10)."
- default: '5.6'
- aliases: ['version']
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices: ['present', 'absent']
- default: present
- wait:
- description:
- - wait for the instance to be in state 'running' before returning
- type: bool
- default: false
- wait_timeout:
- type: int
- description:
- - how long before wait gives up, in seconds
- default: 300
-author: "Simon JAILLET (@jails)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a Cloud Databases
- gather_facts: false
- tasks:
- - name: Server build request
- local_action:
- module: rax_cdb
- credentials: ~/.raxpub
- region: IAD
- name: db-server1
- flavor: 1
- volume: 2
- cdb_type: MySQL
- cdb_version: 5.6
- wait: true
- state: present
- register: rax_db_server
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, rax_to_dict, setup_rax_module
-
-
-def find_instance(name):
-
- cdb = pyrax.cloud_databases
- instances = cdb.list()
- if instances:
- for instance in instances:
- if instance.name == name:
- return instance
- return False
-
-
-def save_instance(module, name, flavor, volume, cdb_type, cdb_version, wait,
- wait_timeout):
-
- for arg, value in dict(name=name, flavor=flavor,
- volume=volume, type=cdb_type, version=cdb_version
- ).items():
- if not value:
- module.fail_json(msg='%s is required for the "rax_cdb"'
- ' module' % arg)
-
- if not (volume >= 1 and volume <= 150):
- module.fail_json(msg='volume is required to be between 1 and 150')
-
- cdb = pyrax.cloud_databases
-
- flavors = []
- for item in cdb.list_flavors():
- flavors.append(item.id)
-
- if not (flavor in flavors):
- module.fail_json(msg='unexisting flavor reference "%s"' % str(flavor))
-
- changed = False
-
- instance = find_instance(name)
-
- if not instance:
- action = 'create'
- try:
- instance = cdb.create(name=name, flavor=flavor, volume=volume,
- type=cdb_type, version=cdb_version)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
-
- else:
- action = None
-
- if instance.volume.size != volume:
- action = 'resize'
- if instance.volume.size > volume:
- module.fail_json(changed=False, action=action,
- msg='The new volume size must be larger than '
- 'the current volume size',
- cdb=rax_to_dict(instance))
- instance.resize_volume(volume)
- changed = True
-
- if int(instance.flavor.id) != flavor:
- action = 'resize'
- pyrax.utils.wait_until(instance, 'status', 'ACTIVE',
- attempts=wait_timeout)
- instance.resize(flavor)
- changed = True
-
- if wait:
- pyrax.utils.wait_until(instance, 'status', 'ACTIVE',
- attempts=wait_timeout)
-
- if wait and instance.status != 'ACTIVE':
- module.fail_json(changed=changed, action=action,
- cdb=rax_to_dict(instance),
- msg='Timeout waiting for "%s" databases instance to '
- 'be created' % name)
-
- module.exit_json(changed=changed, action=action, cdb=rax_to_dict(instance))
-
-
-def delete_instance(module, name, wait, wait_timeout):
-
- if not name:
- module.fail_json(msg='name is required for the "rax_cdb" module')
-
- changed = False
-
- instance = find_instance(name)
- if not instance:
- module.exit_json(changed=False, action='delete')
-
- try:
- instance.delete()
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
-
- if wait:
- pyrax.utils.wait_until(instance, 'status', 'SHUTDOWN',
- attempts=wait_timeout)
-
- if wait and instance.status != 'SHUTDOWN':
- module.fail_json(changed=changed, action='delete',
- cdb=rax_to_dict(instance),
- msg='Timeout waiting for "%s" databases instance to '
- 'be deleted' % name)
-
- module.exit_json(changed=changed, action='delete',
- cdb=rax_to_dict(instance))
-
-
-def rax_cdb(module, state, name, flavor, volume, cdb_type, cdb_version, wait,
- wait_timeout):
-
- # act on the state
- if state == 'present':
- save_instance(module, name, flavor, volume, cdb_type, cdb_version, wait,
- wait_timeout)
- elif state == 'absent':
- delete_instance(module, name, wait, wait_timeout)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- name=dict(type='str', required=True),
- flavor=dict(type='int', default=1),
- volume=dict(type='int', default=2),
- cdb_type=dict(type='str', default='MySQL', aliases=['type']),
- cdb_version=dict(type='str', default='5.6', aliases=['version']),
- state=dict(default='present', choices=['present', 'absent']),
- wait=dict(type='bool', default=False),
- wait_timeout=dict(type='int', default=300),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- name = module.params.get('name')
- flavor = module.params.get('flavor')
- volume = module.params.get('volume')
- cdb_type = module.params.get('cdb_type')
- cdb_version = module.params.get('cdb_version')
- state = module.params.get('state')
- wait = module.params.get('wait')
- wait_timeout = module.params.get('wait_timeout')
-
- setup_rax_module(module, pyrax)
- rax_cdb(module, state, name, flavor, volume, cdb_type, cdb_version, wait, wait_timeout)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_cdb_database.py b/ansible_collections/community/general/plugins/modules/rax_cdb_database.py
deleted file mode 100644
index b0db11814..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_cdb_database.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
-module: rax_cdb_database
-short_description: Create / delete a database in the Cloud Databases
-description:
- - create / delete a database in the Cloud Databases.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- cdb_id:
- type: str
- description:
- - The databases server UUID
- required: true
- name:
- type: str
- description:
- - Name to give to the database
- required: true
- character_set:
- type: str
- description:
- - Set of symbols and encodings
- default: 'utf8'
- collate:
- type: str
- description:
- - Set of rules for comparing characters in a character set
- default: 'utf8_general_ci'
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices: ['present', 'absent']
- default: present
-author: "Simon JAILLET (@jails)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a database in Cloud Databases
- tasks:
- - name: Database build request
- local_action:
- module: rax_cdb_database
- credentials: ~/.raxpub
- region: IAD
- cdb_id: 323e7ce0-9cb0-11e3-a5e2-0800200c9a66
- name: db1
- state: present
- register: rax_db_database
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, rax_to_dict, setup_rax_module
-
-
-def find_database(instance, name):
- try:
- database = instance.get_database(name)
- except Exception:
- return False
-
- return database
-
-
-def save_database(module, cdb_id, name, character_set, collate):
- cdb = pyrax.cloud_databases
-
- try:
- instance = cdb.get(cdb_id)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- changed = False
-
- database = find_database(instance, name)
-
- if not database:
- try:
- database = instance.create_database(name=name,
- character_set=character_set,
- collate=collate)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
-
- module.exit_json(changed=changed, action='create',
- database=rax_to_dict(database))
-
-
-def delete_database(module, cdb_id, name):
- cdb = pyrax.cloud_databases
-
- try:
- instance = cdb.get(cdb_id)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- changed = False
-
- database = find_database(instance, name)
-
- if database:
- try:
- database.delete()
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
-
- module.exit_json(changed=changed, action='delete',
- database=rax_to_dict(database))
-
-
-def rax_cdb_database(module, state, cdb_id, name, character_set, collate):
-
- # act on the state
- if state == 'present':
- save_database(module, cdb_id, name, character_set, collate)
- elif state == 'absent':
- delete_database(module, cdb_id, name)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- cdb_id=dict(type='str', required=True),
- name=dict(type='str', required=True),
- character_set=dict(type='str', default='utf8'),
- collate=dict(type='str', default='utf8_general_ci'),
- state=dict(default='present', choices=['present', 'absent'])
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- cdb_id = module.params.get('cdb_id')
- name = module.params.get('name')
- character_set = module.params.get('character_set')
- collate = module.params.get('collate')
- state = module.params.get('state')
-
- setup_rax_module(module, pyrax)
- rax_cdb_database(module, state, cdb_id, name, character_set, collate)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_cdb_user.py b/ansible_collections/community/general/plugins/modules/rax_cdb_user.py
deleted file mode 100644
index 6ee86c4fe..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_cdb_user.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_cdb_user
-short_description: Create / delete a Rackspace Cloud Database
-description:
- - create / delete a database in the Cloud Databases.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- cdb_id:
- type: str
- description:
- - The databases server UUID
- required: true
- db_username:
- type: str
- description:
- - Name of the database user
- required: true
- db_password:
- type: str
- description:
- - Database user password
- required: true
- databases:
- type: list
- elements: str
- description:
- - Name of the databases that the user can access
- default: []
- host:
- type: str
- description:
- - Specifies the host from which a user is allowed to connect to
- the database. Possible values are a string containing an IPv4 address
- or "%" to allow connecting from any host
- default: '%'
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices: ['present', 'absent']
- default: present
-author: "Simon JAILLET (@jails)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a user in Cloud Databases
- tasks:
- - name: User build request
- local_action:
- module: rax_cdb_user
- credentials: ~/.raxpub
- region: IAD
- cdb_id: 323e7ce0-9cb0-11e3-a5e2-0800200c9a66
- db_username: user1
- db_password: user1
- databases: ['db1']
- state: present
- register: rax_db_user
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_text
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, rax_to_dict, setup_rax_module
-
-
-def find_user(instance, name):
- try:
- user = instance.get_user(name)
- except Exception:
- return False
-
- return user
-
-
-def save_user(module, cdb_id, name, password, databases, host):
-
- for arg, value in dict(cdb_id=cdb_id, name=name).items():
- if not value:
- module.fail_json(msg='%s is required for the "rax_cdb_user" '
- 'module' % arg)
-
- cdb = pyrax.cloud_databases
-
- try:
- instance = cdb.get(cdb_id)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- changed = False
-
- user = find_user(instance, name)
-
- if not user:
- action = 'create'
- try:
- user = instance.create_user(name=name,
- password=password,
- database_names=databases,
- host=host)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
- else:
- action = 'update'
-
- if user.host != host:
- changed = True
-
- user.update(password=password, host=host)
-
- former_dbs = set([item.name for item in user.list_user_access()])
- databases = set(databases)
-
- if databases != former_dbs:
- try:
- revoke_dbs = [db for db in former_dbs if db not in databases]
- user.revoke_user_access(db_names=revoke_dbs)
-
- new_dbs = [db for db in databases if db not in former_dbs]
- user.grant_user_access(db_names=new_dbs)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
-
- module.exit_json(changed=changed, action=action, user=rax_to_dict(user))
-
-
-def delete_user(module, cdb_id, name):
-
- for arg, value in dict(cdb_id=cdb_id, name=name).items():
- if not value:
- module.fail_json(msg='%s is required for the "rax_cdb_user"'
- ' module' % arg)
-
- cdb = pyrax.cloud_databases
-
- try:
- instance = cdb.get(cdb_id)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- changed = False
-
- user = find_user(instance, name)
-
- if user:
- try:
- user.delete()
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- changed = True
-
- module.exit_json(changed=changed, action='delete')
-
-
-def rax_cdb_user(module, state, cdb_id, name, password, databases, host):
-
- # act on the state
- if state == 'present':
- save_user(module, cdb_id, name, password, databases, host)
- elif state == 'absent':
- delete_user(module, cdb_id, name)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- cdb_id=dict(type='str', required=True),
- db_username=dict(type='str', required=True),
- db_password=dict(type='str', required=True, no_log=True),
- databases=dict(type='list', elements='str', default=[]),
- host=dict(type='str', default='%'),
- state=dict(default='present', choices=['present', 'absent'])
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- cdb_id = module.params.get('cdb_id')
- name = module.params.get('db_username')
- password = module.params.get('db_password')
- databases = module.params.get('databases')
- host = to_text(module.params.get('host'), errors='surrogate_or_strict')
- state = module.params.get('state')
-
- setup_rax_module(module, pyrax)
- rax_cdb_user(module, state, cdb_id, name, password, databases, host)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_clb.py b/ansible_collections/community/general/plugins/modules/rax_clb.py
deleted file mode 100644
index 23c795f39..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_clb.py
+++ /dev/null
@@ -1,320 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_clb
-short_description: Create / delete a load balancer in Rackspace Public Cloud
-description:
- - creates / deletes a Rackspace Public Cloud load balancer.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- algorithm:
- type: str
- description:
- - algorithm for the balancer being created
- choices:
- - RANDOM
- - LEAST_CONNECTIONS
- - ROUND_ROBIN
- - WEIGHTED_LEAST_CONNECTIONS
- - WEIGHTED_ROUND_ROBIN
- default: LEAST_CONNECTIONS
- meta:
- type: dict
- default: {}
- description:
- - A hash of metadata to associate with the instance
- name:
- type: str
- description:
- - Name to give the load balancer
- required: true
- port:
- type: int
- description:
- - Port for the balancer being created
- default: 80
- protocol:
- type: str
- description:
- - Protocol for the balancer being created
- choices:
- - DNS_TCP
- - DNS_UDP
- - FTP
- - HTTP
- - HTTPS
- - IMAPS
- - IMAPv4
- - LDAP
- - LDAPS
- - MYSQL
- - POP3
- - POP3S
- - SMTP
- - TCP
- - TCP_CLIENT_FIRST
- - UDP
- - UDP_STREAM
- - SFTP
- default: HTTP
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- timeout:
- type: int
- description:
- - timeout for communication between the balancer and the node
- default: 30
- type:
- type: str
- description:
- - type of interface for the balancer being created
- choices:
- - PUBLIC
- - SERVICENET
- default: PUBLIC
- vip_id:
- type: str
- description:
- - Virtual IP ID to use when creating the load balancer for purposes of
- sharing an IP with another load balancer of another protocol
- wait:
- description:
- - wait for the balancer to be in state 'running' before returning
- type: bool
- default: false
- wait_timeout:
- type: int
- description:
- - how long before wait gives up, in seconds
- default: 300
-author:
- - "Christopher H. Laco (@claco)"
- - "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a Load Balancer
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Load Balancer create request
- local_action:
- module: rax_clb
- credentials: ~/.raxpub
- name: my-lb
- port: 8080
- protocol: HTTP
- type: SERVICENET
- timeout: 30
- region: DFW
- wait: true
- state: present
- meta:
- app: my-cool-app
- register: my_lb
-'''
-
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (CLB_ALGORITHMS,
- CLB_PROTOCOLS,
- rax_argument_spec,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
- vip_type, timeout, wait, wait_timeout, vip_id):
- if int(timeout) < 30:
- module.fail_json(msg='"timeout" must be greater than or equal to 30')
-
- changed = False
- balancers = []
-
- clb = pyrax.cloud_loadbalancers
- if not clb:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- balancer_list = clb.list()
- while balancer_list:
- retrieved = clb.list(marker=balancer_list.pop().id)
- balancer_list.extend(retrieved)
- if len(retrieved) < 2:
- break
-
- for balancer in balancer_list:
- if name != balancer.name and name != balancer.id:
- continue
-
- balancers.append(balancer)
-
- if len(balancers) > 1:
- module.fail_json(msg='Multiple Load Balancers were matched by name, '
- 'try using the Load Balancer ID instead')
-
- if state == 'present':
- if isinstance(meta, dict):
- metadata = [dict(key=k, value=v) for k, v in meta.items()]
-
- if not balancers:
- try:
- virtual_ips = [clb.VirtualIP(type=vip_type, id=vip_id)]
- balancer = clb.create(name, metadata=metadata, port=port,
- algorithm=algorithm, protocol=protocol,
- timeout=timeout, virtual_ips=virtual_ips)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- balancer = balancers[0]
- setattr(balancer, 'metadata',
- [dict(key=k, value=v) for k, v in
- balancer.get_metadata().items()])
- atts = {
- 'name': name,
- 'algorithm': algorithm,
- 'port': port,
- 'protocol': protocol,
- 'timeout': timeout
- }
- for att, value in atts.items():
- current = getattr(balancer, att)
- if current != value:
- changed = True
-
- if changed:
- balancer.update(**atts)
-
- if balancer.metadata != metadata:
- balancer.set_metadata(meta)
- changed = True
-
- virtual_ips = [clb.VirtualIP(type=vip_type)]
- current_vip_types = set([v.type for v in balancer.virtual_ips])
- vip_types = set([v.type for v in virtual_ips])
- if current_vip_types != vip_types:
- module.fail_json(msg='Load balancer Virtual IP type cannot '
- 'be changed')
-
- if wait:
- attempts = wait_timeout // 5
- pyrax.utils.wait_for_build(balancer, interval=5, attempts=attempts)
-
- balancer.get()
- instance = rax_to_dict(balancer, 'clb')
-
- result = dict(changed=changed, balancer=instance)
-
- if balancer.status == 'ERROR':
- result['msg'] = '%s failed to build' % balancer.id
- elif wait and balancer.status not in ('ACTIVE', 'ERROR'):
- result['msg'] = 'Timeout waiting on %s' % balancer.id
-
- if 'msg' in result:
- module.fail_json(**result)
- else:
- module.exit_json(**result)
-
- elif state == 'absent':
- if balancers:
- balancer = balancers[0]
- try:
- balancer.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- instance = rax_to_dict(balancer, 'clb')
-
- if wait:
- attempts = wait_timeout // 5
- pyrax.utils.wait_until(balancer, 'status', ('DELETED'),
- interval=5, attempts=attempts)
- else:
- instance = {}
-
- module.exit_json(changed=changed, balancer=instance)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- algorithm=dict(choices=CLB_ALGORITHMS,
- default='LEAST_CONNECTIONS'),
- meta=dict(type='dict', default={}),
- name=dict(required=True),
- port=dict(type='int', default=80),
- protocol=dict(choices=CLB_PROTOCOLS, default='HTTP'),
- state=dict(default='present', choices=['present', 'absent']),
- timeout=dict(type='int', default=30),
- type=dict(choices=['PUBLIC', 'SERVICENET'], default='PUBLIC'),
- vip_id=dict(),
- wait=dict(type='bool', default=False),
- wait_timeout=dict(type='int', default=300),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- algorithm = module.params.get('algorithm')
- meta = module.params.get('meta')
- name = module.params.get('name')
- port = module.params.get('port')
- protocol = module.params.get('protocol')
- state = module.params.get('state')
- timeout = int(module.params.get('timeout'))
- vip_id = module.params.get('vip_id')
- vip_type = module.params.get('type')
- wait = module.params.get('wait')
- wait_timeout = int(module.params.get('wait_timeout'))
-
- setup_rax_module(module, pyrax)
-
- cloud_load_balancer(module, state, name, meta, algorithm, port, protocol,
- vip_type, timeout, wait, wait_timeout, vip_id)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_clb_nodes.py b/ansible_collections/community/general/plugins/modules/rax_clb_nodes.py
deleted file mode 100644
index c076dced7..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_clb_nodes.py
+++ /dev/null
@@ -1,291 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_clb_nodes
-short_description: Add, modify and remove nodes from a Rackspace Cloud Load Balancer
-description:
- - Adds, modifies and removes nodes from a Rackspace Cloud Load Balancer
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- address:
- type: str
- required: false
- description:
- - IP address or domain name of the node
- condition:
- type: str
- required: false
- choices:
- - enabled
- - disabled
- - draining
- description:
- - Condition for the node, which determines its role within the load
- balancer
- load_balancer_id:
- type: int
- required: true
- description:
- - Load balancer id
- node_id:
- type: int
- required: false
- description:
- - Node id
- port:
- type: int
- required: false
- description:
- - Port number of the load balanced service on the node
- state:
- type: str
- required: false
- default: "present"
- choices:
- - present
- - absent
- description:
- - Indicate desired state of the node
- type:
- type: str
- required: false
- choices:
- - primary
- - secondary
- description:
- - Type of node
- wait:
- required: false
- default: false
- type: bool
- description:
- - Wait for the load balancer to become active before returning
- wait_timeout:
- type: int
- required: false
- default: 30
- description:
- - How long to wait before giving up and returning an error
- weight:
- type: int
- required: false
- description:
- - Weight of node
- virtualenv:
- type: path
- description:
- - Virtualenv to execute this module in
-author: "Lukasz Kawczynski (@neuroid)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Add a new node to the load balancer
- local_action:
- module: rax_clb_nodes
- load_balancer_id: 71
- address: 10.2.2.3
- port: 80
- condition: enabled
- type: primary
- wait: true
- credentials: /path/to/credentials
-
-- name: Drain connections from a node
- local_action:
- module: rax_clb_nodes
- load_balancer_id: 71
- node_id: 410
- condition: draining
- wait: true
- credentials: /path/to/credentials
-
-- name: Remove a node from the load balancer
- local_action:
- module: rax_clb_nodes
- load_balancer_id: 71
- node_id: 410
- state: absent
- wait: true
- credentials: /path/to/credentials
-'''
-
-import os
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_clb_node_to_dict, rax_required_together, setup_rax_module
-
-
-def _activate_virtualenv(path):
- activate_this = os.path.join(path, 'bin', 'activate_this.py')
- with open(activate_this) as f:
- code = compile(f.read(), activate_this, 'exec')
- exec(code)
-
-
-def _get_node(lb, node_id=None, address=None, port=None):
- """Return a matching node"""
- for node in getattr(lb, 'nodes', []):
- match_list = []
- if node_id is not None:
- match_list.append(getattr(node, 'id', None) == node_id)
- if address is not None:
- match_list.append(getattr(node, 'address', None) == address)
- if port is not None:
- match_list.append(getattr(node, 'port', None) == port)
-
- if match_list and all(match_list):
- return node
-
- return None
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- address=dict(),
- condition=dict(choices=['enabled', 'disabled', 'draining']),
- load_balancer_id=dict(required=True, type='int'),
- node_id=dict(type='int'),
- port=dict(type='int'),
- state=dict(default='present', choices=['present', 'absent']),
- type=dict(choices=['primary', 'secondary']),
- virtualenv=dict(type='path'),
- wait=dict(default=False, type='bool'),
- wait_timeout=dict(default=30, type='int'),
- weight=dict(type='int'),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- address = module.params['address']
- condition = (module.params['condition'] and
- module.params['condition'].upper())
- load_balancer_id = module.params['load_balancer_id']
- node_id = module.params['node_id']
- port = module.params['port']
- state = module.params['state']
- typ = module.params['type'] and module.params['type'].upper()
- virtualenv = module.params['virtualenv']
- wait = module.params['wait']
- wait_timeout = module.params['wait_timeout'] or 1
- weight = module.params['weight']
-
- if virtualenv:
- try:
- _activate_virtualenv(virtualenv)
- except IOError as e:
- module.fail_json(msg='Failed to activate virtualenv %s (%s)' % (
- virtualenv, e))
-
- setup_rax_module(module, pyrax)
-
- if not pyrax.cloud_loadbalancers:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- try:
- lb = pyrax.cloud_loadbalancers.get(load_balancer_id)
- except pyrax.exc.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
-
- node = _get_node(lb, node_id, address, port)
-
- result = rax_clb_node_to_dict(node)
-
- if state == 'absent':
- if not node: # Removing a non-existent node
- module.exit_json(changed=False, state=state)
- try:
- lb.delete_node(node)
- result = {}
- except pyrax.exc.NotFound:
- module.exit_json(changed=False, state=state)
- except pyrax.exc.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
- else: # present
- if not node:
- if node_id: # Updating a non-existent node
- msg = 'Node %d not found' % node_id
- if lb.nodes:
- msg += (' (available nodes: %s)' %
- ', '.join([str(x.id) for x in lb.nodes]))
- module.fail_json(msg=msg)
- else: # Creating a new node
- try:
- node = pyrax.cloudloadbalancers.Node(
- address=address, port=port, condition=condition,
- weight=weight, type=typ)
- resp, body = lb.add_nodes([node])
- result.update(body['nodes'][0])
- except pyrax.exc.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
- else: # Updating an existing node
- mutable = {
- 'condition': condition,
- 'type': typ,
- 'weight': weight,
- }
-
- for name in list(mutable):
- value = mutable[name]
- if value is None or value == getattr(node, name):
- mutable.pop(name)
-
- if not mutable:
- module.exit_json(changed=False, state=state, node=result)
-
- try:
- # The diff has to be set explicitly to update node's weight and
- # type; this should probably be fixed in pyrax
- lb.update_node(node, diff=mutable)
- result.update(mutable)
- except pyrax.exc.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
-
- if wait:
- pyrax.utils.wait_until(lb, "status", "ACTIVE", interval=1,
- attempts=wait_timeout)
- if lb.status != 'ACTIVE':
- module.fail_json(
- msg='Load balancer not active after %ds (current status: %s)' %
- (wait_timeout, lb.status.lower()))
-
- kwargs = {'node': result} if result else {}
- module.exit_json(changed=True, state=state, **kwargs)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_clb_ssl.py b/ansible_collections/community/general/plugins/modules/rax_clb_ssl.py
deleted file mode 100644
index b794130cf..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_clb_ssl.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
-module: rax_clb_ssl
-short_description: Manage SSL termination for a Rackspace Cloud Load Balancer
-description:
-- Set up, reconfigure, or remove SSL termination for an existing load balancer.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- loadbalancer:
- type: str
- description:
- - Name or ID of the load balancer on which to manage SSL termination.
- required: true
- state:
- type: str
- description:
- - If set to "present", SSL termination will be added to this load balancer.
- - If "absent", SSL termination will be removed instead.
- choices:
- - present
- - absent
- default: present
- enabled:
- description:
- - If set to "false", temporarily disable SSL termination without discarding
- - existing credentials.
- default: true
- type: bool
- private_key:
- type: str
- description:
- - The private SSL key as a string in PEM format.
- certificate:
- type: str
- description:
- - The public SSL certificates as a string in PEM format.
- intermediate_certificate:
- type: str
- description:
- - One or more intermediate certificate authorities as a string in PEM
- - format, concatenated into a single string.
- secure_port:
- type: int
- description:
- - The port to listen for secure traffic.
- default: 443
- secure_traffic_only:
- description:
- - If "true", the load balancer will *only* accept secure traffic.
- default: false
- type: bool
- https_redirect:
- description:
- - If "true", the load balancer will redirect HTTP traffic to HTTPS.
- - Requires "secure_traffic_only" to be true. Incurs an implicit wait if SSL
- - termination is also applied or removed.
- type: bool
- wait:
- description:
- - Wait for the balancer to be in state "running" before turning.
- default: false
- type: bool
- wait_timeout:
- type: int
- description:
- - How long before "wait" gives up, in seconds.
- default: 300
-author: Ash Wilson (@smashwilson)
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Enable SSL termination on a load balancer
- community.general.rax_clb_ssl:
- loadbalancer: the_loadbalancer
- state: present
- private_key: "{{ lookup('file', 'credentials/server.key' ) }}"
- certificate: "{{ lookup('file', 'credentials/server.crt' ) }}"
- intermediate_certificate: "{{ lookup('file', 'credentials/trust-chain.crt') }}"
- secure_traffic_only: true
- wait: true
-
-- name: Disable SSL termination
- community.general.rax_clb_ssl:
- loadbalancer: "{{ registered_lb.balancer.id }}"
- state: absent
- wait: true
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec,
- rax_find_loadbalancer,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def cloud_load_balancer_ssl(module, loadbalancer, state, enabled, private_key,
- certificate, intermediate_certificate, secure_port,
- secure_traffic_only, https_redirect,
- wait, wait_timeout):
- # Validate arguments.
-
- if state == 'present':
- if not private_key:
- module.fail_json(msg="private_key must be provided.")
- else:
- private_key = private_key.strip()
-
- if not certificate:
- module.fail_json(msg="certificate must be provided.")
- else:
- certificate = certificate.strip()
-
- attempts = wait_timeout // 5
-
- # Locate the load balancer.
-
- balancer = rax_find_loadbalancer(module, pyrax, loadbalancer)
- existing_ssl = balancer.get_ssl_termination()
-
- changed = False
-
- if state == 'present':
- # Apply or reconfigure SSL termination on the load balancer.
- ssl_attrs = dict(
- securePort=secure_port,
- privatekey=private_key,
- certificate=certificate,
- intermediateCertificate=intermediate_certificate,
- enabled=enabled,
- secureTrafficOnly=secure_traffic_only
- )
-
- needs_change = False
-
- if existing_ssl:
- for ssl_attr, value in ssl_attrs.items():
- if ssl_attr == 'privatekey':
- # The private key is not included in get_ssl_termination's
- # output (as it shouldn't be). Also, if you're changing the
- # private key, you'll also be changing the certificate,
- # so we don't lose anything by not checking it.
- continue
-
- if value is not None and existing_ssl.get(ssl_attr) != value:
- # module.fail_json(msg='Unnecessary change', attr=ssl_attr, value=value, existing=existing_ssl.get(ssl_attr))
- needs_change = True
- else:
- needs_change = True
-
- if needs_change:
- try:
- balancer.add_ssl_termination(**ssl_attrs)
- except pyrax.exceptions.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
- changed = True
- elif state == 'absent':
- # Remove SSL termination if it's already configured.
- if existing_ssl:
- try:
- balancer.delete_ssl_termination()
- except pyrax.exceptions.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
- changed = True
-
- if https_redirect is not None and balancer.httpsRedirect != https_redirect:
- if changed:
- # This wait is unavoidable because load balancers are immutable
- # while the SSL termination changes above are being applied.
- pyrax.utils.wait_for_build(balancer, interval=5, attempts=attempts)
-
- try:
- balancer.update(httpsRedirect=https_redirect)
- except pyrax.exceptions.PyraxException as e:
- module.fail_json(msg='%s' % e.message)
- changed = True
-
- if changed and wait:
- pyrax.utils.wait_for_build(balancer, interval=5, attempts=attempts)
-
- balancer.get()
- new_ssl_termination = balancer.get_ssl_termination()
-
- # Intentionally omit the private key from the module output, so you don't
- # accidentally echo it with `ansible-playbook -v` or `debug`, and the
- # certificate, which is just long. Convert other attributes to snake_case
- # and include https_redirect at the top-level.
- if new_ssl_termination:
- new_ssl = dict(
- enabled=new_ssl_termination['enabled'],
- secure_port=new_ssl_termination['securePort'],
- secure_traffic_only=new_ssl_termination['secureTrafficOnly']
- )
- else:
- new_ssl = None
-
- result = dict(
- changed=changed,
- https_redirect=balancer.httpsRedirect,
- ssl_termination=new_ssl,
- balancer=rax_to_dict(balancer, 'clb')
- )
- success = True
-
- if balancer.status == 'ERROR':
- result['msg'] = '%s failed to build' % balancer.id
- success = False
- elif wait and balancer.status not in ('ACTIVE', 'ERROR'):
- result['msg'] = 'Timeout waiting on %s' % balancer.id
- success = False
-
- if success:
- module.exit_json(**result)
- else:
- module.fail_json(**result)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(dict(
- loadbalancer=dict(required=True),
- state=dict(default='present', choices=['present', 'absent']),
- enabled=dict(type='bool', default=True),
- private_key=dict(no_log=True),
- certificate=dict(),
- intermediate_certificate=dict(),
- secure_port=dict(type='int', default=443),
- secure_traffic_only=dict(type='bool', default=False),
- https_redirect=dict(type='bool'),
- wait=dict(type='bool', default=False),
- wait_timeout=dict(type='int', default=300)
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module.')
-
- loadbalancer = module.params.get('loadbalancer')
- state = module.params.get('state')
- enabled = module.boolean(module.params.get('enabled'))
- private_key = module.params.get('private_key')
- certificate = module.params.get('certificate')
- intermediate_certificate = module.params.get('intermediate_certificate')
- secure_port = module.params.get('secure_port')
- secure_traffic_only = module.boolean(module.params.get('secure_traffic_only'))
- https_redirect = module.boolean(module.params.get('https_redirect'))
- wait = module.boolean(module.params.get('wait'))
- wait_timeout = module.params.get('wait_timeout')
-
- setup_rax_module(module, pyrax)
-
- cloud_load_balancer_ssl(
- module, loadbalancer, state, enabled, private_key, certificate,
- intermediate_certificate, secure_port, secure_traffic_only,
- https_redirect, wait, wait_timeout
- )
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_dns.py b/ansible_collections/community/general/plugins/modules/rax_dns.py
deleted file mode 100644
index 31782cd88..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_dns.py
+++ /dev/null
@@ -1,180 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_dns
-short_description: Manage domains on Rackspace Cloud DNS
-description:
- - Manage domains on Rackspace Cloud DNS
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- comment:
- type: str
- description:
- - Brief description of the domain. Maximum length of 160 characters
- email:
- type: str
- description:
- - Email address of the domain administrator
- name:
- type: str
- description:
- - Domain name to create
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- ttl:
- type: int
- description:
- - Time to live of domain in seconds
- default: 3600
-notes:
- - "It is recommended that plays utilizing this module be run with
- C(serial: 1) to avoid exceeding the API request limit imposed by
- the Rackspace CloudDNS API"
-author: "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Create domain
- hosts: all
- gather_facts: false
- tasks:
- - name: Domain create request
- local_action:
- module: rax_dns
- credentials: ~/.raxpub
- name: example.org
- email: admin@example.org
- register: rax_dns
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def rax_dns(module, comment, email, name, state, ttl):
- changed = False
-
- dns = pyrax.cloud_dns
- if not dns:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if state == 'present':
- if not email:
- module.fail_json(msg='An "email" attribute is required for '
- 'creating a domain')
-
- try:
- domain = dns.find(name=name)
- except pyrax.exceptions.NoUniqueMatch as e:
- module.fail_json(msg='%s' % e.message)
- except pyrax.exceptions.NotFound:
- try:
- domain = dns.create(name=name, emailAddress=email, ttl=ttl,
- comment=comment)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- update = {}
- if comment != getattr(domain, 'comment', None):
- update['comment'] = comment
- if ttl != getattr(domain, 'ttl', None):
- update['ttl'] = ttl
- if email != getattr(domain, 'emailAddress', None):
- update['emailAddress'] = email
-
- if update:
- try:
- domain.update(**update)
- changed = True
- domain.get()
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- elif state == 'absent':
- try:
- domain = dns.find(name=name)
- except pyrax.exceptions.NotFound:
- domain = {}
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- if domain:
- try:
- domain.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, domain=rax_to_dict(domain))
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- comment=dict(),
- email=dict(),
- name=dict(),
- state=dict(default='present', choices=['present', 'absent']),
- ttl=dict(type='int', default=3600),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- comment = module.params.get('comment')
- email = module.params.get('email')
- name = module.params.get('name')
- state = module.params.get('state')
- ttl = module.params.get('ttl')
-
- setup_rax_module(module, pyrax, False)
-
- rax_dns(module, comment, email, name, state, ttl)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_dns_record.py b/ansible_collections/community/general/plugins/modules/rax_dns_record.py
deleted file mode 100644
index cb3cd279e..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_dns_record.py
+++ /dev/null
@@ -1,358 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_dns_record
-short_description: Manage DNS records on Rackspace Cloud DNS
-description:
- - Manage DNS records on Rackspace Cloud DNS
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- comment:
- type: str
- description:
- - Brief description of the domain. Maximum length of 160 characters
- data:
- type: str
- description:
- - IP address for A/AAAA record, FQDN for CNAME/MX/NS, or text data for
- SRV/TXT
- required: true
- domain:
- type: str
- description:
- - Domain name to create the record in. This is an invalid option when
- type=PTR
- loadbalancer:
- type: str
- description:
- - Load Balancer ID to create a PTR record for. Only used with type=PTR
- name:
- type: str
- description:
- - FQDN record name to create
- required: true
- overwrite:
- description:
- - Add new records if data doesn't match, instead of updating existing
- record with matching name. If there are already multiple records with
- matching name and overwrite=true, this module will fail.
- default: true
- type: bool
- priority:
- type: int
- description:
- - Required for MX and SRV records, but forbidden for other record types.
- If specified, must be an integer from 0 to 65535.
- server:
- type: str
- description:
- - Server ID to create a PTR record for. Only used with type=PTR
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- ttl:
- type: int
- description:
- - Time to live of record in seconds
- default: 3600
- type:
- type: str
- description:
- - DNS record type
- choices:
- - A
- - AAAA
- - CNAME
- - MX
- - NS
- - SRV
- - TXT
- - PTR
- required: true
-notes:
- - "It is recommended that plays utilizing this module be run with
- C(serial: 1) to avoid exceeding the API request limit imposed by
- the Rackspace CloudDNS API."
- - To manipulate a C(PTR) record either C(loadbalancer) or C(server) must be
- supplied.
-author: "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Create DNS Records
- hosts: all
- gather_facts: false
- tasks:
- - name: Create A record
- local_action:
- module: rax_dns_record
- credentials: ~/.raxpub
- domain: example.org
- name: www.example.org
- data: "{{ rax_accessipv4 }}"
- type: A
- register: a_record
-
- - name: Create PTR record
- local_action:
- module: rax_dns_record
- credentials: ~/.raxpub
- server: "{{ rax_id }}"
- name: "{{ inventory_hostname }}"
- region: DFW
- register: ptr_record
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec,
- rax_find_loadbalancer,
- rax_find_server,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def rax_dns_record_ptr(module, data=None, comment=None, loadbalancer=None,
- name=None, server=None, state='present', ttl=7200):
- changed = False
- results = []
-
- dns = pyrax.cloud_dns
-
- if not dns:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if loadbalancer:
- item = rax_find_loadbalancer(module, pyrax, loadbalancer)
- elif server:
- item = rax_find_server(module, pyrax, server)
-
- if state == 'present':
- current = dns.list_ptr_records(item)
- for record in current:
- if record.data == data:
- if record.ttl != ttl or record.name != name:
- try:
- dns.update_ptr_record(item, record, name, data, ttl)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- record.ttl = ttl
- record.name = name
- results.append(rax_to_dict(record))
- break
- else:
- results.append(rax_to_dict(record))
- break
-
- if not results:
- record = dict(name=name, type='PTR', data=data, ttl=ttl,
- comment=comment)
- try:
- results = dns.add_ptr_records(item, [record])
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, records=results)
-
- elif state == 'absent':
- current = dns.list_ptr_records(item)
- for record in current:
- if record.data == data:
- results.append(rax_to_dict(record))
- break
-
- if results:
- try:
- dns.delete_ptr_records(item, data)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, records=results)
-
-
-def rax_dns_record(module, comment=None, data=None, domain=None, name=None,
- overwrite=True, priority=None, record_type='A',
- state='present', ttl=7200):
- """Function for manipulating record types other than PTR"""
-
- changed = False
-
- dns = pyrax.cloud_dns
- if not dns:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if state == 'present':
- if not priority and record_type in ['MX', 'SRV']:
- module.fail_json(msg='A "priority" attribute is required for '
- 'creating a MX or SRV record')
-
- try:
- domain = dns.find(name=domain)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- try:
- if overwrite:
- record = domain.find_record(record_type, name=name)
- else:
- record = domain.find_record(record_type, name=name, data=data)
- except pyrax.exceptions.DomainRecordNotUnique as e:
- module.fail_json(msg='overwrite=true and there are multiple matching records')
- except pyrax.exceptions.DomainRecordNotFound as e:
- try:
- record_data = {
- 'type': record_type,
- 'name': name,
- 'data': data,
- 'ttl': ttl
- }
- if comment:
- record_data.update(dict(comment=comment))
- if priority and record_type.upper() in ['MX', 'SRV']:
- record_data.update(dict(priority=priority))
-
- record = domain.add_records([record_data])[0]
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- update = {}
- if comment != getattr(record, 'comment', None):
- update['comment'] = comment
- if ttl != getattr(record, 'ttl', None):
- update['ttl'] = ttl
- if priority != getattr(record, 'priority', None):
- update['priority'] = priority
- if data != getattr(record, 'data', None):
- update['data'] = data
-
- if update:
- try:
- record.update(**update)
- changed = True
- record.get()
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- elif state == 'absent':
- try:
- domain = dns.find(name=domain)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- try:
- record = domain.find_record(record_type, name=name, data=data)
- except pyrax.exceptions.DomainRecordNotFound as e:
- record = {}
- except pyrax.exceptions.DomainRecordNotUnique as e:
- module.fail_json(msg='%s' % e.message)
-
- if record:
- try:
- record.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, record=rax_to_dict(record))
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- comment=dict(),
- data=dict(required=True),
- domain=dict(),
- loadbalancer=dict(),
- name=dict(required=True),
- overwrite=dict(type='bool', default=True),
- priority=dict(type='int'),
- server=dict(),
- state=dict(default='present', choices=['present', 'absent']),
- ttl=dict(type='int', default=3600),
- type=dict(required=True, choices=['A', 'AAAA', 'CNAME', 'MX', 'NS',
- 'SRV', 'TXT', 'PTR'])
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- mutually_exclusive=[
- ['server', 'loadbalancer', 'domain'],
- ],
- required_one_of=[
- ['server', 'loadbalancer', 'domain'],
- ],
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- comment = module.params.get('comment')
- data = module.params.get('data')
- domain = module.params.get('domain')
- loadbalancer = module.params.get('loadbalancer')
- name = module.params.get('name')
- overwrite = module.params.get('overwrite')
- priority = module.params.get('priority')
- server = module.params.get('server')
- state = module.params.get('state')
- ttl = module.params.get('ttl')
- record_type = module.params.get('type')
-
- setup_rax_module(module, pyrax, False)
-
- if record_type.upper() == 'PTR':
- if not server and not loadbalancer:
- module.fail_json(msg='one of the following is required: '
- 'server,loadbalancer')
- rax_dns_record_ptr(module, data=data, comment=comment,
- loadbalancer=loadbalancer, name=name, server=server,
- state=state, ttl=ttl)
- else:
- rax_dns_record(module, comment=comment, data=data, domain=domain,
- name=name, overwrite=overwrite, priority=priority,
- record_type=record_type, state=state, ttl=ttl)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_facts.py b/ansible_collections/community/general/plugins/modules/rax_facts.py
deleted file mode 100644
index f8bb0e050..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_facts.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_facts
-short_description: Gather facts for Rackspace Cloud Servers
-description:
- - Gather facts for Rackspace Cloud Servers.
-attributes:
- check_mode:
- version_added: 3.3.0
- # This was backported to 2.5.4 and 1.3.11 as well, since this was a bugfix
-options:
- address:
- type: str
- description:
- - Server IP address to retrieve facts for, will match any IP assigned to
- the server
- id:
- type: str
- description:
- - Server ID to retrieve facts for
- name:
- type: str
- description:
- - Server name to retrieve facts for
-author: "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
- - community.general.attributes.facts
- - community.general.attributes.facts_module
-
-'''
-
-EXAMPLES = '''
-- name: Gather info about servers
- hosts: all
- gather_facts: false
- tasks:
- - name: Get facts about servers
- local_action:
- module: rax_facts
- credentials: ~/.raxpub
- name: "{{ inventory_hostname }}"
- region: DFW
- - name: Map some facts
- ansible.builtin.set_fact:
- ansible_ssh_host: "{{ rax_accessipv4 }}"
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def rax_facts(module, address, name, server_id):
- changed = False
-
- cs = pyrax.cloudservers
-
- if cs is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- ansible_facts = {}
-
- search_opts = {}
- if name:
- search_opts = dict(name='^%s$' % name)
- try:
- servers = cs.servers.list(search_opts=search_opts)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- elif address:
- servers = []
- try:
- for server in cs.servers.list():
- for addresses in server.networks.values():
- if address in addresses:
- servers.append(server)
- break
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- elif server_id:
- servers = []
- try:
- servers.append(cs.servers.get(server_id))
- except Exception as e:
- pass
-
- servers[:] = [server for server in servers if server.status != "DELETED"]
-
- if len(servers) > 1:
- module.fail_json(msg='Multiple servers found matching provided '
- 'search parameters')
- elif len(servers) == 1:
- ansible_facts = rax_to_dict(servers[0], 'server')
-
- module.exit_json(changed=changed, ansible_facts=ansible_facts)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- address=dict(),
- id=dict(),
- name=dict(),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- mutually_exclusive=[['address', 'id', 'name']],
- required_one_of=[['address', 'id', 'name']],
- supports_check_mode=True,
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- address = module.params.get('address')
- server_id = module.params.get('id')
- name = module.params.get('name')
-
- setup_rax_module(module, pyrax)
-
- rax_facts(module, address, name, server_id)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_files.py b/ansible_collections/community/general/plugins/modules/rax_files.py
deleted file mode 100644
index a63e107eb..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_files.py
+++ /dev/null
@@ -1,400 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright (c) 2013, Paul Durivage <paul.durivage@rackspace.com>
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_files
-short_description: Manipulate Rackspace Cloud Files Containers
-description:
- - Manipulate Rackspace Cloud Files Containers
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- clear_meta:
- description:
- - Optionally clear existing metadata when applying metadata to existing containers.
- Selecting this option is only appropriate when setting type=meta
- type: bool
- default: false
- container:
- type: str
- description:
- - The container to use for container or metadata operations.
- meta:
- type: dict
- default: {}
- description:
- - A hash of items to set as metadata values on a container
- private:
- description:
- - Used to set a container as private, removing it from the CDN. B(Warning!)
- Private containers, if previously made public, can have live objects
- available until the TTL on cached objects expires
- type: bool
- default: false
- public:
- description:
- - Used to set a container as public, available via the Cloud Files CDN
- type: bool
- default: false
- region:
- type: str
- description:
- - Region to create an instance in
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices: ['present', 'absent', 'list']
- default: present
- ttl:
- type: int
- description:
- - In seconds, set a container-wide TTL for all objects cached on CDN edge nodes.
- Setting a TTL is only appropriate for containers that are public
- type:
- type: str
- description:
- - Type of object to do work on, i.e. metadata object or a container object
- choices:
- - container
- - meta
- default: container
- web_error:
- type: str
- description:
- - Sets an object to be presented as the HTTP error page when accessed by the CDN URL
- web_index:
- type: str
- description:
- - Sets an object to be presented as the HTTP index page when accessed by the CDN URL
-author: "Paul Durivage (@angstwad)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: "Test Cloud Files Containers"
- hosts: local
- gather_facts: false
- tasks:
- - name: "List all containers"
- community.general.rax_files:
- state: list
-
- - name: "Create container called 'mycontainer'"
- community.general.rax_files:
- container: mycontainer
-
- - name: "Create container 'mycontainer2' with metadata"
- community.general.rax_files:
- container: mycontainer2
- meta:
- key: value
- file_for: someuser@example.com
-
- - name: "Set a container's web index page"
- community.general.rax_files:
- container: mycontainer
- web_index: index.html
-
- - name: "Set a container's web error page"
- community.general.rax_files:
- container: mycontainer
- web_error: error.html
-
- - name: "Make container public"
- community.general.rax_files:
- container: mycontainer
- public: true
-
- - name: "Make container public with a 24 hour TTL"
- community.general.rax_files:
- container: mycontainer
- public: true
- ttl: 86400
-
- - name: "Make container private"
- community.general.rax_files:
- container: mycontainer
- private: true
-
-- name: "Test Cloud Files Containers Metadata Storage"
- hosts: local
- gather_facts: false
- tasks:
- - name: "Get mycontainer2 metadata"
- community.general.rax_files:
- container: mycontainer2
- type: meta
-
- - name: "Set mycontainer2 metadata"
- community.general.rax_files:
- container: mycontainer2
- type: meta
- meta:
- uploaded_by: someuser@example.com
-
- - name: "Remove mycontainer2 metadata"
- community.general.rax_files:
- container: "mycontainer2"
- type: meta
- state: absent
- meta:
- key: ""
- file_for: ""
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError as e:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-EXIT_DICT = dict(success=True)
-META_PREFIX = 'x-container-meta-'
-
-
-def _get_container(module, cf, container):
- try:
- return cf.get_container(container)
- except pyrax.exc.NoSuchContainer as e:
- module.fail_json(msg=e.message)
-
-
-def _fetch_meta(module, container):
- EXIT_DICT['meta'] = dict()
- try:
- for k, v in container.get_metadata().items():
- split_key = k.split(META_PREFIX)[-1]
- EXIT_DICT['meta'][split_key] = v
- except Exception as e:
- module.fail_json(msg=e.message)
-
-
-def meta(cf, module, container_, state, meta_, clear_meta):
- c = _get_container(module, cf, container_)
-
- if meta_ and state == 'present':
- try:
- meta_set = c.set_metadata(meta_, clear=clear_meta)
- except Exception as e:
- module.fail_json(msg=e.message)
- elif meta_ and state == 'absent':
- remove_results = []
- for k, v in meta_.items():
- c.remove_metadata_key(k)
- remove_results.append(k)
- EXIT_DICT['deleted_meta_keys'] = remove_results
- elif state == 'absent':
- remove_results = []
- for k, v in c.get_metadata().items():
- c.remove_metadata_key(k)
- remove_results.append(k)
- EXIT_DICT['deleted_meta_keys'] = remove_results
-
- _fetch_meta(module, c)
- _locals = locals().keys()
-
- EXIT_DICT['container'] = c.name
- if 'meta_set' in _locals or 'remove_results' in _locals:
- EXIT_DICT['changed'] = True
-
- module.exit_json(**EXIT_DICT)
-
-
-def container(cf, module, container_, state, meta_, clear_meta, ttl, public,
- private, web_index, web_error):
- if public and private:
- module.fail_json(msg='container cannot be simultaneously '
- 'set to public and private')
-
- if state == 'absent' and (meta_ or clear_meta or public or private or web_index or web_error):
- module.fail_json(msg='state cannot be omitted when setting/removing '
- 'attributes on a container')
-
- if state == 'list':
- # We don't care if attributes are specified, let's list containers
- EXIT_DICT['containers'] = cf.list_containers()
- module.exit_json(**EXIT_DICT)
-
- try:
- c = cf.get_container(container_)
- except pyrax.exc.NoSuchContainer as e:
- # Make the container if state=present, otherwise bomb out
- if state == 'present':
- try:
- c = cf.create_container(container_)
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['changed'] = True
- EXIT_DICT['created'] = True
- else:
- module.fail_json(msg=e.message)
- else:
- # Successfully grabbed a container object
- # Delete if state is absent
- if state == 'absent':
- try:
- cont_deleted = c.delete()
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['deleted'] = True
-
- if meta_:
- try:
- meta_set = c.set_metadata(meta_, clear=clear_meta)
- except Exception as e:
- module.fail_json(msg=e.message)
- finally:
- _fetch_meta(module, c)
-
- if ttl:
- try:
- c.cdn_ttl = ttl
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['ttl'] = c.cdn_ttl
-
- if public:
- try:
- cont_public = c.make_public()
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['container_urls'] = dict(url=c.cdn_uri,
- ssl_url=c.cdn_ssl_uri,
- streaming_url=c.cdn_streaming_uri,
- ios_uri=c.cdn_ios_uri)
-
- if private:
- try:
- cont_private = c.make_private()
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['set_private'] = True
-
- if web_index:
- try:
- cont_web_index = c.set_web_index_page(web_index)
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['set_index'] = True
- finally:
- _fetch_meta(module, c)
-
- if web_error:
- try:
- cont_err_index = c.set_web_error_page(web_error)
- except Exception as e:
- module.fail_json(msg=e.message)
- else:
- EXIT_DICT['set_error'] = True
- finally:
- _fetch_meta(module, c)
-
- EXIT_DICT['container'] = c.name
- EXIT_DICT['objs_in_container'] = c.object_count
- EXIT_DICT['total_bytes'] = c.total_bytes
-
- _locals = locals().keys()
- if ('cont_deleted' in _locals
- or 'meta_set' in _locals
- or 'cont_public' in _locals
- or 'cont_private' in _locals
- or 'cont_web_index' in _locals
- or 'cont_err_index' in _locals):
- EXIT_DICT['changed'] = True
-
- module.exit_json(**EXIT_DICT)
-
-
-def cloudfiles(module, container_, state, meta_, clear_meta, typ, ttl, public,
- private, web_index, web_error):
- """ Dispatch from here to work with metadata or file objects """
- cf = pyrax.cloudfiles
-
- if cf is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if typ == "container":
- container(cf, module, container_, state, meta_, clear_meta, ttl,
- public, private, web_index, web_error)
- else:
- meta(cf, module, container_, state, meta_, clear_meta)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- container=dict(),
- state=dict(choices=['present', 'absent', 'list'],
- default='present'),
- meta=dict(type='dict', default=dict()),
- clear_meta=dict(default=False, type='bool'),
- type=dict(choices=['container', 'meta'], default='container'),
- ttl=dict(type='int'),
- public=dict(default=False, type='bool'),
- private=dict(default=False, type='bool'),
- web_index=dict(),
- web_error=dict()
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- container_ = module.params.get('container')
- state = module.params.get('state')
- meta_ = module.params.get('meta')
- clear_meta = module.params.get('clear_meta')
- typ = module.params.get('type')
- ttl = module.params.get('ttl')
- public = module.params.get('public')
- private = module.params.get('private')
- web_index = module.params.get('web_index')
- web_error = module.params.get('web_error')
-
- if state in ['present', 'absent'] and not container_:
- module.fail_json(msg='please specify a container name')
- if clear_meta and not typ == 'meta':
- module.fail_json(msg='clear_meta can only be used when setting '
- 'metadata')
-
- setup_rax_module(module, pyrax)
- cloudfiles(module, container_, state, meta_, clear_meta, typ, ttl, public,
- private, web_index, web_error)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_files_objects.py b/ansible_collections/community/general/plugins/modules/rax_files_objects.py
deleted file mode 100644
index bbcdfe4f8..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_files_objects.py
+++ /dev/null
@@ -1,556 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright (c) 2013, Paul Durivage <paul.durivage@rackspace.com>
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_files_objects
-short_description: Upload, download, and delete objects in Rackspace Cloud Files
-description:
- - Upload, download, and delete objects in Rackspace Cloud Files.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- clear_meta:
- description:
- - Optionally clear existing metadata when applying metadata to existing objects.
- Selecting this option is only appropriate when setting O(type=meta).
- type: bool
- default: false
- container:
- type: str
- description:
- - The container to use for file object operations.
- required: true
- dest:
- type: str
- description:
- - The destination of a C(get) operation; i.e. a local directory, C(/home/user/myfolder).
- Used to specify the destination of an operation on a remote object; i.e. a file name,
- V(file1), or a comma-separated list of remote objects, V(file1,file2,file17).
- expires:
- type: int
- description:
- - Used to set an expiration in seconds on an uploaded file or folder.
- meta:
- type: dict
- default: {}
- description:
- - Items to set as metadata values on an uploaded file or folder.
- method:
- type: str
- description:
- - >
- The method of operation to be performed: V(put) to upload files, V(get) to download files or
- V(delete) to remove remote objects in Cloud Files.
- choices:
- - get
- - put
- - delete
- default: get
- src:
- type: str
- description:
- - Source from which to upload files. Used to specify a remote object as a source for
- an operation, i.e. a file name, V(file1), or a comma-separated list of remote objects,
- V(file1,file2,file17). Parameters O(src) and O(dest) are mutually exclusive on remote-only object operations
- structure:
- description:
- - Used to specify whether to maintain nested directory structure when downloading objects
- from Cloud Files. Setting to false downloads the contents of a container to a single,
- flat directory
- type: bool
- default: true
- type:
- type: str
- description:
- - Type of object to do work on
- - Metadata object or a file object
- choices:
- - file
- - meta
- default: file
-author: "Paul Durivage (@angstwad)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: "Test Cloud Files Objects"
- hosts: local
- gather_facts: false
- tasks:
- - name: "Get objects from test container"
- community.general.rax_files_objects:
- container: testcont
- dest: ~/Downloads/testcont
-
- - name: "Get single object from test container"
- community.general.rax_files_objects:
- container: testcont
- src: file1
- dest: ~/Downloads/testcont
-
- - name: "Get several objects from test container"
- community.general.rax_files_objects:
- container: testcont
- src: file1,file2,file3
- dest: ~/Downloads/testcont
-
- - name: "Delete one object in test container"
- community.general.rax_files_objects:
- container: testcont
- method: delete
- dest: file1
-
- - name: "Delete several objects in test container"
- community.general.rax_files_objects:
- container: testcont
- method: delete
- dest: file2,file3,file4
-
- - name: "Delete all objects in test container"
- community.general.rax_files_objects:
- container: testcont
- method: delete
-
- - name: "Upload all files to test container"
- community.general.rax_files_objects:
- container: testcont
- method: put
- src: ~/Downloads/onehundred
-
- - name: "Upload one file to test container"
- community.general.rax_files_objects:
- container: testcont
- method: put
- src: ~/Downloads/testcont/file1
-
- - name: "Upload one file to test container with metadata"
- community.general.rax_files_objects:
- container: testcont
- src: ~/Downloads/testcont/file2
- method: put
- meta:
- testkey: testdata
- who_uploaded_this: someuser@example.com
-
- - name: "Upload one file to test container with TTL of 60 seconds"
- community.general.rax_files_objects:
- container: testcont
- method: put
- src: ~/Downloads/testcont/file3
- expires: 60
-
- - name: "Attempt to get remote object that does not exist"
- community.general.rax_files_objects:
- container: testcont
- method: get
- src: FileThatDoesNotExist.jpg
- dest: ~/Downloads/testcont
- ignore_errors: true
-
- - name: "Attempt to delete remote object that does not exist"
- community.general.rax_files_objects:
- container: testcont
- method: delete
- dest: FileThatDoesNotExist.jpg
- ignore_errors: true
-
-- name: "Test Cloud Files Objects Metadata"
- hosts: local
- gather_facts: false
- tasks:
- - name: "Get metadata on one object"
- community.general.rax_files_objects:
- container: testcont
- type: meta
- dest: file2
-
- - name: "Get metadata on several objects"
- community.general.rax_files_objects:
- container: testcont
- type: meta
- src: file2,file1
-
- - name: "Set metadata on an object"
- community.general.rax_files_objects:
- container: testcont
- type: meta
- dest: file17
- method: put
- meta:
- key1: value1
- key2: value2
- clear_meta: true
-
- - name: "Verify metadata is set"
- community.general.rax_files_objects:
- container: testcont
- type: meta
- src: file17
-
- - name: "Delete metadata"
- community.general.rax_files_objects:
- container: testcont
- type: meta
- dest: file17
- method: delete
- meta:
- key1: ''
- key2: ''
-
- - name: "Get metadata on all objects"
- community.general.rax_files_objects:
- container: testcont
- type: meta
-'''
-
-import os
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-EXIT_DICT = dict(success=False)
-META_PREFIX = 'x-object-meta-'
-
-
-def _get_container(module, cf, container):
- try:
- return cf.get_container(container)
- except pyrax.exc.NoSuchContainer as e:
- module.fail_json(msg=e.message)
-
-
-def _upload_folder(cf, folder, container, ttl=None, headers=None):
- """ Uploads a folder to Cloud Files.
- """
- total_bytes = 0
- for root, dummy, files in os.walk(folder):
- for fname in files:
- full_path = os.path.join(root, fname)
- obj_name = os.path.relpath(full_path, folder)
- obj_size = os.path.getsize(full_path)
- cf.upload_file(container, full_path, obj_name=obj_name, return_none=True, ttl=ttl, headers=headers)
- total_bytes += obj_size
- return total_bytes
-
-
-def upload(module, cf, container, src, dest, meta, expires):
- """ Uploads a single object or a folder to Cloud Files Optionally sets an
- metadata, TTL value (expires), or Content-Disposition and Content-Encoding
- headers.
- """
- if not src:
- module.fail_json(msg='src must be specified when uploading')
-
- c = _get_container(module, cf, container)
- src = os.path.abspath(os.path.expanduser(src))
- is_dir = os.path.isdir(src)
-
- if not is_dir and not os.path.isfile(src) or not os.path.exists(src):
- module.fail_json(msg='src must be a file or a directory')
- if dest and is_dir:
- module.fail_json(msg='dest cannot be set when whole '
- 'directories are uploaded')
-
- cont_obj = None
- total_bytes = 0
- try:
- if dest and not is_dir:
- cont_obj = c.upload_file(src, obj_name=dest, ttl=expires, headers=meta)
- elif is_dir:
- total_bytes = _upload_folder(cf, src, c, ttl=expires, headers=meta)
- else:
- cont_obj = c.upload_file(src, ttl=expires, headers=meta)
- except Exception as e:
- module.fail_json(msg=e.message)
-
- EXIT_DICT['success'] = True
- EXIT_DICT['container'] = c.name
- EXIT_DICT['msg'] = "Uploaded %s to container: %s" % (src, c.name)
- if cont_obj or total_bytes > 0:
- EXIT_DICT['changed'] = True
- if meta:
- EXIT_DICT['meta'] = dict(updated=True)
-
- if cont_obj:
- EXIT_DICT['bytes'] = cont_obj.total_bytes
- EXIT_DICT['etag'] = cont_obj.etag
- else:
- EXIT_DICT['bytes'] = total_bytes
-
- module.exit_json(**EXIT_DICT)
-
-
-def download(module, cf, container, src, dest, structure):
- """ Download objects from Cloud Files to a local path specified by "dest".
- Optionally disable maintaining a directory structure by by passing a
- false value to "structure".
- """
- # Looking for an explicit destination
- if not dest:
- module.fail_json(msg='dest is a required argument when '
- 'downloading from Cloud Files')
-
- # Attempt to fetch the container by name
- c = _get_container(module, cf, container)
-
- # Accept a single object name or a comma-separated list of objs
- # If not specified, get the entire container
- if src:
- objs = map(str.strip, src.split(','))
- else:
- objs = c.get_object_names()
-
- dest = os.path.abspath(os.path.expanduser(dest))
- is_dir = os.path.isdir(dest)
-
- if not is_dir:
- module.fail_json(msg='dest must be a directory')
-
- try:
- results = [c.download_object(obj, dest, structure=structure) for obj in objs]
- except Exception as e:
- module.fail_json(msg=e.message)
-
- len_results = len(results)
- len_objs = len(objs)
-
- EXIT_DICT['container'] = c.name
- EXIT_DICT['requested_downloaded'] = results
- if results:
- EXIT_DICT['changed'] = True
- if len_results == len_objs:
- EXIT_DICT['success'] = True
- EXIT_DICT['msg'] = "%s objects downloaded to %s" % (len_results, dest)
- else:
- EXIT_DICT['msg'] = "Error: only %s of %s objects were " \
- "downloaded" % (len_results, len_objs)
- module.exit_json(**EXIT_DICT)
-
-
-def delete(module, cf, container, src, dest):
- """ Delete specific objects by proving a single file name or a
- comma-separated list to src OR dest (but not both). Omitting file name(s)
- assumes the entire container is to be deleted.
- """
- if src and dest:
- module.fail_json(msg="Error: ambiguous instructions; files to be deleted "
- "have been specified on both src and dest args")
-
- c = _get_container(module, cf, container)
-
- objs = dest or src
- if objs:
- objs = map(str.strip, objs.split(','))
- else:
- objs = c.get_object_names()
-
- num_objs = len(objs)
-
- try:
- results = [c.delete_object(obj) for obj in objs]
- except Exception as e:
- module.fail_json(msg=e.message)
-
- num_deleted = results.count(True)
-
- EXIT_DICT['container'] = c.name
- EXIT_DICT['deleted'] = num_deleted
- EXIT_DICT['requested_deleted'] = objs
-
- if num_deleted:
- EXIT_DICT['changed'] = True
-
- if num_objs == num_deleted:
- EXIT_DICT['success'] = True
- EXIT_DICT['msg'] = "%s objects deleted" % num_deleted
- else:
- EXIT_DICT['msg'] = ("Error: only %s of %s objects "
- "deleted" % (num_deleted, num_objs))
- module.exit_json(**EXIT_DICT)
-
-
-def get_meta(module, cf, container, src, dest):
- """ Get metadata for a single file, comma-separated list, or entire
- container
- """
- if src and dest:
- module.fail_json(msg="Error: ambiguous instructions; files to be deleted "
- "have been specified on both src and dest args")
-
- c = _get_container(module, cf, container)
-
- objs = dest or src
- if objs:
- objs = map(str.strip, objs.split(','))
- else:
- objs = c.get_object_names()
-
- try:
- results = dict()
- for obj in objs:
- meta = c.get_object(obj).get_metadata()
- results[obj] = dict((k.split(META_PREFIX)[-1], v) for k, v in meta.items())
- except Exception as e:
- module.fail_json(msg=e.message)
-
- EXIT_DICT['container'] = c.name
- if results:
- EXIT_DICT['meta_results'] = results
- EXIT_DICT['success'] = True
- module.exit_json(**EXIT_DICT)
-
-
-def put_meta(module, cf, container, src, dest, meta, clear_meta):
- """ Set metadata on a container, single file, or comma-separated list.
- Passing a true value to clear_meta clears the metadata stored in Cloud
- Files before setting the new metadata to the value of "meta".
- """
- if src and dest:
- module.fail_json(msg="Error: ambiguous instructions; files to set meta"
- " have been specified on both src and dest args")
- objs = dest or src
- objs = map(str.strip, objs.split(','))
-
- c = _get_container(module, cf, container)
-
- try:
- results = [c.get_object(obj).set_metadata(meta, clear=clear_meta) for obj in objs]
- except Exception as e:
- module.fail_json(msg=e.message)
-
- EXIT_DICT['container'] = c.name
- EXIT_DICT['success'] = True
- if results:
- EXIT_DICT['changed'] = True
- EXIT_DICT['num_changed'] = True
- module.exit_json(**EXIT_DICT)
-
-
-def delete_meta(module, cf, container, src, dest, meta):
- """ Removes metadata keys and values specified in meta, if any. Deletes on
- all objects specified by src or dest (but not both), if any; otherwise it
- deletes keys on all objects in the container
- """
- if src and dest:
- module.fail_json(msg="Error: ambiguous instructions; meta keys to be "
- "deleted have been specified on both src and dest"
- " args")
- objs = dest or src
- objs = map(str.strip, objs.split(','))
-
- c = _get_container(module, cf, container)
-
- try:
- for obj in objs:
- o = c.get_object(obj)
- results = [
- o.remove_metadata_key(k)
- for k in (meta or o.get_metadata())
- ]
- except Exception as e:
- module.fail_json(msg=e.message)
-
- EXIT_DICT['container'] = c.name
- EXIT_DICT['success'] = True
- if results:
- EXIT_DICT['changed'] = True
- EXIT_DICT['num_deleted'] = len(results)
- module.exit_json(**EXIT_DICT)
-
-
-def cloudfiles(module, container, src, dest, method, typ, meta, clear_meta,
- structure, expires):
- """ Dispatch from here to work with metadata or file objects """
- cf = pyrax.cloudfiles
-
- if cf is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if typ == "file":
- if method == 'get':
- download(module, cf, container, src, dest, structure)
-
- if method == 'put':
- upload(module, cf, container, src, dest, meta, expires)
-
- if method == 'delete':
- delete(module, cf, container, src, dest)
-
- else:
- if method == 'get':
- get_meta(module, cf, container, src, dest)
-
- if method == 'put':
- put_meta(module, cf, container, src, dest, meta, clear_meta)
-
- if method == 'delete':
- delete_meta(module, cf, container, src, dest, meta)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- container=dict(required=True),
- src=dict(),
- dest=dict(),
- method=dict(default='get', choices=['put', 'get', 'delete']),
- type=dict(default='file', choices=['file', 'meta']),
- meta=dict(type='dict', default=dict()),
- clear_meta=dict(default=False, type='bool'),
- structure=dict(default=True, type='bool'),
- expires=dict(type='int'),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- container = module.params.get('container')
- src = module.params.get('src')
- dest = module.params.get('dest')
- method = module.params.get('method')
- typ = module.params.get('type')
- meta = module.params.get('meta')
- clear_meta = module.params.get('clear_meta')
- structure = module.params.get('structure')
- expires = module.params.get('expires')
-
- if clear_meta and not typ == 'meta':
- module.fail_json(msg='clear_meta can only be used when setting metadata')
-
- setup_rax_module(module, pyrax)
- cloudfiles(module, container, src, dest, method, typ, meta, clear_meta, structure, expires)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_identity.py b/ansible_collections/community/general/plugins/modules/rax_identity.py
deleted file mode 100644
index b2eb15627..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_identity.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_identity
-short_description: Load Rackspace Cloud Identity
-description:
- - Verifies Rackspace Cloud credentials and returns identity information
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices: ['present']
- default: present
- required: false
-author:
- - "Christopher H. Laco (@claco)"
- - "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Load Rackspace Cloud Identity
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Load Identity
- local_action:
- module: rax_identity
- credentials: ~/.raxpub
- region: DFW
- register: rackspace_identity
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec, rax_required_together, rax_to_dict,
- setup_rax_module)
-
-
-def cloud_identity(module, state, identity):
- instance = dict(
- authenticated=identity.authenticated,
- credentials=identity._creds_file
- )
- changed = False
-
- instance.update(rax_to_dict(identity))
- instance['services'] = instance.get('services', {}).keys()
-
- if state == 'present':
- if not identity.authenticated:
- module.fail_json(msg='Credentials could not be verified!')
-
- module.exit_json(changed=changed, identity=instance)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- state=dict(default='present', choices=['present'])
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- state = module.params.get('state')
-
- setup_rax_module(module, pyrax)
-
- if not pyrax.identity:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- cloud_identity(module, state, pyrax.identity)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_keypair.py b/ansible_collections/community/general/plugins/modules/rax_keypair.py
deleted file mode 100644
index d7d7a2cc3..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_keypair.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_keypair
-short_description: Create a keypair for use with Rackspace Cloud Servers
-description:
- - Create a keypair for use with Rackspace Cloud Servers
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- name:
- type: str
- description:
- - Name of keypair
- required: true
- public_key:
- type: str
- description:
- - Public Key string to upload. Can be a file path or string
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
-author: "Matt Martz (@sivel)"
-notes:
- - Keypairs cannot be manipulated, only created and deleted. To "update" a
- keypair you must first delete and then recreate.
- - The ability to specify a file path for the public key was added in 1.7
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Create a keypair
- hosts: localhost
- gather_facts: false
- tasks:
- - name: Keypair request
- local_action:
- module: rax_keypair
- credentials: ~/.raxpub
- name: my_keypair
- region: DFW
- register: keypair
- - name: Create local public key
- local_action:
- module: copy
- content: "{{ keypair.keypair.public_key }}"
- dest: "{{ inventory_dir }}/{{ keypair.keypair.name }}.pub"
- - name: Create local private key
- local_action:
- module: copy
- content: "{{ keypair.keypair.private_key }}"
- dest: "{{ inventory_dir }}/{{ keypair.keypair.name }}"
-
-- name: Create a keypair
- hosts: localhost
- gather_facts: false
- tasks:
- - name: Keypair request
- local_action:
- module: rax_keypair
- credentials: ~/.raxpub
- name: my_keypair
- public_key: "{{ lookup('file', 'authorized_keys/id_rsa.pub') }}"
- region: DFW
- register: keypair
-'''
-import os
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec,
- rax_required_together,
- rax_to_dict,
- setup_rax_module,
- )
-
-
-def rax_keypair(module, name, public_key, state):
- changed = False
-
- cs = pyrax.cloudservers
-
- if cs is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- keypair = {}
-
- if state == 'present':
- if public_key and os.path.isfile(public_key):
- try:
- f = open(public_key)
- public_key = f.read()
- f.close()
- except Exception as e:
- module.fail_json(msg='Failed to load %s' % public_key)
-
- try:
- keypair = cs.keypairs.find(name=name)
- except cs.exceptions.NotFound:
- try:
- keypair = cs.keypairs.create(name, public_key)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- elif state == 'absent':
- try:
- keypair = cs.keypairs.find(name=name)
- except Exception:
- pass
-
- if keypair:
- try:
- keypair.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, keypair=rax_to_dict(keypair))
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- name=dict(required=True),
- public_key=dict(),
- state=dict(default='present', choices=['absent', 'present']),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- name = module.params.get('name')
- public_key = module.params.get('public_key')
- state = module.params.get('state')
-
- setup_rax_module(module, pyrax)
-
- rax_keypair(module, name, public_key, state)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_meta.py b/ansible_collections/community/general/plugins/modules/rax_meta.py
deleted file mode 100644
index 7b52e906f..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_meta.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_meta
-short_description: Manipulate metadata for Rackspace Cloud Servers
-description:
- - Manipulate metadata for Rackspace Cloud Servers
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- address:
- type: str
- description:
- - Server IP address to modify metadata for, will match any IP assigned to
- the server
- id:
- type: str
- description:
- - Server ID to modify metadata for
- name:
- type: str
- description:
- - Server name to modify metadata for
- meta:
- type: dict
- default: {}
- description:
- - A hash of metadata to associate with the instance
-author: "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Set metadata for a server
- hosts: all
- gather_facts: false
- tasks:
- - name: Set metadata
- local_action:
- module: rax_meta
- credentials: ~/.raxpub
- name: "{{ inventory_hostname }}"
- region: DFW
- meta:
- group: primary_group
- groups:
- - group_two
- - group_three
- app: my_app
-
- - name: Clear metadata
- local_action:
- module: rax_meta
- credentials: ~/.raxpub
- name: "{{ inventory_hostname }}"
- region: DFW
-'''
-
-import json
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-from ansible.module_utils.six import string_types
-
-
-def rax_meta(module, address, name, server_id, meta):
- changed = False
-
- cs = pyrax.cloudservers
-
- if cs is None:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- search_opts = {}
- if name:
- search_opts = dict(name='^%s$' % name)
- try:
- servers = cs.servers.list(search_opts=search_opts)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- elif address:
- servers = []
- try:
- for server in cs.servers.list():
- for addresses in server.networks.values():
- if address in addresses:
- servers.append(server)
- break
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- elif server_id:
- servers = []
- try:
- servers.append(cs.servers.get(server_id))
- except Exception as e:
- pass
-
- if len(servers) > 1:
- module.fail_json(msg='Multiple servers found matching provided '
- 'search parameters')
- elif not servers:
- module.fail_json(msg='Failed to find a server matching provided '
- 'search parameters')
-
- # Normalize and ensure all metadata values are strings
- for k, v in meta.items():
- if isinstance(v, list):
- meta[k] = ','.join(['%s' % i for i in v])
- elif isinstance(v, dict):
- meta[k] = json.dumps(v)
- elif not isinstance(v, string_types):
- meta[k] = '%s' % v
-
- server = servers[0]
- if server.metadata == meta:
- changed = False
- else:
- changed = True
- removed = set(server.metadata.keys()).difference(meta.keys())
- cs.servers.delete_meta(server, list(removed))
- cs.servers.set_meta(server, meta)
- server.get()
-
- module.exit_json(changed=changed, meta=server.metadata)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- address=dict(),
- id=dict(),
- name=dict(),
- meta=dict(type='dict', default=dict()),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- mutually_exclusive=[['address', 'id', 'name']],
- required_one_of=[['address', 'id', 'name']],
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- address = module.params.get('address')
- server_id = module.params.get('id')
- name = module.params.get('name')
- meta = module.params.get('meta')
-
- setup_rax_module(module, pyrax)
-
- rax_meta(module, address, name, server_id, meta)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_mon_alarm.py b/ansible_collections/community/general/plugins/modules/rax_mon_alarm.py
deleted file mode 100644
index b66611a90..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_mon_alarm.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_mon_alarm
-short_description: Create or delete a Rackspace Cloud Monitoring alarm
-description:
-- Create or delete a Rackspace Cloud Monitoring alarm that associates an
- existing rax_mon_entity, rax_mon_check, and rax_mon_notification_plan with
- criteria that specify what conditions will trigger which levels of
- notifications. Rackspace monitoring module flow | rax_mon_entity ->
- rax_mon_check -> rax_mon_notification -> rax_mon_notification_plan ->
- *rax_mon_alarm*
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- state:
- type: str
- description:
- - Ensure that the alarm with this O(label) exists or does not exist.
- choices: [ "present", "absent" ]
- required: false
- default: present
- label:
- type: str
- description:
- - Friendly name for this alarm, used to achieve idempotence. Must be a String
- between 1 and 255 characters long.
- required: true
- entity_id:
- type: str
- description:
- - ID of the entity this alarm is attached to. May be acquired by registering
- the value of a rax_mon_entity task.
- required: true
- check_id:
- type: str
- description:
- - ID of the check that should be alerted on. May be acquired by registering
- the value of a rax_mon_check task.
- required: true
- notification_plan_id:
- type: str
- description:
- - ID of the notification plan to trigger if this alarm fires. May be acquired
- by registering the value of a rax_mon_notification_plan task.
- required: true
- criteria:
- type: str
- description:
- - Alarm DSL that describes alerting conditions and their output states. Must
- be between 1 and 16384 characters long. See
- http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/alerts-language.html
- for a reference on the alerting language.
- disabled:
- description:
- - If yes, create this alarm, but leave it in an inactive state. Defaults to
- no.
- type: bool
- default: false
- metadata:
- type: dict
- description:
- - Arbitrary key/value pairs to accompany the alarm. Must be a hash of String
- keys and values between 1 and 255 characters long.
-author: Ash Wilson (@smashwilson)
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Alarm example
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Ensure that a specific alarm exists.
- community.general.rax_mon_alarm:
- credentials: ~/.rax_pub
- state: present
- label: uhoh
- entity_id: "{{ the_entity['entity']['id'] }}"
- check_id: "{{ the_check['check']['id'] }}"
- notification_plan_id: "{{ defcon1['notification_plan']['id'] }}"
- criteria: >
- if (rate(metric['average']) > 10) {
- return new AlarmStatus(WARNING);
- }
- return new AlarmStatus(OK);
- register: the_alarm
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def alarm(module, state, label, entity_id, check_id, notification_plan_id, criteria,
- disabled, metadata):
-
- if len(label) < 1 or len(label) > 255:
- module.fail_json(msg='label must be between 1 and 255 characters long')
-
- if criteria and len(criteria) < 1 or len(criteria) > 16384:
- module.fail_json(msg='criteria must be between 1 and 16384 characters long')
-
- # Coerce attributes.
-
- changed = False
- alarm = None
-
- cm = pyrax.cloud_monitoring
- if not cm:
- module.fail_json(msg='Failed to instantiate client. This typically '
- 'indicates an invalid region or an incorrectly '
- 'capitalized region name.')
-
- existing = [a for a in cm.list_alarms(entity_id) if a.label == label]
-
- if existing:
- alarm = existing[0]
-
- if state == 'present':
- should_create = False
- should_update = False
- should_delete = False
-
- if len(existing) > 1:
- module.fail_json(msg='%s existing alarms have the label %s.' %
- (len(existing), label))
-
- if alarm:
- if check_id != alarm.check_id or notification_plan_id != alarm.notification_plan_id:
- should_delete = should_create = True
-
- should_update = (disabled and disabled != alarm.disabled) or \
- (metadata and metadata != alarm.metadata) or \
- (criteria and criteria != alarm.criteria)
-
- if should_update and not should_delete:
- cm.update_alarm(entity=entity_id, alarm=alarm,
- criteria=criteria, disabled=disabled,
- label=label, metadata=metadata)
- changed = True
-
- if should_delete:
- alarm.delete()
- changed = True
- else:
- should_create = True
-
- if should_create:
- alarm = cm.create_alarm(entity=entity_id, check=check_id,
- notification_plan=notification_plan_id,
- criteria=criteria, disabled=disabled, label=label,
- metadata=metadata)
- changed = True
- else:
- for a in existing:
- a.delete()
- changed = True
-
- if alarm:
- alarm_dict = {
- "id": alarm.id,
- "label": alarm.label,
- "check_id": alarm.check_id,
- "notification_plan_id": alarm.notification_plan_id,
- "criteria": alarm.criteria,
- "disabled": alarm.disabled,
- "metadata": alarm.metadata
- }
- module.exit_json(changed=changed, alarm=alarm_dict)
- else:
- module.exit_json(changed=changed)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- state=dict(default='present', choices=['present', 'absent']),
- label=dict(required=True),
- entity_id=dict(required=True),
- check_id=dict(required=True),
- notification_plan_id=dict(required=True),
- criteria=dict(),
- disabled=dict(type='bool', default=False),
- metadata=dict(type='dict')
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- state = module.params.get('state')
- label = module.params.get('label')
- entity_id = module.params.get('entity_id')
- check_id = module.params.get('check_id')
- notification_plan_id = module.params.get('notification_plan_id')
- criteria = module.params.get('criteria')
- disabled = module.boolean(module.params.get('disabled'))
- metadata = module.params.get('metadata')
-
- setup_rax_module(module, pyrax)
-
- alarm(module, state, label, entity_id, check_id, notification_plan_id,
- criteria, disabled, metadata)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_mon_check.py b/ansible_collections/community/general/plugins/modules/rax_mon_check.py
deleted file mode 100644
index 253c26dcf..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_mon_check.py
+++ /dev/null
@@ -1,329 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_mon_check
-short_description: Create or delete a Rackspace Cloud Monitoring check for an
- existing entity.
-description:
-- Create or delete a Rackspace Cloud Monitoring check associated with an
- existing rax_mon_entity. A check is a specific test or measurement that is
- performed, possibly from different monitoring zones, on the systems you
- monitor. Rackspace monitoring module flow | rax_mon_entity ->
- *rax_mon_check* -> rax_mon_notification -> rax_mon_notification_plan ->
- rax_mon_alarm
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- state:
- type: str
- description:
- - Ensure that a check with this O(label) exists or does not exist.
- choices: ["present", "absent"]
- default: present
- entity_id:
- type: str
- description:
- - ID of the rax_mon_entity to target with this check.
- required: true
- label:
- type: str
- description:
- - Defines a label for this check, between 1 and 64 characters long.
- required: true
- check_type:
- type: str
- description:
- - The type of check to create. C(remote.) checks may be created on any
- rax_mon_entity. C(agent.) checks may only be created on rax_mon_entities
- that have a non-null C(agent_id).
- - |
- Choices for this option are:
- - V(remote.dns)
- - V(remote.ftp-banner)
- - V(remote.http)
- - V(remote.imap-banner)
- - V(remote.mssql-banner)
- - V(remote.mysql-banner)
- - V(remote.ping)
- - V(remote.pop3-banner)
- - V(remote.postgresql-banner)
- - V(remote.smtp-banner)
- - V(remote.smtp)
- - V(remote.ssh)
- - V(remote.tcp)
- - V(remote.telnet-banner)
- - V(agent.filesystem)
- - V(agent.memory)
- - V(agent.load_average)
- - V(agent.cpu)
- - V(agent.disk)
- - V(agent.network)
- - V(agent.plugin)
- required: true
- monitoring_zones_poll:
- type: str
- description:
- - Comma-separated list of the names of the monitoring zones the check should
- run from. Available monitoring zones include mzdfw, mzhkg, mziad, mzlon,
- mzord and mzsyd. Required for remote.* checks; prohibited for agent.* checks.
- target_hostname:
- type: str
- description:
- - One of O(target_hostname) and O(target_alias) is required for remote.* checks,
- but prohibited for agent.* checks. The hostname this check should target.
- Must be a valid IPv4, IPv6, or FQDN.
- target_alias:
- type: str
- description:
- - One of O(target_alias) and O(target_hostname) is required for remote.* checks,
- but prohibited for agent.* checks. Use the corresponding key in the entity's
- C(ip_addresses) hash to resolve an IP address to target.
- details:
- type: dict
- default: {}
- description:
- - Additional details specific to the check type. Must be a hash of strings
- between 1 and 255 characters long, or an array or object containing 0 to
- 256 items.
- disabled:
- description:
- - If V(true), ensure the check is created, but don't actually use it yet.
- type: bool
- default: false
- metadata:
- type: dict
- default: {}
- description:
- - Hash of arbitrary key-value pairs to accompany this check if it fires.
- Keys and values must be strings between 1 and 255 characters long.
- period:
- type: int
- description:
- - The number of seconds between each time the check is performed. Must be
- greater than the minimum period set on your account.
- timeout:
- type: int
- description:
- - The number of seconds this check will wait when attempting to collect
- results. Must be less than the period.
-author: Ash Wilson (@smashwilson)
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Create a monitoring check
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Associate a check with an existing entity.
- community.general.rax_mon_check:
- credentials: ~/.rax_pub
- state: present
- entity_id: "{{ the_entity['entity']['id'] }}"
- label: the_check
- check_type: remote.ping
- monitoring_zones_poll: mziad,mzord,mzdfw
- details:
- count: 10
- meta:
- hurf: durf
- register: the_check
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def cloud_check(module, state, entity_id, label, check_type,
- monitoring_zones_poll, target_hostname, target_alias, details,
- disabled, metadata, period, timeout):
-
- # Coerce attributes.
-
- if monitoring_zones_poll and not isinstance(monitoring_zones_poll, list):
- monitoring_zones_poll = [monitoring_zones_poll]
-
- if period:
- period = int(period)
-
- if timeout:
- timeout = int(timeout)
-
- changed = False
- check = None
-
- cm = pyrax.cloud_monitoring
- if not cm:
- module.fail_json(msg='Failed to instantiate client. This typically '
- 'indicates an invalid region or an incorrectly '
- 'capitalized region name.')
-
- entity = cm.get_entity(entity_id)
- if not entity:
- module.fail_json(msg='Failed to instantiate entity. "%s" may not be'
- ' a valid entity id.' % entity_id)
-
- existing = [e for e in entity.list_checks() if e.label == label]
-
- if existing:
- check = existing[0]
-
- if state == 'present':
- if len(existing) > 1:
- module.fail_json(msg='%s existing checks have a label of %s.' %
- (len(existing), label))
-
- should_delete = False
- should_create = False
- should_update = False
-
- if check:
- # Details may include keys set to default values that are not
- # included in the initial creation.
- #
- # Only force a recreation of the check if one of the *specified*
- # keys is missing or has a different value.
- if details:
- for (key, value) in details.items():
- if key not in check.details:
- should_delete = should_create = True
- elif value != check.details[key]:
- should_delete = should_create = True
-
- should_update = label != check.label or \
- (target_hostname and target_hostname != check.target_hostname) or \
- (target_alias and target_alias != check.target_alias) or \
- (disabled != check.disabled) or \
- (metadata and metadata != check.metadata) or \
- (period and period != check.period) or \
- (timeout and timeout != check.timeout) or \
- (monitoring_zones_poll and monitoring_zones_poll != check.monitoring_zones_poll)
-
- if should_update and not should_delete:
- check.update(label=label,
- disabled=disabled,
- metadata=metadata,
- monitoring_zones_poll=monitoring_zones_poll,
- timeout=timeout,
- period=period,
- target_alias=target_alias,
- target_hostname=target_hostname)
- changed = True
- else:
- # The check doesn't exist yet.
- should_create = True
-
- if should_delete:
- check.delete()
-
- if should_create:
- check = cm.create_check(entity,
- label=label,
- check_type=check_type,
- target_hostname=target_hostname,
- target_alias=target_alias,
- monitoring_zones_poll=monitoring_zones_poll,
- details=details,
- disabled=disabled,
- metadata=metadata,
- period=period,
- timeout=timeout)
- changed = True
- elif state == 'absent':
- if check:
- check.delete()
- changed = True
- else:
- module.fail_json(msg='state must be either present or absent.')
-
- if check:
- check_dict = {
- "id": check.id,
- "label": check.label,
- "type": check.type,
- "target_hostname": check.target_hostname,
- "target_alias": check.target_alias,
- "monitoring_zones_poll": check.monitoring_zones_poll,
- "details": check.details,
- "disabled": check.disabled,
- "metadata": check.metadata,
- "period": check.period,
- "timeout": check.timeout
- }
- module.exit_json(changed=changed, check=check_dict)
- else:
- module.exit_json(changed=changed)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- entity_id=dict(required=True),
- label=dict(required=True),
- check_type=dict(required=True),
- monitoring_zones_poll=dict(),
- target_hostname=dict(),
- target_alias=dict(),
- details=dict(type='dict', default={}),
- disabled=dict(type='bool', default=False),
- metadata=dict(type='dict', default={}),
- period=dict(type='int'),
- timeout=dict(type='int'),
- state=dict(default='present', choices=['present', 'absent'])
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- entity_id = module.params.get('entity_id')
- label = module.params.get('label')
- check_type = module.params.get('check_type')
- monitoring_zones_poll = module.params.get('monitoring_zones_poll')
- target_hostname = module.params.get('target_hostname')
- target_alias = module.params.get('target_alias')
- details = module.params.get('details')
- disabled = module.boolean(module.params.get('disabled'))
- metadata = module.params.get('metadata')
- period = module.params.get('period')
- timeout = module.params.get('timeout')
-
- state = module.params.get('state')
-
- setup_rax_module(module, pyrax)
-
- cloud_check(module, state, entity_id, label, check_type,
- monitoring_zones_poll, target_hostname, target_alias, details,
- disabled, metadata, period, timeout)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_mon_entity.py b/ansible_collections/community/general/plugins/modules/rax_mon_entity.py
deleted file mode 100644
index fbad9f98f..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_mon_entity.py
+++ /dev/null
@@ -1,201 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_mon_entity
-short_description: Create or delete a Rackspace Cloud Monitoring entity
-description:
-- Create or delete a Rackspace Cloud Monitoring entity, which represents a device
- to monitor. Entities associate checks and alarms with a target system and
- provide a convenient, centralized place to store IP addresses. Rackspace
- monitoring module flow | *rax_mon_entity* -> rax_mon_check ->
- rax_mon_notification -> rax_mon_notification_plan -> rax_mon_alarm
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- label:
- type: str
- description:
- - Defines a name for this entity. Must be a non-empty string between 1 and
- 255 characters long.
- required: true
- state:
- type: str
- description:
- - Ensure that an entity with this C(name) exists or does not exist.
- choices: ["present", "absent"]
- default: present
- agent_id:
- type: str
- description:
- - Rackspace monitoring agent on the target device to which this entity is
- bound. Necessary to collect C(agent.) rax_mon_checks against this entity.
- named_ip_addresses:
- type: dict
- default: {}
- description:
- - Hash of IP addresses that may be referenced by name by rax_mon_checks
- added to this entity. Must be a dictionary of with keys that are names
- between 1 and 64 characters long, and values that are valid IPv4 or IPv6
- addresses.
- metadata:
- type: dict
- default: {}
- description:
- - Hash of arbitrary C(name), C(value) pairs that are passed to associated
- rax_mon_alarms. Names and values must all be between 1 and 255 characters
- long.
-author: Ash Wilson (@smashwilson)
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Entity example
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Ensure an entity exists
- community.general.rax_mon_entity:
- credentials: ~/.rax_pub
- state: present
- label: my_entity
- named_ip_addresses:
- web_box: 192.0.2.4
- db_box: 192.0.2.5
- meta:
- hurf: durf
- register: the_entity
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def cloud_monitoring(module, state, label, agent_id, named_ip_addresses,
- metadata):
-
- if len(label) < 1 or len(label) > 255:
- module.fail_json(msg='label must be between 1 and 255 characters long')
-
- changed = False
-
- cm = pyrax.cloud_monitoring
- if not cm:
- module.fail_json(msg='Failed to instantiate client. This typically '
- 'indicates an invalid region or an incorrectly '
- 'capitalized region name.')
-
- existing = []
- for entity in cm.list_entities():
- if label == entity.label:
- existing.append(entity)
-
- entity = None
-
- if existing:
- entity = existing[0]
-
- if state == 'present':
- should_update = False
- should_delete = False
- should_create = False
-
- if len(existing) > 1:
- module.fail_json(msg='%s existing entities have the label %s.' %
- (len(existing), label))
-
- if entity:
- if named_ip_addresses and named_ip_addresses != entity.ip_addresses:
- should_delete = should_create = True
-
- # Change an existing Entity, unless there's nothing to do.
- should_update = agent_id and agent_id != entity.agent_id or \
- (metadata and metadata != entity.metadata)
-
- if should_update and not should_delete:
- entity.update(agent_id, metadata)
- changed = True
-
- if should_delete:
- entity.delete()
- else:
- should_create = True
-
- if should_create:
- # Create a new Entity.
- entity = cm.create_entity(label=label, agent=agent_id,
- ip_addresses=named_ip_addresses,
- metadata=metadata)
- changed = True
- else:
- # Delete the existing Entities.
- for e in existing:
- e.delete()
- changed = True
-
- if entity:
- entity_dict = {
- "id": entity.id,
- "name": entity.name,
- "agent_id": entity.agent_id,
- }
- module.exit_json(changed=changed, entity=entity_dict)
- else:
- module.exit_json(changed=changed)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- state=dict(default='present', choices=['present', 'absent']),
- label=dict(required=True),
- agent_id=dict(),
- named_ip_addresses=dict(type='dict', default={}),
- metadata=dict(type='dict', default={})
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- state = module.params.get('state')
-
- label = module.params.get('label')
- agent_id = module.params.get('agent_id')
- named_ip_addresses = module.params.get('named_ip_addresses')
- metadata = module.params.get('metadata')
-
- setup_rax_module(module, pyrax)
-
- cloud_monitoring(module, state, label, agent_id, named_ip_addresses, metadata)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_mon_notification.py b/ansible_collections/community/general/plugins/modules/rax_mon_notification.py
deleted file mode 100644
index 7539f2a37..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_mon_notification.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_mon_notification
-short_description: Create or delete a Rackspace Cloud Monitoring notification
-description:
-- Create or delete a Rackspace Cloud Monitoring notification that specifies a
- channel that can be used to communicate alarms, such as email, webhooks, or
- PagerDuty. Rackspace monitoring module flow | rax_mon_entity -> rax_mon_check ->
- *rax_mon_notification* -> rax_mon_notification_plan -> rax_mon_alarm
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- state:
- type: str
- description:
- - Ensure that the notification with this O(label) exists or does not exist.
- choices: ['present', 'absent']
- default: present
- label:
- type: str
- description:
- - Defines a friendly name for this notification. String between 1 and 255
- characters long.
- required: true
- notification_type:
- type: str
- description:
- - A supported notification type.
- choices: ["webhook", "email", "pagerduty"]
- required: true
- details:
- type: dict
- description:
- - Dictionary of key-value pairs used to initialize the notification.
- Required keys and meanings vary with notification type. See
- http://docs.rackspace.com/cm/api/v1.0/cm-devguide/content/
- service-notification-types-crud.html for details.
- required: true
-author: Ash Wilson (@smashwilson)
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Monitoring notification example
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Email me when something goes wrong.
- rax_mon_entity:
- credentials: ~/.rax_pub
- label: omg
- type: email
- details:
- address: me@mailhost.com
- register: the_notification
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def notification(module, state, label, notification_type, details):
-
- if len(label) < 1 or len(label) > 255:
- module.fail_json(msg='label must be between 1 and 255 characters long')
-
- changed = False
- notification = None
-
- cm = pyrax.cloud_monitoring
- if not cm:
- module.fail_json(msg='Failed to instantiate client. This typically '
- 'indicates an invalid region or an incorrectly '
- 'capitalized region name.')
-
- existing = []
- for n in cm.list_notifications():
- if n.label == label:
- existing.append(n)
-
- if existing:
- notification = existing[0]
-
- if state == 'present':
- should_update = False
- should_delete = False
- should_create = False
-
- if len(existing) > 1:
- module.fail_json(msg='%s existing notifications are labelled %s.' %
- (len(existing), label))
-
- if notification:
- should_delete = (notification_type != notification.type)
-
- should_update = (details != notification.details)
-
- if should_update and not should_delete:
- notification.update(details=notification.details)
- changed = True
-
- if should_delete:
- notification.delete()
- else:
- should_create = True
-
- if should_create:
- notification = cm.create_notification(notification_type,
- label=label, details=details)
- changed = True
- else:
- for n in existing:
- n.delete()
- changed = True
-
- if notification:
- notification_dict = {
- "id": notification.id,
- "type": notification.type,
- "label": notification.label,
- "details": notification.details
- }
- module.exit_json(changed=changed, notification=notification_dict)
- else:
- module.exit_json(changed=changed)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- state=dict(default='present', choices=['present', 'absent']),
- label=dict(required=True),
- notification_type=dict(required=True, choices=['webhook', 'email', 'pagerduty']),
- details=dict(required=True, type='dict')
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- state = module.params.get('state')
-
- label = module.params.get('label')
- notification_type = module.params.get('notification_type')
- details = module.params.get('details')
-
- setup_rax_module(module, pyrax)
-
- notification(module, state, label, notification_type, details)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_mon_notification_plan.py b/ansible_collections/community/general/plugins/modules/rax_mon_notification_plan.py
deleted file mode 100644
index 31647304b..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_mon_notification_plan.py
+++ /dev/null
@@ -1,191 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_mon_notification_plan
-short_description: Create or delete a Rackspace Cloud Monitoring notification
- plan.
-description:
-- Create or delete a Rackspace Cloud Monitoring notification plan by
- associating existing rax_mon_notifications with severity levels. Rackspace
- monitoring module flow | rax_mon_entity -> rax_mon_check ->
- rax_mon_notification -> *rax_mon_notification_plan* -> rax_mon_alarm
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- state:
- type: str
- description:
- - Ensure that the notification plan with this O(label) exists or does not
- exist.
- choices: ['present', 'absent']
- default: present
- label:
- type: str
- description:
- - Defines a friendly name for this notification plan. String between 1 and
- 255 characters long.
- required: true
- critical_state:
- type: list
- elements: str
- description:
- - Notification list to use when the alarm state is CRITICAL. Must be an
- array of valid rax_mon_notification ids.
- warning_state:
- type: list
- elements: str
- description:
- - Notification list to use when the alarm state is WARNING. Must be an array
- of valid rax_mon_notification ids.
- ok_state:
- type: list
- elements: str
- description:
- - Notification list to use when the alarm state is OK. Must be an array of
- valid rax_mon_notification ids.
-author: Ash Wilson (@smashwilson)
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Example notification plan
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Establish who gets called when.
- community.general.rax_mon_notification_plan:
- credentials: ~/.rax_pub
- state: present
- label: defcon1
- critical_state:
- - "{{ everyone['notification']['id'] }}"
- warning_state:
- - "{{ opsfloor['notification']['id'] }}"
- register: defcon1
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def notification_plan(module, state, label, critical_state, warning_state, ok_state):
-
- if len(label) < 1 or len(label) > 255:
- module.fail_json(msg='label must be between 1 and 255 characters long')
-
- changed = False
- notification_plan = None
-
- cm = pyrax.cloud_monitoring
- if not cm:
- module.fail_json(msg='Failed to instantiate client. This typically '
- 'indicates an invalid region or an incorrectly '
- 'capitalized region name.')
-
- existing = []
- for n in cm.list_notification_plans():
- if n.label == label:
- existing.append(n)
-
- if existing:
- notification_plan = existing[0]
-
- if state == 'present':
- should_create = False
- should_delete = False
-
- if len(existing) > 1:
- module.fail_json(msg='%s notification plans are labelled %s.' %
- (len(existing), label))
-
- if notification_plan:
- should_delete = (critical_state and critical_state != notification_plan.critical_state) or \
- (warning_state and warning_state != notification_plan.warning_state) or \
- (ok_state and ok_state != notification_plan.ok_state)
-
- if should_delete:
- notification_plan.delete()
- should_create = True
- else:
- should_create = True
-
- if should_create:
- notification_plan = cm.create_notification_plan(label=label,
- critical_state=critical_state,
- warning_state=warning_state,
- ok_state=ok_state)
- changed = True
- else:
- for np in existing:
- np.delete()
- changed = True
-
- if notification_plan:
- notification_plan_dict = {
- "id": notification_plan.id,
- "critical_state": notification_plan.critical_state,
- "warning_state": notification_plan.warning_state,
- "ok_state": notification_plan.ok_state,
- "metadata": notification_plan.metadata
- }
- module.exit_json(changed=changed, notification_plan=notification_plan_dict)
- else:
- module.exit_json(changed=changed)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- state=dict(default='present', choices=['present', 'absent']),
- label=dict(required=True),
- critical_state=dict(type='list', elements='str'),
- warning_state=dict(type='list', elements='str'),
- ok_state=dict(type='list', elements='str'),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- state = module.params.get('state')
-
- label = module.params.get('label')
- critical_state = module.params.get('critical_state')
- warning_state = module.params.get('warning_state')
- ok_state = module.params.get('ok_state')
-
- setup_rax_module(module, pyrax)
-
- notification_plan(module, state, label, critical_state, warning_state, ok_state)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_network.py b/ansible_collections/community/general/plugins/modules/rax_network.py
deleted file mode 100644
index 22f148366..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_network.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_network
-short_description: Create / delete an isolated network in Rackspace Public Cloud
-description:
- - creates / deletes a Rackspace Public Cloud isolated network.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- label:
- type: str
- description:
- - Label (name) to give the network
- required: true
- cidr:
- type: str
- description:
- - cidr of the network being created
-author:
- - "Christopher H. Laco (@claco)"
- - "Jesse Keating (@omgjlk)"
-extends_documentation_fragment:
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build an Isolated Network
- gather_facts: false
-
- tasks:
- - name: Network create request
- local_action:
- module: rax_network
- credentials: ~/.raxpub
- label: my-net
- cidr: 192.168.3.0/24
- state: present
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def cloud_network(module, state, label, cidr):
- changed = False
- network = None
- networks = []
-
- if not pyrax.cloud_networks:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if state == 'present':
- if not cidr:
- module.fail_json(msg='missing required arguments: cidr')
-
- try:
- network = pyrax.cloud_networks.find_network_by_label(label)
- except pyrax.exceptions.NetworkNotFound:
- try:
- network = pyrax.cloud_networks.create(label, cidr=cidr)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- elif state == 'absent':
- try:
- network = pyrax.cloud_networks.find_network_by_label(label)
- network.delete()
- changed = True
- except pyrax.exceptions.NetworkNotFound:
- pass
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- if network:
- instance = dict(id=network.id,
- label=network.label,
- cidr=network.cidr)
- networks.append(instance)
-
- module.exit_json(changed=changed, networks=networks)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- state=dict(default='present',
- choices=['present', 'absent']),
- label=dict(required=True),
- cidr=dict()
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- state = module.params.get('state')
- label = module.params.get('label')
- cidr = module.params.get('cidr')
-
- setup_rax_module(module, pyrax)
-
- cloud_network(module, state, label, cidr)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_queue.py b/ansible_collections/community/general/plugins/modules/rax_queue.py
deleted file mode 100644
index 00f730b27..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_queue.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_queue
-short_description: Create / delete a queue in Rackspace Public Cloud
-description:
- - creates / deletes a Rackspace Public Cloud queue.
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- name:
- type: str
- description:
- - Name to give the queue
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
-author:
- - "Christopher H. Laco (@claco)"
- - "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
-- name: Build a Queue
- gather_facts: false
- hosts: local
- connection: local
- tasks:
- - name: Queue create request
- local_action:
- module: rax_queue
- credentials: ~/.raxpub
- name: my-queue
- region: DFW
- state: present
- register: my_queue
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module
-
-
-def cloud_queue(module, state, name):
- for arg in (state, name):
- if not arg:
- module.fail_json(msg='%s is required for rax_queue' % arg)
-
- changed = False
- queues = []
- instance = {}
-
- cq = pyrax.queues
- if not cq:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- for queue in cq.list():
- if name != queue.name:
- continue
-
- queues.append(queue)
-
- if len(queues) > 1:
- module.fail_json(msg='Multiple Queues were matched by name')
-
- if state == 'present':
- if not queues:
- try:
- queue = cq.create(name)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- queue = queues[0]
-
- instance = dict(name=queue.name)
- result = dict(changed=changed, queue=instance)
- module.exit_json(**result)
-
- elif state == 'absent':
- if queues:
- queue = queues[0]
- try:
- queue.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, queue=instance)
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- name=dict(),
- state=dict(default='present', choices=['present', 'absent']),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together()
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- name = module.params.get('name')
- state = module.params.get('state')
-
- setup_rax_module(module, pyrax)
-
- cloud_queue(module, state, name)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_scaling_group.py b/ansible_collections/community/general/plugins/modules/rax_scaling_group.py
deleted file mode 100644
index f4bb79025..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_scaling_group.py
+++ /dev/null
@@ -1,441 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_scaling_group
-short_description: Manipulate Rackspace Cloud Autoscale Groups
-description:
- - Manipulate Rackspace Cloud Autoscale Groups
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- config_drive:
- description:
- - Attach read-only configuration drive to server as label config-2
- type: bool
- default: false
- cooldown:
- type: int
- description:
- - The period of time, in seconds, that must pass before any scaling can
- occur after the previous scaling. Must be an integer between 0 and
- 86400 (24 hrs).
- default: 300
- disk_config:
- type: str
- description:
- - Disk partitioning strategy
- - If not specified, it will fallback to V(auto).
- choices:
- - auto
- - manual
- files:
- type: dict
- default: {}
- description:
- - 'Files to insert into the instance. Hash of C(remotepath: localpath)'
- flavor:
- type: str
- description:
- - flavor to use for the instance
- required: true
- image:
- type: str
- description:
- - image to use for the instance. Can be an C(id), C(human_id) or C(name).
- required: true
- key_name:
- type: str
- description:
- - key pair to use on the instance
- loadbalancers:
- type: list
- elements: dict
- description:
- - List of load balancer C(id) and C(port) hashes
- max_entities:
- type: int
- description:
- - The maximum number of entities that are allowed in the scaling group.
- Must be an integer between 0 and 1000.
- required: true
- meta:
- type: dict
- default: {}
- description:
- - A hash of metadata to associate with the instance
- min_entities:
- type: int
- description:
- - The minimum number of entities that are allowed in the scaling group.
- Must be an integer between 0 and 1000.
- required: true
- name:
- type: str
- description:
- - Name to give the scaling group
- required: true
- networks:
- type: list
- elements: str
- description:
- - The network to attach to the instances. If specified, you must include
- ALL networks including the public and private interfaces. Can be C(id)
- or C(label).
- default:
- - public
- - private
- server_name:
- type: str
- description:
- - The base name for servers created by Autoscale
- required: true
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
- user_data:
- type: str
- description:
- - Data to be uploaded to the servers config drive. This option implies
- O(config_drive). Can be a file path or a string
- wait:
- description:
- - wait for the scaling group to finish provisioning the minimum amount of
- servers
- type: bool
- default: false
- wait_timeout:
- type: int
- description:
- - how long before wait gives up, in seconds
- default: 300
-author: "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
----
-- hosts: localhost
- gather_facts: false
- connection: local
- tasks:
- - community.general.rax_scaling_group:
- credentials: ~/.raxpub
- region: ORD
- cooldown: 300
- flavor: performance1-1
- image: bb02b1a3-bc77-4d17-ab5b-421d89850fca
- min_entities: 5
- max_entities: 10
- name: ASG Test
- server_name: asgtest
- loadbalancers:
- - id: 228385
- port: 80
- register: asg
-'''
-
-import base64
-import json
-import os
-import time
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (
- rax_argument_spec, rax_find_image, rax_find_network,
- rax_required_together, rax_to_dict, setup_rax_module,
- rax_scaling_group_personality_file,
-)
-from ansible.module_utils.six import string_types
-
-
-def rax_asg(module, cooldown=300, disk_config=None, files=None, flavor=None,
- image=None, key_name=None, loadbalancers=None, meta=None,
- min_entities=0, max_entities=0, name=None, networks=None,
- server_name=None, state='present', user_data=None,
- config_drive=False, wait=True, wait_timeout=300):
- files = {} if files is None else files
- loadbalancers = [] if loadbalancers is None else loadbalancers
- meta = {} if meta is None else meta
- networks = [] if networks is None else networks
-
- changed = False
-
- au = pyrax.autoscale
- if not au:
- module.fail_json(msg='Failed to instantiate clients. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- if user_data:
- config_drive = True
-
- if user_data and os.path.isfile(user_data):
- try:
- f = open(user_data)
- user_data = f.read()
- f.close()
- except Exception as e:
- module.fail_json(msg='Failed to load %s' % user_data)
-
- if state == 'present':
- # Normalize and ensure all metadata values are strings
- if meta:
- for k, v in meta.items():
- if isinstance(v, list):
- meta[k] = ','.join(['%s' % i for i in v])
- elif isinstance(v, dict):
- meta[k] = json.dumps(v)
- elif not isinstance(v, string_types):
- meta[k] = '%s' % v
-
- if image:
- image = rax_find_image(module, pyrax, image)
-
- nics = []
- if networks:
- for network in networks:
- nics.extend(rax_find_network(module, pyrax, network))
-
- for nic in nics:
- # pyrax is currently returning net-id, but we need uuid
- # this check makes this forward compatible for a time when
- # pyrax uses uuid instead
- if nic.get('net-id'):
- nic.update(uuid=nic['net-id'])
- del nic['net-id']
-
- # Handle the file contents
- personality = rax_scaling_group_personality_file(module, files)
-
- lbs = []
- if loadbalancers:
- for lb in loadbalancers:
- try:
- lb_id = int(lb.get('id'))
- except (ValueError, TypeError):
- module.fail_json(msg='Load balancer ID is not an integer: '
- '%s' % lb.get('id'))
- try:
- port = int(lb.get('port'))
- except (ValueError, TypeError):
- module.fail_json(msg='Load balancer port is not an '
- 'integer: %s' % lb.get('port'))
- if not lb_id or not port:
- continue
- lbs.append((lb_id, port))
-
- try:
- sg = au.find(name=name)
- except pyrax.exceptions.NoUniqueMatch as e:
- module.fail_json(msg='%s' % e.message)
- except pyrax.exceptions.NotFound:
- try:
- sg = au.create(name, cooldown=cooldown,
- min_entities=min_entities,
- max_entities=max_entities,
- launch_config_type='launch_server',
- server_name=server_name, image=image,
- flavor=flavor, disk_config=disk_config,
- metadata=meta, personality=personality,
- networks=nics, load_balancers=lbs,
- key_name=key_name, config_drive=config_drive,
- user_data=user_data)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- if not changed:
- # Scaling Group Updates
- group_args = {}
- if cooldown != sg.cooldown:
- group_args['cooldown'] = cooldown
-
- if min_entities != sg.min_entities:
- group_args['min_entities'] = min_entities
-
- if max_entities != sg.max_entities:
- group_args['max_entities'] = max_entities
-
- if group_args:
- changed = True
- sg.update(**group_args)
-
- # Launch Configuration Updates
- lc = sg.get_launch_config()
- lc_args = {}
- if server_name != lc.get('name'):
- lc_args['server_name'] = server_name
-
- if image != lc.get('image'):
- lc_args['image'] = image
-
- if flavor != lc.get('flavor'):
- lc_args['flavor'] = flavor
-
- disk_config = disk_config or 'AUTO'
- if ((disk_config or lc.get('disk_config')) and
- disk_config != lc.get('disk_config', 'AUTO')):
- lc_args['disk_config'] = disk_config
-
- if (meta or lc.get('meta')) and meta != lc.get('metadata'):
- lc_args['metadata'] = meta
-
- test_personality = []
- for p in personality:
- test_personality.append({
- 'path': p['path'],
- 'contents': base64.b64encode(p['contents'])
- })
- if ((test_personality or lc.get('personality')) and
- test_personality != lc.get('personality')):
- lc_args['personality'] = personality
-
- if nics != lc.get('networks'):
- lc_args['networks'] = nics
-
- if lbs != lc.get('load_balancers'):
- # Work around for https://github.com/rackspace/pyrax/pull/393
- lc_args['load_balancers'] = sg.manager._resolve_lbs(lbs)
-
- if key_name != lc.get('key_name'):
- lc_args['key_name'] = key_name
-
- if config_drive != lc.get('config_drive', False):
- lc_args['config_drive'] = config_drive
-
- if (user_data and
- base64.b64encode(user_data) != lc.get('user_data')):
- lc_args['user_data'] = user_data
-
- if lc_args:
- # Work around for https://github.com/rackspace/pyrax/pull/389
- if 'flavor' not in lc_args:
- lc_args['flavor'] = lc.get('flavor')
- changed = True
- sg.update_launch_config(**lc_args)
-
- sg.get()
-
- if wait:
- end_time = time.time() + wait_timeout
- infinite = wait_timeout == 0
- while infinite or time.time() < end_time:
- state = sg.get_state()
- if state["pending_capacity"] == 0:
- break
-
- time.sleep(5)
-
- module.exit_json(changed=changed, autoscale_group=rax_to_dict(sg))
-
- else:
- try:
- sg = au.find(name=name)
- sg.delete()
- changed = True
- except pyrax.exceptions.NotFound as e:
- sg = {}
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, autoscale_group=rax_to_dict(sg))
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- config_drive=dict(default=False, type='bool'),
- cooldown=dict(type='int', default=300),
- disk_config=dict(choices=['auto', 'manual']),
- files=dict(type='dict', default={}),
- flavor=dict(required=True),
- image=dict(required=True),
- key_name=dict(),
- loadbalancers=dict(type='list', elements='dict'),
- meta=dict(type='dict', default={}),
- min_entities=dict(type='int', required=True),
- max_entities=dict(type='int', required=True),
- name=dict(required=True),
- networks=dict(type='list', elements='str', default=['public', 'private']),
- server_name=dict(required=True),
- state=dict(default='present', choices=['present', 'absent']),
- user_data=dict(no_log=True),
- wait=dict(default=False, type='bool'),
- wait_timeout=dict(default=300, type='int'),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- config_drive = module.params.get('config_drive')
- cooldown = module.params.get('cooldown')
- disk_config = module.params.get('disk_config')
- if disk_config:
- disk_config = disk_config.upper()
- files = module.params.get('files')
- flavor = module.params.get('flavor')
- image = module.params.get('image')
- key_name = module.params.get('key_name')
- loadbalancers = module.params.get('loadbalancers')
- meta = module.params.get('meta')
- min_entities = module.params.get('min_entities')
- max_entities = module.params.get('max_entities')
- name = module.params.get('name')
- networks = module.params.get('networks')
- server_name = module.params.get('server_name')
- state = module.params.get('state')
- user_data = module.params.get('user_data')
-
- if not 0 <= min_entities <= 1000 or not 0 <= max_entities <= 1000:
- module.fail_json(msg='min_entities and max_entities must be an '
- 'integer between 0 and 1000')
-
- if not 0 <= cooldown <= 86400:
- module.fail_json(msg='cooldown must be an integer between 0 and 86400')
-
- setup_rax_module(module, pyrax)
-
- rax_asg(module, cooldown=cooldown, disk_config=disk_config,
- files=files, flavor=flavor, image=image, meta=meta,
- key_name=key_name, loadbalancers=loadbalancers,
- min_entities=min_entities, max_entities=max_entities,
- name=name, networks=networks, server_name=server_name,
- state=state, config_drive=config_drive, user_data=user_data)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/rax_scaling_policy.py b/ansible_collections/community/general/plugins/modules/rax_scaling_policy.py
deleted file mode 100644
index 2869a6910..000000000
--- a/ansible_collections/community/general/plugins/modules/rax_scaling_policy.py
+++ /dev/null
@@ -1,294 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-module: rax_scaling_policy
-short_description: Manipulate Rackspace Cloud Autoscale Scaling Policy
-description:
- - Manipulate Rackspace Cloud Autoscale Scaling Policy
-attributes:
- check_mode:
- support: none
- diff_mode:
- support: none
-options:
- at:
- type: str
- description:
- - The UTC time when this policy will be executed. The time must be
- formatted according to C(yyyy-MM-dd'T'HH:mm:ss.SSS) such as
- V(2013-05-19T08:07:08Z)
- change:
- type: int
- description:
- - The change, either as a number of servers or as a percentage, to make
- in the scaling group. If this is a percentage, you must set
- O(is_percent) to V(true) also.
- cron:
- type: str
- description:
- - The time when the policy will be executed, as a cron entry. For
- example, if this is parameter is set to V(1 0 * * *).
- cooldown:
- type: int
- description:
- - The period of time, in seconds, that must pass before any scaling can
- occur after the previous scaling. Must be an integer between 0 and
- 86400 (24 hrs).
- default: 300
- desired_capacity:
- type: int
- description:
- - The desired server capacity of the scaling the group; that is, how
- many servers should be in the scaling group.
- is_percent:
- description:
- - Whether the value in O(change) is a percent value
- default: false
- type: bool
- name:
- type: str
- description:
- - Name to give the policy
- required: true
- policy_type:
- type: str
- description:
- - The type of policy that will be executed for the current release.
- choices:
- - webhook
- - schedule
- required: true
- scaling_group:
- type: str
- description:
- - Name of the scaling group that this policy will be added to
- required: true
- state:
- type: str
- description:
- - Indicate desired state of the resource
- choices:
- - present
- - absent
- default: present
-author: "Matt Martz (@sivel)"
-extends_documentation_fragment:
- - community.general.rackspace
- - community.general.rackspace.openstack
- - community.general.attributes
-
-'''
-
-EXAMPLES = '''
----
-- hosts: localhost
- gather_facts: false
- connection: local
- tasks:
- - community.general.rax_scaling_policy:
- credentials: ~/.raxpub
- region: ORD
- at: '2013-05-19T08:07:08Z'
- change: 25
- cooldown: 300
- is_percent: true
- name: ASG Test Policy - at
- policy_type: schedule
- scaling_group: ASG Test
- register: asps_at
-
- - community.general.rax_scaling_policy:
- credentials: ~/.raxpub
- region: ORD
- cron: '1 0 * * *'
- change: 25
- cooldown: 300
- is_percent: true
- name: ASG Test Policy - cron
- policy_type: schedule
- scaling_group: ASG Test
- register: asp_cron
-
- - community.general.rax_scaling_policy:
- credentials: ~/.raxpub
- region: ORD
- cooldown: 300
- desired_capacity: 5
- name: ASG Test Policy - webhook
- policy_type: webhook
- scaling_group: ASG Test
- register: asp_webhook
-'''
-
-try:
- import pyrax
- HAS_PYRAX = True
-except ImportError:
- HAS_PYRAX = False
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.community.general.plugins.module_utils.rax import (UUID, rax_argument_spec, rax_required_together, rax_to_dict,
- setup_rax_module)
-
-
-def rax_asp(module, at=None, change=0, cron=None, cooldown=300,
- desired_capacity=0, is_percent=False, name=None,
- policy_type=None, scaling_group=None, state='present'):
- changed = False
-
- au = pyrax.autoscale
- if not au:
- module.fail_json(msg='Failed to instantiate client. This '
- 'typically indicates an invalid region or an '
- 'incorrectly capitalized region name.')
-
- try:
- UUID(scaling_group)
- except ValueError:
- try:
- sg = au.find(name=scaling_group)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
- else:
- try:
- sg = au.get(scaling_group)
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- if state == 'present':
- policies = filter(lambda p: name == p.name, sg.list_policies())
- if len(policies) > 1:
- module.fail_json(msg='No unique policy match found by name')
- if at:
- args = dict(at=at)
- elif cron:
- args = dict(cron=cron)
- else:
- args = None
-
- if not policies:
- try:
- policy = sg.add_policy(name, policy_type=policy_type,
- cooldown=cooldown, change=change,
- is_percent=is_percent,
- desired_capacity=desired_capacity,
- args=args)
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- else:
- policy = policies[0]
- kwargs = {}
- if policy_type != policy.type:
- kwargs['policy_type'] = policy_type
-
- if cooldown != policy.cooldown:
- kwargs['cooldown'] = cooldown
-
- if hasattr(policy, 'change') and change != policy.change:
- kwargs['change'] = change
-
- if hasattr(policy, 'changePercent') and is_percent is False:
- kwargs['change'] = change
- kwargs['is_percent'] = False
- elif hasattr(policy, 'change') and is_percent is True:
- kwargs['change'] = change
- kwargs['is_percent'] = True
-
- if hasattr(policy, 'desiredCapacity') and change:
- kwargs['change'] = change
- elif ((hasattr(policy, 'change') or
- hasattr(policy, 'changePercent')) and desired_capacity):
- kwargs['desired_capacity'] = desired_capacity
-
- if hasattr(policy, 'args') and args != policy.args:
- kwargs['args'] = args
-
- if kwargs:
- policy.update(**kwargs)
- changed = True
-
- policy.get()
-
- module.exit_json(changed=changed, autoscale_policy=rax_to_dict(policy))
-
- else:
- try:
- policies = filter(lambda p: name == p.name, sg.list_policies())
- if len(policies) > 1:
- module.fail_json(msg='No unique policy match found by name')
- elif not policies:
- policy = {}
- else:
- policy.delete()
- changed = True
- except Exception as e:
- module.fail_json(msg='%s' % e.message)
-
- module.exit_json(changed=changed, autoscale_policy=rax_to_dict(policy))
-
-
-def main():
- argument_spec = rax_argument_spec()
- argument_spec.update(
- dict(
- at=dict(),
- change=dict(type='int'),
- cron=dict(),
- cooldown=dict(type='int', default=300),
- desired_capacity=dict(type='int'),
- is_percent=dict(type='bool', default=False),
- name=dict(required=True),
- policy_type=dict(required=True, choices=['webhook', 'schedule']),
- scaling_group=dict(required=True),
- state=dict(default='present', choices=['present', 'absent']),
- )
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=rax_required_together(),
- mutually_exclusive=[
- ['cron', 'at'],
- ['change', 'desired_capacity'],
- ]
- )
-
- if not HAS_PYRAX:
- module.fail_json(msg='pyrax is required for this module')
-
- at = module.params.get('at')
- change = module.params.get('change')
- cron = module.params.get('cron')
- cooldown = module.params.get('cooldown')
- desired_capacity = module.params.get('desired_capacity')
- is_percent = module.params.get('is_percent')
- name = module.params.get('name')
- policy_type = module.params.get('policy_type')
- scaling_group = module.params.get('scaling_group')
- state = module.params.get('state')
-
- if (at or cron) and policy_type == 'webhook':
- module.fail_json(msg='policy_type=schedule is required for a time '
- 'based policy')
-
- setup_rax_module(module, pyrax)
-
- rax_asp(module, at=at, change=change, cron=cron, cooldown=cooldown,
- desired_capacity=desired_capacity, is_percent=is_percent,
- name=name, policy_type=policy_type, scaling_group=scaling_group,
- state=state)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/redfish_command.py b/ansible_collections/community/general/plugins/modules/redfish_command.py
index 06224235a..d351e7c1d 100644
--- a/ansible_collections/community/general/plugins/modules/redfish_command.py
+++ b/ansible_collections/community/general/plugins/modules/redfish_command.py
@@ -109,9 +109,10 @@ options:
timeout:
description:
- Timeout in seconds for HTTP requests to OOB controller.
- - The default value for this param is C(10) but that is being deprecated
- and it will be replaced with C(60) in community.general 9.0.0.
+ - The default value for this parameter changed from V(10) to V(60)
+ in community.general 9.0.0.
type: int
+ default: 60
boot_override_mode:
description:
- Boot mode when using an override.
@@ -805,7 +806,7 @@ def main():
update_username=dict(type='str', aliases=["account_updatename"]),
account_properties=dict(type='dict', default={}),
bootdevice=dict(),
- timeout=dict(type='int'),
+ timeout=dict(type='int', default=60),
uefi_target=dict(),
boot_next=dict(),
boot_override_mode=dict(choices=['Legacy', 'UEFI']),
@@ -854,16 +855,6 @@ def main():
supports_check_mode=False
)
- if module.params['timeout'] is None:
- timeout = 10
- module.deprecate(
- 'The default value {0} for parameter param1 is being deprecated and it will be replaced by {1}'.format(
- 10, 60
- ),
- version='9.0.0',
- collection_name='community.general'
- )
-
category = module.params['category']
command_list = module.params['command']
diff --git a/ansible_collections/community/general/plugins/modules/redfish_config.py b/ansible_collections/community/general/plugins/modules/redfish_config.py
index 1fea9e7cd..129b33b2e 100644
--- a/ansible_collections/community/general/plugins/modules/redfish_config.py
+++ b/ansible_collections/community/general/plugins/modules/redfish_config.py
@@ -64,9 +64,10 @@ options:
timeout:
description:
- Timeout in seconds for HTTP requests to OOB controller.
- - The default value for this param is C(10) but that is being deprecated
- and it will be replaced with C(60) in community.general 9.0.0.
+ - The default value for this parameter changed from V(10) to V(60)
+ in community.general 9.0.0.
type: int
+ default: 60
boot_order:
required: false
description:
@@ -384,7 +385,7 @@ def main():
password=dict(no_log=True),
auth_token=dict(no_log=True),
bios_attributes=dict(type='dict', default={}),
- timeout=dict(type='int'),
+ timeout=dict(type='int', default=60),
boot_order=dict(type='list', elements='str', default=[]),
network_protocols=dict(
type='dict',
@@ -418,16 +419,6 @@ def main():
supports_check_mode=False
)
- if module.params['timeout'] is None:
- timeout = 10
- module.deprecate(
- 'The default value {0} for parameter param1 is being deprecated and it will be replaced by {1}'.format(
- 10, 60
- ),
- version='9.0.0',
- collection_name='community.general'
- )
-
category = module.params['category']
command_list = module.params['command']
diff --git a/ansible_collections/community/general/plugins/modules/redfish_info.py b/ansible_collections/community/general/plugins/modules/redfish_info.py
index 0b39bb6fa..3b594b7a2 100644
--- a/ansible_collections/community/general/plugins/modules/redfish_info.py
+++ b/ansible_collections/community/general/plugins/modules/redfish_info.py
@@ -63,9 +63,10 @@ options:
timeout:
description:
- Timeout in seconds for HTTP requests to OOB controller.
- - The default value for this param is C(10) but that is being deprecated
- and it will be replaced with C(60) in community.general 9.0.0.
+ - The default value for this parameter changed from V(10) to V(60)
+ in community.general 9.0.0.
type: int
+ default: 60
update_handle:
required: false
description:
@@ -407,7 +408,7 @@ def main():
username=dict(),
password=dict(no_log=True),
auth_token=dict(no_log=True),
- timeout=dict(type='int'),
+ timeout=dict(type='int', default=60),
update_handle=dict(),
manager=dict(),
),
@@ -423,16 +424,6 @@ def main():
supports_check_mode=True,
)
- if module.params['timeout'] is None:
- timeout = 10
- module.deprecate(
- 'The default value {0} for parameter param1 is being deprecated and it will be replaced by {1}'.format(
- 10, 60
- ),
- version='9.0.0',
- collection_name='community.general'
- )
-
# admin credentials used for authentication
creds = {'user': module.params['username'],
'pswd': module.params['password'],
diff --git a/ansible_collections/community/general/plugins/modules/redhat_subscription.py b/ansible_collections/community/general/plugins/modules/redhat_subscription.py
index d4b47d5d5..4a7aac483 100644
--- a/ansible_collections/community/general/plugins/modules/redhat_subscription.py
+++ b/ansible_collections/community/general/plugins/modules/redhat_subscription.py
@@ -123,10 +123,9 @@ options:
description:
- Upon successful registration, auto-consume available subscriptions
- |
- Please note that the alias O(autosubscribe) will be removed in
+ Please note that the alias O(ignore:autosubscribe) was removed in
community.general 9.0.0.
type: bool
- aliases: [autosubscribe]
activationkey:
description:
- supply an activation key for use with registration
@@ -1106,17 +1105,7 @@ def main():
'server_port': {},
'rhsm_baseurl': {},
'rhsm_repo_ca_cert': {},
- 'auto_attach': {
- 'type': 'bool',
- 'aliases': ['autosubscribe'],
- 'deprecated_aliases': [
- {
- 'name': 'autosubscribe',
- 'version': '9.0.0',
- 'collection_name': 'community.general',
- },
- ],
- },
+ 'auto_attach': {'type': 'bool'},
'activationkey': {'no_log': True},
'org_id': {},
'environment': {},
diff --git a/ansible_collections/community/general/plugins/modules/slackpkg.py b/ansible_collections/community/general/plugins/modules/slackpkg.py
index e3d7a1542..9347db159 100644
--- a/ansible_collections/community/general/plugins/modules/slackpkg.py
+++ b/ansible_collections/community/general/plugins/modules/slackpkg.py
@@ -106,9 +106,8 @@ def remove_packages(module, slackpkg_path, packages):
continue
if not module.check_mode:
- rc, out, err = module.run_command("%s -default_answer=y -batch=on \
- remove %s" % (slackpkg_path,
- package))
+ rc, out, err = module.run_command(
+ [slackpkg_path, "-default_answer=y", "-batch=on", "remove", package])
if not module.check_mode and query_package(module, slackpkg_path,
package):
@@ -132,9 +131,8 @@ def install_packages(module, slackpkg_path, packages):
continue
if not module.check_mode:
- rc, out, err = module.run_command("%s -default_answer=y -batch=on \
- install %s" % (slackpkg_path,
- package))
+ rc, out, err = module.run_command(
+ [slackpkg_path, "-default_answer=y", "-batch=on", "install", package])
if not module.check_mode and not query_package(module, slackpkg_path,
package):
@@ -155,9 +153,8 @@ def upgrade_packages(module, slackpkg_path, packages):
for package in packages:
if not module.check_mode:
- rc, out, err = module.run_command("%s -default_answer=y -batch=on \
- upgrade %s" % (slackpkg_path,
- package))
+ rc, out, err = module.run_command(
+ [slackpkg_path, "-default_answer=y", "-batch=on", "upgrade", package])
if not module.check_mode and not query_package(module, slackpkg_path,
package):
@@ -174,7 +171,8 @@ def upgrade_packages(module, slackpkg_path, packages):
def update_cache(module, slackpkg_path):
- rc, out, err = module.run_command("%s -batch=on update" % (slackpkg_path))
+ rc, out, err = module.run_command(
+ [slackpkg_path, "-batch=on", "update"])
if rc != 0:
module.fail_json(msg="Could not update package cache")
diff --git a/ansible_collections/community/general/plugins/modules/snap.py b/ansible_collections/community/general/plugins/modules/snap.py
index fd1676480..16c3aec48 100644
--- a/ansible_collections/community/general/plugins/modules/snap.py
+++ b/ansible_collections/community/general/plugins/modules/snap.py
@@ -194,6 +194,7 @@ class Snap(StateModuleHelper):
},
supports_check_mode=True,
)
+ use_old_vardict = False
@staticmethod
def _first_non_zero(a):
@@ -405,8 +406,8 @@ class Snap(StateModuleHelper):
def state_present(self):
- self.vars.meta('classic').set(output=True)
- self.vars.meta('channel').set(output=True)
+ self.vars.set_meta('classic', output=True)
+ self.vars.set_meta('channel', output=True)
actionable_refresh = [snap for snap in self.vars.name if self.vars.snap_status_map[snap] == Snap.CHANNEL_MISMATCH]
if actionable_refresh:
diff --git a/ansible_collections/community/general/plugins/modules/snap_alias.py b/ansible_collections/community/general/plugins/modules/snap_alias.py
index 54448c6f3..ba54a9e15 100644
--- a/ansible_collections/community/general/plugins/modules/snap_alias.py
+++ b/ansible_collections/community/general/plugins/modules/snap_alias.py
@@ -105,6 +105,7 @@ class SnapAlias(StateModuleHelper):
],
supports_check_mode=True,
)
+ use_old_vardict = False
def _aliases(self):
n = self.vars.name
diff --git a/ansible_collections/community/general/plugins/modules/stackdriver.py b/ansible_collections/community/general/plugins/modules/stackdriver.py
deleted file mode 100644
index 35b2b0dc1..000000000
--- a/ansible_collections/community/general/plugins/modules/stackdriver.py
+++ /dev/null
@@ -1,228 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: stackdriver
-short_description: Send code deploy and annotation events to stackdriver
-description:
- - Send code deploy and annotation events to Stackdriver
-author: "Ben Whaley (@bwhaley)"
-extends_documentation_fragment:
- - community.general.attributes
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-options:
- key:
- type: str
- description:
- - API key.
- required: true
- event:
- type: str
- description:
- - The type of event to send, either annotation or deploy
- choices: ['annotation', 'deploy']
- required: true
- revision_id:
- type: str
- description:
- - The revision of the code that was deployed. Required for deploy events
- deployed_by:
- type: str
- description:
- - The person or robot responsible for deploying the code
- default: "Ansible"
- deployed_to:
- type: str
- description:
- - "The environment code was deployed to. (ie: development, staging, production)"
- repository:
- type: str
- description:
- - The repository (or project) deployed
- msg:
- type: str
- description:
- - The contents of the annotation message, in plain text. Limited to 256 characters. Required for annotation.
- annotated_by:
- type: str
- description:
- - The person or robot who the annotation should be attributed to.
- default: "Ansible"
- level:
- type: str
- description:
- - one of INFO/WARN/ERROR, defaults to INFO if not supplied. May affect display.
- choices: ['INFO', 'WARN', 'ERROR']
- default: 'INFO'
- instance_id:
- type: str
- description:
- - id of an EC2 instance that this event should be attached to, which will limit the contexts where this event is shown
- event_epoch:
- type: str
- description:
- - "Unix timestamp of where the event should appear in the timeline, defaults to now. Be careful with this."
-'''
-
-EXAMPLES = '''
-- name: Send a code deploy event to stackdriver
- community.general.stackdriver:
- key: AAAAAA
- event: deploy
- deployed_to: production
- deployed_by: leeroyjenkins
- repository: MyWebApp
- revision_id: abcd123
-
-- name: Send an annotation event to stackdriver
- community.general.stackdriver:
- key: AAAAAA
- event: annotation
- msg: Greetings from Ansible
- annotated_by: leeroyjenkins
- level: WARN
- instance_id: i-abcd1234
-'''
-
-# ===========================================
-# Stackdriver module specific support methods.
-#
-
-import json
-import traceback
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
-from ansible.module_utils.urls import fetch_url
-
-
-def send_deploy_event(module, key, revision_id, deployed_by='Ansible', deployed_to=None, repository=None):
- """Send a deploy event to Stackdriver"""
- deploy_api = "https://event-gateway.stackdriver.com/v1/deployevent"
-
- params = {}
- params['revision_id'] = revision_id
- params['deployed_by'] = deployed_by
- if deployed_to:
- params['deployed_to'] = deployed_to
- if repository:
- params['repository'] = repository
-
- return do_send_request(module, deploy_api, params, key)
-
-
-def send_annotation_event(module, key, msg, annotated_by='Ansible', level=None, instance_id=None, event_epoch=None):
- """Send an annotation event to Stackdriver"""
- annotation_api = "https://event-gateway.stackdriver.com/v1/annotationevent"
-
- params = {}
- params['message'] = msg
- if annotated_by:
- params['annotated_by'] = annotated_by
- if level:
- params['level'] = level
- if instance_id:
- params['instance_id'] = instance_id
- if event_epoch:
- params['event_epoch'] = event_epoch
-
- return do_send_request(module, annotation_api, params, key)
-
-
-def do_send_request(module, url, params, key):
- data = json.dumps(params)
- headers = {
- 'Content-Type': 'application/json',
- 'x-stackdriver-apikey': key
- }
- response, info = fetch_url(module, url, headers=headers, data=data, method='POST')
- if info['status'] != 200:
- module.fail_json(msg="Unable to send msg: %s" % info['msg'])
-
-
-# ===========================================
-# Module execution.
-#
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict( # @TODO add types
- key=dict(required=True, no_log=True),
- event=dict(required=True, choices=['deploy', 'annotation']),
- msg=dict(),
- revision_id=dict(),
- annotated_by=dict(default='Ansible'),
- level=dict(default='INFO', choices=['INFO', 'WARN', 'ERROR']),
- instance_id=dict(),
- event_epoch=dict(), # @TODO int?
- deployed_by=dict(default='Ansible'),
- deployed_to=dict(),
- repository=dict(),
- ),
- supports_check_mode=True
- )
-
- key = module.params["key"]
- event = module.params["event"]
-
- # Annotation params
- msg = module.params["msg"]
- annotated_by = module.params["annotated_by"]
- level = module.params["level"]
- instance_id = module.params["instance_id"]
- event_epoch = module.params["event_epoch"]
-
- # Deploy params
- revision_id = module.params["revision_id"]
- deployed_by = module.params["deployed_by"]
- deployed_to = module.params["deployed_to"]
- repository = module.params["repository"]
-
- ##################################################################
- # deploy requires revision_id
- # annotation requires msg
- # We verify these manually
- ##################################################################
-
- if event == 'deploy':
- if not revision_id:
- module.fail_json(msg="revision_id required for deploy events")
- try:
- send_deploy_event(module, key, revision_id, deployed_by, deployed_to, repository)
- except Exception as e:
- module.fail_json(msg="unable to sent deploy event: %s" % to_native(e),
- exception=traceback.format_exc())
-
- if event == 'annotation':
- if not msg:
- module.fail_json(msg="msg required for annotation events")
- try:
- send_annotation_event(module, key, msg, annotated_by, level, instance_id, event_epoch)
- except Exception as e:
- module.fail_json(msg="unable to sent annotation event: %s" % to_native(e),
- exception=traceback.format_exc())
-
- changed = True
- module.exit_json(changed=changed, deployed_by=deployed_by)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/svr4pkg.py b/ansible_collections/community/general/plugins/modules/svr4pkg.py
index db9902c77..56ded66e6 100644
--- a/ansible_collections/community/general/plugins/modules/svr4pkg.py
+++ b/ansible_collections/community/general/plugins/modules/svr4pkg.py
@@ -120,7 +120,7 @@ def package_installed(module, name, category):
if category:
cmd.append('-c')
cmd.append(name)
- rc, out, err = module.run_command(' '.join(cmd))
+ rc, out, err = module.run_command(cmd)
if rc == 0:
return True
else:
diff --git a/ansible_collections/community/general/plugins/modules/swdepot.py b/ansible_collections/community/general/plugins/modules/swdepot.py
index 28a8ce314..9ba1b02b3 100644
--- a/ansible_collections/community/general/plugins/modules/swdepot.py
+++ b/ansible_collections/community/general/plugins/modules/swdepot.py
@@ -68,7 +68,6 @@ EXAMPLES = '''
import re
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves import shlex_quote
def compare_package(version1, version2):
@@ -94,13 +93,13 @@ def compare_package(version1, version2):
def query_package(module, name, depot=None):
""" Returns whether a package is installed or not and version. """
- cmd_list = '/usr/sbin/swlist -a revision -l product'
+ cmd_list = ['/usr/sbin/swlist', '-a', 'revision', '-l', 'product']
if depot:
- rc, stdout, stderr = module.run_command("%s -s %s %s | grep %s" % (cmd_list, shlex_quote(depot), shlex_quote(name), shlex_quote(name)),
- use_unsafe_shell=True)
- else:
- rc, stdout, stderr = module.run_command("%s %s | grep %s" % (cmd_list, shlex_quote(name), shlex_quote(name)), use_unsafe_shell=True)
+ cmd_list.extend(['-s', depot])
+ cmd_list.append(name)
+ rc, stdout, stderr = module.run_command(cmd_list)
if rc == 0:
+ stdout = ''.join(line for line in stdout.splitlines(True) if name in line)
version = re.sub(r"\s\s+|\t", " ", stdout).strip().split()[1]
else:
version = None
@@ -112,7 +111,7 @@ def remove_package(module, name):
""" Uninstall package if installed. """
cmd_remove = '/usr/sbin/swremove'
- rc, stdout, stderr = module.run_command("%s %s" % (cmd_remove, name))
+ rc, stdout, stderr = module.run_command([cmd_remove, name])
if rc == 0:
return rc, stdout
@@ -123,8 +122,8 @@ def remove_package(module, name):
def install_package(module, depot, name):
""" Install package if not already installed """
- cmd_install = '/usr/sbin/swinstall -x mount_all_filesystems=false'
- rc, stdout, stderr = module.run_command("%s -s %s %s" % (cmd_install, depot, name))
+ cmd_install = ['/usr/sbin/swinstall', '-x', 'mount_all_filesystems=false']
+ rc, stdout, stderr = module.run_command(cmd_install + ["-s", depot, name])
if rc == 0:
return rc, stdout
else:
diff --git a/ansible_collections/community/general/plugins/modules/webfaction_app.py b/ansible_collections/community/general/plugins/modules/webfaction_app.py
deleted file mode 100644
index 81bfc8b68..000000000
--- a/ansible_collections/community/general/plugins/modules/webfaction_app.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2015, Quentin Stafford-Fraser, with contributions gratefully acknowledged from:
-# * Andy Baker
-# * Federico Tarantini
-#
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Create a Webfaction application using Ansible and the Webfaction API
-#
-# Valid application types can be found by looking here:
-# https://docs.webfaction.com/xmlrpc-api/apps.html#application-types
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: webfaction_app
-short_description: Add or remove applications on a Webfaction host
-description:
- - Add or remove applications on a Webfaction host. Further documentation at U(https://github.com/quentinsf/ansible-webfaction).
-author: Quentin Stafford-Fraser (@quentinsf)
-notes:
- - >
- You can run playbooks that use this on a local machine, or on a Webfaction host, or elsewhere, since the scripts use the remote webfaction API.
- The location is not important. However, running them on multiple hosts I(simultaneously) is best avoided. If you do not specify C(localhost) as
- your host, you may want to add C(serial=1) to the plays.
- - See L(the webfaction API, https://docs.webfaction.com/xmlrpc-api/) for more info.
-
-extends_documentation_fragment:
- - community.general.attributes
-
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-
-options:
- name:
- description:
- - The name of the application
- required: true
- type: str
-
- state:
- description:
- - Whether the application should exist
- choices: ['present', 'absent']
- default: "present"
- type: str
-
- type:
- description:
- - The type of application to create. See the Webfaction docs at U(https://docs.webfaction.com/xmlrpc-api/apps.html) for a list.
- required: true
- type: str
-
- autostart:
- description:
- - Whether the app should restart with an C(autostart.cgi) script
- type: bool
- default: false
-
- extra_info:
- description:
- - Any extra parameters required by the app
- default: ''
- type: str
-
- port_open:
- description:
- - IF the port should be opened
- type: bool
- default: false
-
- login_name:
- description:
- - The webfaction account to use
- required: true
- type: str
-
- login_password:
- description:
- - The webfaction password to use
- required: true
- type: str
-
- machine:
- description:
- - The machine name to use (optional for accounts with only one machine)
- type: str
-
-'''
-
-EXAMPLES = '''
- - name: Create a test app
- community.general.webfaction_app:
- name: "my_wsgi_app1"
- state: present
- type: mod_wsgi35-python27
- login_name: "{{webfaction_user}}"
- login_password: "{{webfaction_passwd}}"
- machine: "{{webfaction_machine}}"
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves import xmlrpc_client
-
-
-webfaction = xmlrpc_client.ServerProxy('https://api.webfaction.com/')
-
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict(
- name=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- type=dict(required=True),
- autostart=dict(type='bool', default=False),
- extra_info=dict(default=""),
- port_open=dict(type='bool', default=False),
- login_name=dict(required=True),
- login_password=dict(required=True, no_log=True),
- machine=dict(),
- ),
- supports_check_mode=True
- )
- app_name = module.params['name']
- app_type = module.params['type']
- app_state = module.params['state']
-
- if module.params['machine']:
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password'],
- module.params['machine']
- )
- else:
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password']
- )
-
- app_list = webfaction.list_apps(session_id)
- app_map = dict([(i['name'], i) for i in app_list])
- existing_app = app_map.get(app_name)
-
- result = {}
-
- # Here's where the real stuff happens
-
- if app_state == 'present':
-
- # Does an app with this name already exist?
- if existing_app:
- if existing_app['type'] != app_type:
- module.fail_json(msg="App already exists with different type. Please fix by hand.")
-
- # If it exists with the right type, we don't change it
- # Should check other parameters.
- module.exit_json(
- changed=False,
- result=existing_app,
- )
-
- if not module.check_mode:
- # If this isn't a dry run, create the app
- result.update(
- webfaction.create_app(
- session_id, app_name, app_type,
- module.boolean(module.params['autostart']),
- module.params['extra_info'],
- module.boolean(module.params['port_open'])
- )
- )
-
- elif app_state == 'absent':
-
- # If the app's already not there, nothing changed.
- if not existing_app:
- module.exit_json(
- changed=False,
- )
-
- if not module.check_mode:
- # If this isn't a dry run, delete the app
- result.update(
- webfaction.delete_app(session_id, app_name)
- )
-
- else:
- module.fail_json(msg="Unknown state specified: {0}".format(app_state))
-
- module.exit_json(
- changed=True,
- result=result
- )
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/webfaction_db.py b/ansible_collections/community/general/plugins/modules/webfaction_db.py
deleted file mode 100644
index 5428de5b6..000000000
--- a/ansible_collections/community/general/plugins/modules/webfaction_db.py
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2015, Quentin Stafford-Fraser, with contributions gratefully acknowledged from:
-# * Andy Baker
-# * Federico Tarantini
-#
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Create a webfaction database using Ansible and the Webfaction API
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: webfaction_db
-short_description: Add or remove a database on Webfaction
-description:
- - Add or remove a database on a Webfaction host. Further documentation at https://github.com/quentinsf/ansible-webfaction.
-author: Quentin Stafford-Fraser (@quentinsf)
-notes:
- - >
- You can run playbooks that use this on a local machine, or on a Webfaction host, or elsewhere, since the scripts use the remote webfaction API.
- The location is not important. However, running them on multiple hosts I(simultaneously) is best avoided. If you do not specify C(localhost) as
- your host, you may want to add C(serial=1) to the plays.
- - See L(the webfaction API, https://docs.webfaction.com/xmlrpc-api/) for more info.
-extends_documentation_fragment:
- - community.general.attributes
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-options:
-
- name:
- description:
- - The name of the database
- required: true
- type: str
-
- state:
- description:
- - Whether the database should exist
- choices: ['present', 'absent']
- default: "present"
- type: str
-
- type:
- description:
- - The type of database to create.
- required: true
- choices: ['mysql', 'postgresql']
- type: str
-
- password:
- description:
- - The password for the new database user.
- type: str
-
- login_name:
- description:
- - The webfaction account to use
- required: true
- type: str
-
- login_password:
- description:
- - The webfaction password to use
- required: true
- type: str
-
- machine:
- description:
- - The machine name to use (optional for accounts with only one machine)
- type: str
-'''
-
-EXAMPLES = '''
- # This will also create a default DB user with the same
- # name as the database, and the specified password.
-
- - name: Create a database
- community.general.webfaction_db:
- name: "{{webfaction_user}}_db1"
- password: mytestsql
- type: mysql
- login_name: "{{webfaction_user}}"
- login_password: "{{webfaction_passwd}}"
- machine: "{{webfaction_machine}}"
-
- # Note that, for symmetry's sake, deleting a database using
- # 'state: absent' will also delete the matching user.
-
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves import xmlrpc_client
-
-
-webfaction = xmlrpc_client.ServerProxy('https://api.webfaction.com/')
-
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict(
- name=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- # You can specify an IP address or hostname.
- type=dict(required=True, choices=['mysql', 'postgresql']),
- password=dict(no_log=True),
- login_name=dict(required=True),
- login_password=dict(required=True, no_log=True),
- machine=dict(),
- ),
- supports_check_mode=True
- )
- db_name = module.params['name']
- db_state = module.params['state']
- db_type = module.params['type']
- db_passwd = module.params['password']
-
- if module.params['machine']:
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password'],
- module.params['machine']
- )
- else:
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password']
- )
-
- db_list = webfaction.list_dbs(session_id)
- db_map = dict([(i['name'], i) for i in db_list])
- existing_db = db_map.get(db_name)
-
- user_list = webfaction.list_db_users(session_id)
- user_map = dict([(i['username'], i) for i in user_list])
- existing_user = user_map.get(db_name)
-
- result = {}
-
- # Here's where the real stuff happens
-
- if db_state == 'present':
-
- # Does a database with this name already exist?
- if existing_db:
- # Yes, but of a different type - fail
- if existing_db['db_type'] != db_type:
- module.fail_json(msg="Database already exists but is a different type. Please fix by hand.")
-
- # If it exists with the right type, we don't change anything.
- module.exit_json(
- changed=False,
- )
-
- if not module.check_mode:
- # If this isn't a dry run, create the db
- # and default user.
- result.update(
- webfaction.create_db(
- session_id, db_name, db_type, db_passwd
- )
- )
-
- elif db_state == 'absent':
-
- # If this isn't a dry run...
- if not module.check_mode:
-
- if not (existing_db or existing_user):
- module.exit_json(changed=False,)
-
- if existing_db:
- # Delete the db if it exists
- result.update(
- webfaction.delete_db(session_id, db_name, db_type)
- )
-
- if existing_user:
- # Delete the default db user if it exists
- result.update(
- webfaction.delete_db_user(session_id, db_name, db_type)
- )
-
- else:
- module.fail_json(msg="Unknown state specified: {0}".format(db_state))
-
- module.exit_json(
- changed=True,
- result=result
- )
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/webfaction_domain.py b/ansible_collections/community/general/plugins/modules/webfaction_domain.py
deleted file mode 100644
index 4c87a539a..000000000
--- a/ansible_collections/community/general/plugins/modules/webfaction_domain.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2015, Quentin Stafford-Fraser
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Create Webfaction domains and subdomains using Ansible and the Webfaction API
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: webfaction_domain
-short_description: Add or remove domains and subdomains on Webfaction
-description:
- - Add or remove domains or subdomains on a Webfaction host. Further documentation at https://github.com/quentinsf/ansible-webfaction.
-author: Quentin Stafford-Fraser (@quentinsf)
-notes:
- - If you are I(deleting) domains by using O(state=absent), then note that if you specify subdomains, just those particular subdomains will be deleted.
- If you do not specify subdomains, the domain will be deleted.
- - >
- You can run playbooks that use this on a local machine, or on a Webfaction host, or elsewhere, since the scripts use the remote webfaction API.
- The location is not important. However, running them on multiple hosts I(simultaneously) is best avoided. If you do not specify C(localhost) as
- your host, you may want to add C(serial=1) to the plays.
- - See L(the webfaction API, https://docs.webfaction.com/xmlrpc-api/) for more info.
-
-extends_documentation_fragment:
- - community.general.attributes
-
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-
-options:
-
- name:
- description:
- - The name of the domain
- required: true
- type: str
-
- state:
- description:
- - Whether the domain should exist
- choices: ['present', 'absent']
- default: "present"
- type: str
-
- subdomains:
- description:
- - Any subdomains to create.
- default: []
- type: list
- elements: str
-
- login_name:
- description:
- - The webfaction account to use
- required: true
- type: str
-
- login_password:
- description:
- - The webfaction password to use
- required: true
- type: str
-'''
-
-EXAMPLES = '''
- - name: Create a test domain
- community.general.webfaction_domain:
- name: mydomain.com
- state: present
- subdomains:
- - www
- - blog
- login_name: "{{webfaction_user}}"
- login_password: "{{webfaction_passwd}}"
-
- - name: Delete test domain and any subdomains
- community.general.webfaction_domain:
- name: mydomain.com
- state: absent
- login_name: "{{webfaction_user}}"
- login_password: "{{webfaction_passwd}}"
-
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves import xmlrpc_client
-
-
-webfaction = xmlrpc_client.ServerProxy('https://api.webfaction.com/')
-
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict(
- name=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- subdomains=dict(default=[], type='list', elements='str'),
- login_name=dict(required=True),
- login_password=dict(required=True, no_log=True),
- ),
- supports_check_mode=True
- )
- domain_name = module.params['name']
- domain_state = module.params['state']
- domain_subdomains = module.params['subdomains']
-
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password']
- )
-
- domain_list = webfaction.list_domains(session_id)
- domain_map = dict([(i['domain'], i) for i in domain_list])
- existing_domain = domain_map.get(domain_name)
-
- result = {}
-
- # Here's where the real stuff happens
-
- if domain_state == 'present':
-
- # Does an app with this name already exist?
- if existing_domain:
-
- if set(existing_domain['subdomains']) >= set(domain_subdomains):
- # If it exists with the right subdomains, we don't change anything.
- module.exit_json(
- changed=False,
- )
-
- positional_args = [session_id, domain_name] + domain_subdomains
-
- if not module.check_mode:
- # If this isn't a dry run, create the app
- # print positional_args
- result.update(
- webfaction.create_domain(
- *positional_args
- )
- )
-
- elif domain_state == 'absent':
-
- # If the app's already not there, nothing changed.
- if not existing_domain:
- module.exit_json(
- changed=False,
- )
-
- positional_args = [session_id, domain_name] + domain_subdomains
-
- if not module.check_mode:
- # If this isn't a dry run, delete the app
- result.update(
- webfaction.delete_domain(*positional_args)
- )
-
- else:
- module.fail_json(msg="Unknown state specified: {0}".format(domain_state))
-
- module.exit_json(
- changed=True,
- result=result
- )
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/webfaction_mailbox.py b/ansible_collections/community/general/plugins/modules/webfaction_mailbox.py
deleted file mode 100644
index 119dfd283..000000000
--- a/ansible_collections/community/general/plugins/modules/webfaction_mailbox.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2015, Quentin Stafford-Fraser and Andy Baker
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Create webfaction mailbox using Ansible and the Webfaction API
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: webfaction_mailbox
-short_description: Add or remove mailboxes on Webfaction
-description:
- - Add or remove mailboxes on a Webfaction account. Further documentation at https://github.com/quentinsf/ansible-webfaction.
-author: Quentin Stafford-Fraser (@quentinsf)
-notes:
- - >
- You can run playbooks that use this on a local machine, or on a Webfaction host, or elsewhere, since the scripts use the remote webfaction API.
- The location is not important. However, running them on multiple hosts I(simultaneously) is best avoided. If you do not specify C(localhost) as
- your host, you may want to add C(serial=1) to the plays.
- - See L(the webfaction API, https://docs.webfaction.com/xmlrpc-api/) for more info.
-
-extends_documentation_fragment:
- - community.general.attributes
-
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-
-options:
-
- mailbox_name:
- description:
- - The name of the mailbox
- required: true
- type: str
-
- mailbox_password:
- description:
- - The password for the mailbox
- required: true
- type: str
-
- state:
- description:
- - Whether the mailbox should exist
- choices: ['present', 'absent']
- default: "present"
- type: str
-
- login_name:
- description:
- - The webfaction account to use
- required: true
- type: str
-
- login_password:
- description:
- - The webfaction password to use
- required: true
- type: str
-'''
-
-EXAMPLES = '''
- - name: Create a mailbox
- community.general.webfaction_mailbox:
- mailbox_name="mybox"
- mailbox_password="myboxpw"
- state=present
- login_name={{webfaction_user}}
- login_password={{webfaction_passwd}}
-'''
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves import xmlrpc_client
-
-
-webfaction = xmlrpc_client.ServerProxy('https://api.webfaction.com/')
-
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict(
- mailbox_name=dict(required=True),
- mailbox_password=dict(required=True, no_log=True),
- state=dict(required=False, choices=['present', 'absent'], default='present'),
- login_name=dict(required=True),
- login_password=dict(required=True, no_log=True),
- ),
- supports_check_mode=True
- )
-
- mailbox_name = module.params['mailbox_name']
- site_state = module.params['state']
-
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password']
- )
-
- mailbox_list = [x['mailbox'] for x in webfaction.list_mailboxes(session_id)]
- existing_mailbox = mailbox_name in mailbox_list
-
- result = {}
-
- # Here's where the real stuff happens
-
- if site_state == 'present':
-
- # Does a mailbox with this name already exist?
- if existing_mailbox:
- module.exit_json(changed=False,)
-
- positional_args = [session_id, mailbox_name]
-
- if not module.check_mode:
- # If this isn't a dry run, create the mailbox
- result.update(webfaction.create_mailbox(*positional_args))
-
- elif site_state == 'absent':
-
- # If the mailbox is already not there, nothing changed.
- if not existing_mailbox:
- module.exit_json(changed=False)
-
- if not module.check_mode:
- # If this isn't a dry run, delete the mailbox
- result.update(webfaction.delete_mailbox(session_id, mailbox_name))
-
- else:
- module.fail_json(msg="Unknown state specified: {0}".format(site_state))
-
- module.exit_json(changed=True, result=result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/webfaction_site.py b/ansible_collections/community/general/plugins/modules/webfaction_site.py
deleted file mode 100644
index 7795c45fe..000000000
--- a/ansible_collections/community/general/plugins/modules/webfaction_site.py
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2015, Quentin Stafford-Fraser
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Create Webfaction website using Ansible and the Webfaction API
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-DOCUMENTATION = '''
----
-
-deprecated:
- removed_in: 9.0.0
- why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
- alternative: no known alternative at this point
-
-module: webfaction_site
-short_description: Add or remove a website on a Webfaction host
-description:
- - Add or remove a website on a Webfaction host. Further documentation at https://github.com/quentinsf/ansible-webfaction.
-author: Quentin Stafford-Fraser (@quentinsf)
-notes:
- - Sadly, you I(do) need to know your webfaction hostname for the C(host) parameter. But at least, unlike the API, you do not need to know the IP
- address. You can use a DNS name.
- - If a site of the same name exists in the account but on a different host, the operation will exit.
- - >
- You can run playbooks that use this on a local machine, or on a Webfaction host, or elsewhere, since the scripts use the remote webfaction API.
- The location is not important. However, running them on multiple hosts I(simultaneously) is best avoided. If you do not specify C(localhost) as
- your host, you may want to add C(serial=1) to the plays.
- - See L(the webfaction API, https://docs.webfaction.com/xmlrpc-api/) for more info.
-
-extends_documentation_fragment:
- - community.general.attributes
-
-attributes:
- check_mode:
- support: full
- diff_mode:
- support: none
-
-options:
-
- name:
- description:
- - The name of the website
- required: true
- type: str
-
- state:
- description:
- - Whether the website should exist
- choices: ['present', 'absent']
- default: "present"
- type: str
-
- host:
- description:
- - The webfaction host on which the site should be created.
- required: true
- type: str
-
- https:
- description:
- - Whether or not to use HTTPS
- type: bool
- default: false
-
- site_apps:
- description:
- - A mapping of URLs to apps
- default: []
- type: list
- elements: list
-
- subdomains:
- description:
- - A list of subdomains associated with this site.
- default: []
- type: list
- elements: str
-
- login_name:
- description:
- - The webfaction account to use
- required: true
- type: str
-
- login_password:
- description:
- - The webfaction password to use
- required: true
- type: str
-'''
-
-EXAMPLES = '''
- - name: Create website
- community.general.webfaction_site:
- name: testsite1
- state: present
- host: myhost.webfaction.com
- subdomains:
- - 'testsite1.my_domain.org'
- site_apps:
- - ['testapp1', '/']
- https: false
- login_name: "{{webfaction_user}}"
- login_password: "{{webfaction_passwd}}"
-'''
-
-import socket
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six.moves import xmlrpc_client
-
-
-webfaction = xmlrpc_client.ServerProxy('https://api.webfaction.com/')
-
-
-def main():
-
- module = AnsibleModule(
- argument_spec=dict(
- name=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- # You can specify an IP address or hostname.
- host=dict(required=True),
- https=dict(required=False, type='bool', default=False),
- subdomains=dict(type='list', elements='str', default=[]),
- site_apps=dict(type='list', elements='list', default=[]),
- login_name=dict(required=True),
- login_password=dict(required=True, no_log=True),
- ),
- supports_check_mode=True
- )
- site_name = module.params['name']
- site_state = module.params['state']
- site_host = module.params['host']
- site_ip = socket.gethostbyname(site_host)
-
- session_id, account = webfaction.login(
- module.params['login_name'],
- module.params['login_password']
- )
-
- site_list = webfaction.list_websites(session_id)
- site_map = dict([(i['name'], i) for i in site_list])
- existing_site = site_map.get(site_name)
-
- result = {}
-
- # Here's where the real stuff happens
-
- if site_state == 'present':
-
- # Does a site with this name already exist?
- if existing_site:
-
- # If yes, but it's on a different IP address, then fail.
- # If we wanted to allow relocation, we could add a 'relocate=true' option
- # which would get the existing IP address, delete the site there, and create it
- # at the new address. A bit dangerous, perhaps, so for now we'll require manual
- # deletion if it's on another host.
-
- if existing_site['ip'] != site_ip:
- module.fail_json(msg="Website already exists with a different IP address. Please fix by hand.")
-
- # If it's on this host and the key parameters are the same, nothing needs to be done.
-
- if (existing_site['https'] == module.boolean(module.params['https'])) and \
- (set(existing_site['subdomains']) == set(module.params['subdomains'])) and \
- (dict(existing_site['website_apps']) == dict(module.params['site_apps'])):
- module.exit_json(
- changed=False
- )
-
- positional_args = [
- session_id, site_name, site_ip,
- module.boolean(module.params['https']),
- module.params['subdomains'],
- ]
- for a in module.params['site_apps']:
- positional_args.append((a[0], a[1]))
-
- if not module.check_mode:
- # If this isn't a dry run, create or modify the site
- result.update(
- webfaction.create_website(
- *positional_args
- ) if not existing_site else webfaction.update_website(
- *positional_args
- )
- )
-
- elif site_state == 'absent':
-
- # If the site's already not there, nothing changed.
- if not existing_site:
- module.exit_json(
- changed=False,
- )
-
- if not module.check_mode:
- # If this isn't a dry run, delete the site
- result.update(
- webfaction.delete_website(session_id, site_name, site_ip)
- )
-
- else:
- module.fail_json(msg="Unknown state specified: {0}".format(site_state))
-
- module.exit_json(
- changed=True,
- result=result
- )
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/general/plugins/modules/xfconf.py b/ansible_collections/community/general/plugins/modules/xfconf.py
index 8ed44c675..15943ae59 100644
--- a/ansible_collections/community/general/plugins/modules/xfconf.py
+++ b/ansible_collections/community/general/plugins/modules/xfconf.py
@@ -187,6 +187,7 @@ class XFConfProperty(StateModuleHelper):
required_together=[('value', 'value_type')],
supports_check_mode=True,
)
+ use_old_vardict = False
default_state = 'present'
@@ -196,7 +197,7 @@ class XFConfProperty(StateModuleHelper):
self.vars.channel)
self.vars.set('previous_value', self._get())
self.vars.set('type', self.vars.value_type)
- self.vars.meta('value').set(initial_value=self.vars.previous_value)
+ self.vars.set_meta('value', initial_value=self.vars.previous_value)
def process_command_output(self, rc, out, err):
if err.rstrip() == self.does_not:
diff --git a/ansible_collections/community/general/plugins/modules/xfconf_info.py b/ansible_collections/community/general/plugins/modules/xfconf_info.py
index 844ef3c11..3d56a70cb 100644
--- a/ansible_collections/community/general/plugins/modules/xfconf_info.py
+++ b/ansible_collections/community/general/plugins/modules/xfconf_info.py
@@ -139,6 +139,7 @@ class XFConfInfo(ModuleHelper):
),
supports_check_mode=True,
)
+ use_old_vardict = False
def __init_module__(self):
self.runner = xfconf_runner(self.module, check_rc=True)
@@ -176,7 +177,7 @@ class XFConfInfo(ModuleHelper):
proc = self._process_list_properties
with self.runner.context('list_arg channel property', output_process=proc) as ctx:
- result = ctx.run(**self.vars)
+ result = ctx.run(**self.vars.as_dict())
if not self.vars.list_arg and self.vars.is_array:
output = "value_array"
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_timestamp/aliases b/ansible_collections/community/general/tests/integration/targets/callback_timestamp/aliases
new file mode 100644
index 000000000..124adcfb8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_timestamp/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2024, kurokobo <kurokobo@protonmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or <https://www.gnu.org/licenses/gpl-3.0.txt>)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/target/callback
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_timestamp/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/callback_timestamp/tasks/main.yml
new file mode 100644
index 000000000..5e0acc15f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_timestamp/tasks/main.yml
@@ -0,0 +1,66 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2024, kurokobo <kurokobo@protonmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Run tests
+ include_role:
+ name: callback
+ vars:
+ tests:
+ - name: Enable timestamp in the default length
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.timestamp
+ ANSIBLE_CALLBACK_TIMESTAMP_FORMAT_STRING: "15:04:05"
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "",
+ "PLAY [testhost] ******************************************************* 15:04:05",
+ "",
+ "TASK [Sample task name] *********************************************** 15:04:05",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP ************************************************************ 15:04:05",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Enable timestamp in the longer length
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.timestamp
+ ANSIBLE_CALLBACK_TIMESTAMP_FORMAT_STRING: "2006-01-02T15:04:05"
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "",
+ "PLAY [testhost] ******************************************** 2006-01-02T15:04:05",
+ "",
+ "TASK [Sample task name] ************************************ 2006-01-02T15:04:05",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP ************************************************* 2006-01-02T15:04:05",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
diff --git a/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml
index c9adc1ca6..89650154f 100644
--- a/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml
@@ -6,7 +6,8 @@
- name: bail out for non-supported platforms
meta: end_play
when:
- - (ansible_os_family != "RedHat" or ansible_distribution_major_version|int < 7)
+ - (ansible_os_family != "RedHat" or ansible_distribution_major_version|int < 8) # TODO: bump back to 7
+ - (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int < 8) # TODO: remove
- ansible_os_family != "Debian"
- name: install perl development package for Red Hat family
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml b/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml
index c07b53893..5307fb664 100644
--- a/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml
@@ -43,6 +43,11 @@
chdir: "{{ tmp_django_root.path }}/startproj"
cmd: "{{ tmp_django_root.path }}/venv/bin/django-admin startapp app1"
+- name: Make manage.py executable
+ file:
+ path: "{{ tmp_django_root.path }}/startproj/test_django_manage_1/manage.py"
+ mode: "0755"
+
- name: Check
community.general.django_manage:
project_path: "{{ tmp_django_root.path }}/startproj/test_django_manage_1"
diff --git a/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml
index 33e07b785..349b3f952 100644
--- a/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml
@@ -10,7 +10,8 @@
- name: Bail out if not supported
ansible.builtin.meta: end_play
- when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora')
+ # TODO: remove Archlinux from the list
+ when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora', 'Archlinux')
- name: Remove ejabberd
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml
index c3f1c1798..87056aa86 100644
--- a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml
@@ -45,10 +45,10 @@
assert:
that:
- result is changed
- - result.record['values'] == {{ item['values'] }}
- - result.record.record == "{{ item.record }}"
- - result.record.type == "{{ item.type }}"
- - result.record.ttl == {{ item.ttl }}
+ - result.record['values'] == item['values']
+ - result.record.record == item.record
+ - result.record.type == item.type
+ - result.record.ttl == item.ttl
- name: test create a dns record idempotence
community.general.gandi_livedns:
@@ -63,7 +63,16 @@
assert:
that:
- result is not changed
- - result.record['values'] == {{ item['values'] }}
- - result.record.record == "{{ item.record }}"
- - result.record.type == "{{ item.type }}"
- - result.record.ttl == {{ item.ttl }}
+ - result.record['values'] == item['values']
+ - result.record.record == item.record
+ - result.record.type == item.type
+ - result.record.ttl == item.ttl
+
+- name: test create a DNS record with personal access token
+ community.general.gandi_livedns:
+ personal_access_token: "{{ gandi_personal_access_token }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item['values'] }}"
+ ttl: "{{ item.ttl }}"
+ type: "{{ item.type }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml
index a080560a7..5f19bfa24 100644
--- a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml
@@ -17,10 +17,10 @@
assert:
that:
- result is changed
- - result.record['values'] == {{ item.update_values | default(item['values']) }}
- - result.record.record == "{{ item.record }}"
- - result.record.type == "{{ item.type }}"
- - result.record.ttl == {{ item.update_ttl | default(item.ttl) }}
+ - result.record['values'] == (item.update_values | default(item['values']))
+ - result.record.record == item.record
+ - result.record.type == item.type
+ - result.record.ttl == (item.update_ttl | default(item.ttl))
- name: test update or add another dns record
community.general.gandi_livedns:
@@ -35,10 +35,10 @@
assert:
that:
- result is changed
- - result.record['values'] == {{ item.update_values | default(item['values']) }}
- - result.record.record == "{{ item.record }}"
- - result.record.ttl == {{ item.update_ttl | default(item.ttl) }}
- - result.record.type == "{{ item.type }}"
+ - result.record['values'] == (item.update_values | default(item['values']))
+ - result.record.record == item.record
+ - result.record.ttl == (item.update_ttl | default(item.ttl))
+ - result.record.type == item.type
- name: test update or add another dns record idempotence
community.general.gandi_livedns:
@@ -53,7 +53,7 @@
assert:
that:
- result is not changed
- - result.record['values'] == {{ item.update_values | default(item['values']) }}
- - result.record.record == "{{ item.record }}"
- - result.record.ttl == {{ item.update_ttl | default(item.ttl) }}
- - result.record.type == "{{ item.type }}"
+ - result.record['values'] == (item.update_values | default(item['values']))
+ - result.record.record == item.record
+ - result.record.ttl == (item.update_ttl | default(item.ttl))
+ - result.record.type == item.type
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/handlers/main.yml
new file mode 100644
index 000000000..90a2e8017
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/handlers/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall docker
+ community.general.homebrew:
+ name: docker
+ state: absent
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml
index 42d3515bf..ffbe67d15 100644
--- a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml
@@ -12,13 +12,11 @@
- name: Find brew binary
command: which brew
register: brew_which
- when: ansible_distribution in ['MacOSX']
- name: Get owner of brew binary
stat:
path: "{{ brew_which.stdout }}"
register: brew_stat
- when: ansible_distribution in ['MacOSX']
#- name: Use ignored-pinned option while upgrading all
# homebrew:
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/docker.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/docker.yml
new file mode 100644
index 000000000..c7f282ba2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/docker.yml
@@ -0,0 +1,23 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: MACOS | Find brew binary
+ command: which brew
+ register: brew_which
+
+- name: MACOS | Get owner of brew binary
+ stat:
+ path: "{{ brew_which.stdout }}"
+ register: brew_stat
+
+- name: MACOS | Install docker
+ community.general.homebrew:
+ name: docker
+ state: present
+ force_formula: true
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ notify:
+ - uninstall docker
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml
index 1db3ef1a6..1ca8d753e 100644
--- a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml
@@ -12,13 +12,11 @@
- name: Find brew binary
command: which brew
register: brew_which
- when: ansible_distribution in ['MacOSX']
- name: Get owner of brew binary
stat:
path: "{{ brew_which.stdout }}"
register: brew_stat
- when: ansible_distribution in ['MacOSX']
#- name: Use ignored-pinned option while upgrading all
# homebrew:
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
index f5479917e..00d0bcf31 100644
--- a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
@@ -9,9 +9,8 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
-- block:
- - include_tasks: 'formulae.yml'
-
- when: ansible_distribution in ['MacOSX']
block:
+ - include_tasks: 'formulae.yml'
- include_tasks: 'casks.yml'
+ - include_tasks: 'docker.yml'
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml
index afad9740e..fa118ed1d 100644
--- a/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml
@@ -62,6 +62,7 @@
- result.existing == {}
- result.end_state.alias == "{{ idp }}"
- result.end_state.mappers != []
+ - result.end_state.config.client_secret = "**********"
- name: Update existing identity provider (no change)
community.general.keycloak_identity_provider:
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh
index 4e66476be..ada6908dd 100755
--- a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh
@@ -14,3 +14,6 @@ ANSIBLE_MERGE_VARIABLES_PATTERN_TYPE=suffix \
ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
ansible-playbook -i test_inventory_all_hosts.yml test_all_hosts.yml "$@"
+
+ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
+ ansible-playbook -i test_cross_host_merge_inventory.yml test_cross_host_merge_play.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_inventory.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_inventory.yml
new file mode 100644
index 000000000..938457023
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_inventory.yml
@@ -0,0 +1,33 @@
+---
+# Copyright (c) 2020, Thales Netherlands
+# Copyright (c) 2021, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+common:
+ vars:
+ provider_instances:
+ servicedata1:
+ host: "{{ hostvars[groups['provider'] | first].inventory_hostname }}"
+ user: usr
+ pass: pwd
+ servicedata2:
+ host: down
+ user: usr2
+ pass: pwd2
+ hosts:
+ host1:
+ host2:
+
+consumer:
+ vars:
+ service_data: "{{ provider_instances.servicedata1 }}"
+ merge2__1: "{{ service_data }}" # service_data is a variable only known to host2, so normally it´s not available for host1 that is performing the merge
+ hosts:
+ host2:
+
+provider:
+ vars:
+ merge_result: "{{ lookup('community.general.merge_variables', 'merge2__', pattern_type='prefix', groups=['consumer']) }}"
+ hosts:
+ host1:
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_play.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_play.yml
new file mode 100644
index 000000000..51cd6f1ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_cross_host_merge_play.yml
@@ -0,0 +1,21 @@
+---
+# Copyright (c) 2020, Thales Netherlands
+# Copyright (c) 2021, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test merge_variables lookup plugin (merging host reference variables)
+ hosts: host1
+ connection: local
+ gather_facts: false
+ tasks:
+ - name: Print merge result
+ ansible.builtin.debug:
+ msg: "{{ merge_result }}"
+ - name: Validate merge result
+ ansible.builtin.assert:
+ that:
+ - "merge_result | length == 3"
+ - "merge_result.host == 'host1'"
+ - "merge_result.user == 'usr'"
+ - "merge_result.pass == 'pwd'"
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py
index 92ebbde6e..b61c32a4d 100644
--- a/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py
@@ -30,10 +30,10 @@ EXAMPLES = ""
RETURN = ""
+from ansible_collections.community.general.plugins.module_utils import deps
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
-from ansible.module_utils.basic import missing_required_lib
-with ModuleHelper.dependency("nopackagewiththisname", missing_required_lib("nopackagewiththisname")):
+with deps.declare("nopackagewiththisname"):
import nopackagewiththisname # noqa: F401, pylint: disable=unused-import
@@ -50,6 +50,7 @@ class MSimple(ModuleHelper):
def __init_module__(self):
self.vars.set('value', None)
self.vars.set('abc', "abc", diff=True)
+ deps.validate(self.module)
def __run__(self):
if (0 if self.vars.a is None else self.vars.a) >= 100:
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py
index bfaab0375..b3b4ed5e6 100644
--- a/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py
@@ -49,6 +49,7 @@ class MState(StateModuleHelper):
state=dict(type='str', choices=['join', 'b_x_a', 'c_x_a', 'both_x_a', 'nop'], default='join'),
),
)
+ use_old_vardict = False
def __init_module__(self):
self.vars.set('result', "abc", diff=True)
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
index 2a683617a..a2d8698d0 100644
--- a/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
@@ -13,10 +13,9 @@
block:
- name: Include test
ansible.builtin.include_tasks: test.yml
- # TODO: Find better package to install from a channel - microk8s installation takes multiple minutes, and even removal takes one minute!
- # - name: Include test_channel
- # ansible.builtin.include_tasks: test_channel.yml
- # TODO: Find bettter package to download and install from sources - cider 1.6.0 takes over 35 seconds to install
+ - name: Include test_channel
+ ansible.builtin.include_tasks: test_channel.yml
+ # TODO: Find better package to download and install from sources - cider 1.6.0 takes over 35 seconds to install
# - name: Include test_dangerous
# ansible.builtin.include_tasks: test_dangerous.yml
- name: Include test_3dash
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml
index e9eb19c89..353735761 100644
--- a/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml
@@ -5,47 +5,44 @@
# NOTE This is currently disabled for performance reasons!
-- name: Make sure package is not installed (microk8s)
+- name: Make sure package is not installed (wisdom)
community.general.snap:
- name: microk8s
+ name: wisdom
state: absent
# Test for https://github.com/ansible-collections/community.general/issues/1606
-- name: Install package (microk8s)
+- name: Install package (wisdom)
community.general.snap:
- name: microk8s
- classic: true
+ name: wisdom
state: present
- register: install_microk8s
+ register: install_wisdom
-- name: Install package with channel (microk8s)
+- name: Install package with channel (wisdom)
community.general.snap:
- name: microk8s
- classic: true
- channel: 1.20/stable
+ name: wisdom
state: present
- register: install_microk8s_chan
+ channel: latest/edge
+ register: install_wisdom_chan
-- name: Install package with channel (microk8s) again
+- name: Install package with channel (wisdom) again
community.general.snap:
- name: microk8s
- classic: true
- channel: 1.20/stable
+ name: wisdom
state: present
- register: install_microk8s_chan_again
+ channel: latest/edge
+ register: install_wisdom_chan_again
-- name: Remove package (microk8s)
+- name: Remove package (wisdom)
community.general.snap:
- name: microk8s
+ name: wisdom
state: absent
- register: remove_microk8s
+ register: remove_wisdom
- assert:
that:
- - install_microk8s is changed
- - install_microk8s_chan is changed
- - install_microk8s_chan_again is not changed
- - remove_microk8s is changed
+ - install_wisdom is changed
+ - install_wisdom_chan is changed
+ - install_wisdom_chan_again is not changed
+ - remove_wisdom is changed
- name: Install package (shellcheck)
community.general.snap:
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.13.txt b/ansible_collections/community/general/tests/sanity/ignore-2.13.txt
index 0665ddc1a..6f6495dd1 100644
--- a/ansible_collections/community/general/tests/sanity/ignore-2.13.txt
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.13.txt
@@ -1,4 +1,6 @@
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
+plugins/callback/timestamp.py validate-modules:invalid-documentation
+plugins/callback/yaml.py validate-modules:invalid-documentation
plugins/lookup/etcd.py validate-modules:invalid-documentation
plugins/lookup/etcd3.py validate-modules:invalid-documentation
plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
@@ -6,9 +8,6 @@ plugins/modules/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
-plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
-plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
-plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
plugins/modules/read_csv.py validate-modules:invalid-documentation
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/xfconf.py validate-modules:return-syntax-error
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.14.txt b/ansible_collections/community/general/tests/sanity/ignore-2.14.txt
index fed147e44..24d752103 100644
--- a/ansible_collections/community/general/tests/sanity/ignore-2.14.txt
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.14.txt
@@ -1,4 +1,6 @@
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
+plugins/callback/timestamp.py validate-modules:invalid-documentation
+plugins/callback/yaml.py validate-modules:invalid-documentation
plugins/lookup/etcd.py validate-modules:invalid-documentation
plugins/lookup/etcd3.py validate-modules:invalid-documentation
plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
@@ -7,9 +9,6 @@ plugins/modules/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
-plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
-plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
-plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
plugins/modules/read_csv.py validate-modules:invalid-documentation
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.15.txt b/ansible_collections/community/general/tests/sanity/ignore-2.15.txt
index d4c92c4d9..667c6cee4 100644
--- a/ansible_collections/community/general/tests/sanity/ignore-2.15.txt
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.15.txt
@@ -5,9 +5,6 @@ plugins/modules/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
-plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
-plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
-plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
plugins/modules/xfconf.py validate-modules:return-syntax-error
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.16.txt b/ansible_collections/community/general/tests/sanity/ignore-2.16.txt
index 397c6d986..f6b058ec6 100644
--- a/ansible_collections/community/general/tests/sanity/ignore-2.16.txt
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.16.txt
@@ -5,9 +5,6 @@ plugins/modules/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
-plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
-plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
-plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.17.txt b/ansible_collections/community/general/tests/sanity/ignore-2.17.txt
index d75aaeac2..806c4c5fc 100644
--- a/ansible_collections/community/general/tests/sanity/ignore-2.17.txt
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.17.txt
@@ -5,13 +5,11 @@ plugins/modules/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
-plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
-plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
-plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
plugins/modules/xfconf.py validate-modules:return-syntax-error
plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2
tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
+tests/unit/plugins/modules/helper.py pylint:use-yield-from # suggested construct does not work with Python 2
tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.18.txt b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt
index d75aaeac2..806c4c5fc 100644
--- a/ansible_collections/community/general/tests/sanity/ignore-2.18.txt
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt
@@ -5,13 +5,11 @@ plugins/modules/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
-plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
-plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
-plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
plugins/modules/xfconf.py validate-modules:return-syntax-error
plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2
tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
+tests/unit/plugins/modules/helper.py pylint:use-yield-from # suggested construct does not work with Python 2
tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes
diff --git a/ansible_collections/community/general/tests/unit/plugins/become/test_run0.py b/ansible_collections/community/general/tests/unit/plugins/become/test_run0.py
new file mode 100644
index 000000000..7507c556e
--- /dev/null
+++ b/ansible_collections/community/general/tests/unit/plugins/become/test_run0.py
@@ -0,0 +1,64 @@
+# Copyright (c) 2024 Ansible Project
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import re
+
+from ansible import context
+
+from .helper import call_become_plugin
+
+
+def test_run0_basic(mocker, parser, reset_cli_args):
+ options = parser.parse_args([])
+ context._init_global_context(options)
+
+ default_cmd = "/bin/foo"
+ default_exe = "/bin/sh"
+ run0_exe = "run0"
+
+ success = "BECOME-SUCCESS-.+?"
+
+ task = {
+ "become_method": "community.general.run0",
+ }
+ var_options = {}
+ cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
+ assert (
+ re.match(
+ f"{run0_exe} --user=root {default_exe} -c 'echo {success}; {default_cmd}'",
+ cmd,
+ )
+ is not None
+ )
+
+
+def test_run0_flags(mocker, parser, reset_cli_args):
+ options = parser.parse_args([])
+ context._init_global_context(options)
+
+ default_cmd = "/bin/foo"
+ default_exe = "/bin/sh"
+ run0_exe = "run0"
+ run0_flags = "--nice=15"
+
+ success = "BECOME-SUCCESS-.+?"
+
+ task = {
+ "become_method": "community.general.run0",
+ "become_flags": run0_flags,
+ }
+ var_options = {}
+ cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
+ assert (
+ re.match(
+ f"{run0_exe} --user=root --nice=15 {default_exe} -c 'echo {success}; {default_cmd}'",
+ cmd,
+ )
+ is not None
+ )
diff --git a/ansible_collections/community/general/tests/unit/plugins/lookup/test_merge_variables.py b/ansible_collections/community/general/tests/unit/plugins/lookup/test_merge_variables.py
index 66cb2f08b..ba8209439 100644
--- a/ansible_collections/community/general/tests/unit/plugins/lookup/test_merge_variables.py
+++ b/ansible_collections/community/general/tests/unit/plugins/lookup/test_merge_variables.py
@@ -18,6 +18,17 @@ from ansible_collections.community.general.plugins.lookup import merge_variables
class TestMergeVariablesLookup(unittest.TestCase):
+ class HostVarsMock(dict):
+
+ def __getattr__(self, item):
+ return super().__getitem__(item)
+
+ def __setattr__(self, item, value):
+ return super().__setitem__(item, value)
+
+ def raw_get(self, host):
+ return super().__getitem__(host)
+
def setUp(self):
self.loader = DictDataLoader({})
self.templar = Templar(loader=self.loader, variables={})
@@ -141,25 +152,28 @@ class TestMergeVariablesLookup(unittest.TestCase):
{'var': [{'item5': 'value5', 'item6': 'value6'}]},
])
def test_merge_dict_group_all(self, mock_set_options, mock_get_option, mock_template):
- results = self.merge_vars_lookup.run(['__merge_var'], {
- 'inventory_hostname': 'host1',
- 'hostvars': {
- 'host1': {
- 'group_names': ['dummy1'],
- 'inventory_hostname': 'host1',
- '1testlist__merge_var': {
- 'var': [{'item1': 'value1', 'item2': 'value2'}]
- }
- },
- 'host2': {
- 'group_names': ['dummy1'],
- 'inventory_hostname': 'host2',
- '2otherlist__merge_var': {
- 'var': [{'item5': 'value5', 'item6': 'value6'}]
- }
+ hostvars = self.HostVarsMock({
+ 'host1': {
+ 'group_names': ['dummy1'],
+ 'inventory_hostname': 'host1',
+ '1testlist__merge_var': {
+ 'var': [{'item1': 'value1', 'item2': 'value2'}]
+ }
+ },
+ 'host2': {
+ 'group_names': ['dummy1'],
+ 'inventory_hostname': 'host2',
+ '2otherlist__merge_var': {
+ 'var': [{'item5': 'value5', 'item6': 'value6'}]
}
}
})
+ variables = {
+ 'inventory_hostname': 'host1',
+ 'hostvars': hostvars
+ }
+
+ results = self.merge_vars_lookup.run(['__merge_var'], variables)
self.assertEqual(results, [
{'var': [
@@ -175,32 +189,35 @@ class TestMergeVariablesLookup(unittest.TestCase):
{'var': [{'item5': 'value5', 'item6': 'value6'}]},
])
def test_merge_dict_group_single(self, mock_set_options, mock_get_option, mock_template):
- results = self.merge_vars_lookup.run(['__merge_var'], {
- 'inventory_hostname': 'host1',
- 'hostvars': {
- 'host1': {
- 'group_names': ['dummy1'],
- 'inventory_hostname': 'host1',
- '1testlist__merge_var': {
- 'var': [{'item1': 'value1', 'item2': 'value2'}]
- }
- },
- 'host2': {
- 'group_names': ['dummy1'],
- 'inventory_hostname': 'host2',
- '2otherlist__merge_var': {
- 'var': [{'item5': 'value5', 'item6': 'value6'}]
- }
- },
- 'host3': {
- 'group_names': ['dummy2'],
- 'inventory_hostname': 'host3',
- '3otherlist__merge_var': {
- 'var': [{'item3': 'value3', 'item4': 'value4'}]
- }
+ hostvars = self.HostVarsMock({
+ 'host1': {
+ 'group_names': ['dummy1'],
+ 'inventory_hostname': 'host1',
+ '1testlist__merge_var': {
+ 'var': [{'item1': 'value1', 'item2': 'value2'}]
+ }
+ },
+ 'host2': {
+ 'group_names': ['dummy1'],
+ 'inventory_hostname': 'host2',
+ '2otherlist__merge_var': {
+ 'var': [{'item5': 'value5', 'item6': 'value6'}]
+ }
+ },
+ 'host3': {
+ 'group_names': ['dummy2'],
+ 'inventory_hostname': 'host3',
+ '3otherlist__merge_var': {
+ 'var': [{'item3': 'value3', 'item4': 'value4'}]
}
}
})
+ variables = {
+ 'inventory_hostname': 'host1',
+ 'hostvars': hostvars
+ }
+
+ results = self.merge_vars_lookup.run(['__merge_var'], variables)
self.assertEqual(results, [
{'var': [
@@ -216,32 +233,34 @@ class TestMergeVariablesLookup(unittest.TestCase):
{'var': [{'item5': 'value5', 'item6': 'value6'}]},
])
def test_merge_dict_group_multiple(self, mock_set_options, mock_get_option, mock_template):
- results = self.merge_vars_lookup.run(['__merge_var'], {
- 'inventory_hostname': 'host1',
- 'hostvars': {
- 'host1': {
- 'group_names': ['dummy1'],
- 'inventory_hostname': 'host1',
- '1testlist__merge_var': {
- 'var': [{'item1': 'value1', 'item2': 'value2'}]
- }
- },
- 'host2': {
- 'group_names': ['dummy2'],
- 'inventory_hostname': 'host2',
- '2otherlist__merge_var': {
- 'var': [{'item5': 'value5', 'item6': 'value6'}]
- }
- },
- 'host3': {
- 'group_names': ['dummy3'],
- 'inventory_hostname': 'host3',
- '3otherlist__merge_var': {
- 'var': [{'item3': 'value3', 'item4': 'value4'}]
- }
+ hostvars = self.HostVarsMock({
+ 'host1': {
+ 'group_names': ['dummy1'],
+ 'inventory_hostname': 'host1',
+ '1testlist__merge_var': {
+ 'var': [{'item1': 'value1', 'item2': 'value2'}]
+ }
+ },
+ 'host2': {
+ 'group_names': ['dummy2'],
+ 'inventory_hostname': 'host2',
+ '2otherlist__merge_var': {
+ 'var': [{'item5': 'value5', 'item6': 'value6'}]
+ }
+ },
+ 'host3': {
+ 'group_names': ['dummy3'],
+ 'inventory_hostname': 'host3',
+ '3otherlist__merge_var': {
+ 'var': [{'item3': 'value3', 'item4': 'value4'}]
}
}
})
+ variables = {
+ 'inventory_hostname': 'host1',
+ 'hostvars': hostvars
+ }
+ results = self.merge_vars_lookup.run(['__merge_var'], variables)
self.assertEqual(results, [
{'var': [
@@ -257,26 +276,27 @@ class TestMergeVariablesLookup(unittest.TestCase):
['item5'],
])
def test_merge_list_group_multiple(self, mock_set_options, mock_get_option, mock_template):
- print()
- results = self.merge_vars_lookup.run(['__merge_var'], {
- 'inventory_hostname': 'host1',
- 'hostvars': {
- 'host1': {
- 'group_names': ['dummy1'],
- 'inventory_hostname': 'host1',
- '1testlist__merge_var': ['item1']
- },
- 'host2': {
- 'group_names': ['dummy2'],
- 'inventory_hostname': 'host2',
- '2otherlist__merge_var': ['item5']
- },
- 'host3': {
- 'group_names': ['dummy3'],
- 'inventory_hostname': 'host3',
- '3otherlist__merge_var': ['item3']
- }
+ hostvars = self.HostVarsMock({
+ 'host1': {
+ 'group_names': ['dummy1'],
+ 'inventory_hostname': 'host1',
+ '1testlist__merge_var': ['item1']
+ },
+ 'host2': {
+ 'group_names': ['dummy2'],
+ 'inventory_hostname': 'host2',
+ '2otherlist__merge_var': ['item5']
+ },
+ 'host3': {
+ 'group_names': ['dummy3'],
+ 'inventory_hostname': 'host3',
+ '3otherlist__merge_var': ['item3']
}
})
+ variables = {
+ 'inventory_hostname': 'host1',
+ 'hostvars': hostvars
+ }
+ results = self.merge_vars_lookup.run(['__merge_var'], variables)
self.assertEqual(results, [['item1', 'item5']])
diff --git a/ansible_collections/community/general/tests/unit/plugins/module_utils/test_cmd_runner.py b/ansible_collections/community/general/tests/unit/plugins/module_utils/test_cmd_runner.py
index 86576e8ce..6816afb34 100644
--- a/ansible_collections/community/general/tests/unit/plugins/module_utils/test_cmd_runner.py
+++ b/ansible_collections/community/general/tests/unit/plugins/module_utils/test_cmd_runner.py
@@ -7,6 +7,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from sys import version_info
+from functools import partial
import pytest
@@ -15,55 +16,64 @@ from ansible_collections.community.general.plugins.module_utils.cmd_runner impor
TC_FORMATS = dict(
- simple_boolean__true=(cmd_runner_fmt.as_bool, ("--superflag",), True, ["--superflag"]),
- simple_boolean__false=(cmd_runner_fmt.as_bool, ("--superflag",), False, []),
- simple_boolean__none=(cmd_runner_fmt.as_bool, ("--superflag",), None, []),
- simple_boolean_both__true=(cmd_runner_fmt.as_bool, ("--superflag", "--falseflag"), True, ["--superflag"]),
- simple_boolean_both__false=(cmd_runner_fmt.as_bool, ("--superflag", "--falseflag"), False, ["--falseflag"]),
- simple_boolean_both__none=(cmd_runner_fmt.as_bool, ("--superflag", "--falseflag"), None, ["--falseflag"]),
- simple_boolean_both__none_ig=(cmd_runner_fmt.as_bool, ("--superflag", "--falseflag", True), None, []),
- simple_boolean_not__true=(cmd_runner_fmt.as_bool_not, ("--superflag",), True, []),
- simple_boolean_not__false=(cmd_runner_fmt.as_bool_not, ("--superflag",), False, ["--superflag"]),
- simple_boolean_not__none=(cmd_runner_fmt.as_bool_not, ("--superflag",), None, ["--superflag"]),
- simple_optval__str=(cmd_runner_fmt.as_optval, ("-t",), "potatoes", ["-tpotatoes"]),
- simple_optval__int=(cmd_runner_fmt.as_optval, ("-t",), 42, ["-t42"]),
- simple_opt_val__str=(cmd_runner_fmt.as_opt_val, ("-t",), "potatoes", ["-t", "potatoes"]),
- simple_opt_val__int=(cmd_runner_fmt.as_opt_val, ("-t",), 42, ["-t", "42"]),
- simple_opt_eq_val__str=(cmd_runner_fmt.as_opt_eq_val, ("--food",), "potatoes", ["--food=potatoes"]),
- simple_opt_eq_val__int=(cmd_runner_fmt.as_opt_eq_val, ("--answer",), 42, ["--answer=42"]),
- simple_list_potato=(cmd_runner_fmt.as_list, (), "literal_potato", ["literal_potato"]),
- simple_list_42=(cmd_runner_fmt.as_list, (), 42, ["42"]),
- simple_map=(cmd_runner_fmt.as_map, ({'a': 1, 'b': 2, 'c': 3},), 'b', ["2"]),
- simple_default_type__list=(cmd_runner_fmt.as_default_type, ("list",), [1, 2, 3, 5, 8], ["--1", "--2", "--3", "--5", "--8"]),
- simple_default_type__bool_true=(cmd_runner_fmt.as_default_type, ("bool", "what"), True, ["--what"]),
- simple_default_type__bool_false=(cmd_runner_fmt.as_default_type, ("bool", "what"), False, []),
- simple_default_type__potato=(cmd_runner_fmt.as_default_type, ("any-other-type", "potato"), "42", ["--potato", "42"]),
- simple_fixed_true=(cmd_runner_fmt.as_fixed, [("--always-here", "--forever")], True, ["--always-here", "--forever"]),
- simple_fixed_false=(cmd_runner_fmt.as_fixed, [("--always-here", "--forever")], False, ["--always-here", "--forever"]),
- simple_fixed_none=(cmd_runner_fmt.as_fixed, [("--always-here", "--forever")], None, ["--always-here", "--forever"]),
- simple_fixed_str=(cmd_runner_fmt.as_fixed, [("--always-here", "--forever")], "something", ["--always-here", "--forever"]),
+ simple_boolean__true=(partial(cmd_runner_fmt.as_bool, "--superflag"), True, ["--superflag"], None),
+ simple_boolean__false=(partial(cmd_runner_fmt.as_bool, "--superflag"), False, [], None),
+ simple_boolean__none=(partial(cmd_runner_fmt.as_bool, "--superflag"), None, [], None),
+ simple_boolean_both__true=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"), True, ["--superflag"], None),
+ simple_boolean_both__false=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"), False, ["--falseflag"], None),
+ simple_boolean_both__none=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag"), None, ["--falseflag"], None),
+ simple_boolean_both__none_ig=(partial(cmd_runner_fmt.as_bool, "--superflag", "--falseflag", True), None, [], None),
+ simple_boolean_not__true=(partial(cmd_runner_fmt.as_bool_not, "--superflag"), True, [], None),
+ simple_boolean_not__false=(partial(cmd_runner_fmt.as_bool_not, "--superflag"), False, ["--superflag"], None),
+ simple_boolean_not__none=(partial(cmd_runner_fmt.as_bool_not, "--superflag"), None, ["--superflag"], None),
+ simple_optval__str=(partial(cmd_runner_fmt.as_optval, "-t"), "potatoes", ["-tpotatoes"], None),
+ simple_optval__int=(partial(cmd_runner_fmt.as_optval, "-t"), 42, ["-t42"], None),
+ simple_opt_val__str=(partial(cmd_runner_fmt.as_opt_val, "-t"), "potatoes", ["-t", "potatoes"], None),
+ simple_opt_val__int=(partial(cmd_runner_fmt.as_opt_val, "-t"), 42, ["-t", "42"], None),
+ simple_opt_eq_val__str=(partial(cmd_runner_fmt.as_opt_eq_val, "--food"), "potatoes", ["--food=potatoes"], None),
+ simple_opt_eq_val__int=(partial(cmd_runner_fmt.as_opt_eq_val, "--answer"), 42, ["--answer=42"], None),
+ simple_list_potato=(cmd_runner_fmt.as_list, "literal_potato", ["literal_potato"], None),
+ simple_list_42=(cmd_runner_fmt.as_list, 42, ["42"], None),
+ simple_list_min_len_ok=(partial(cmd_runner_fmt.as_list, min_len=1), 42, ["42"], None),
+ simple_list_min_len_fail=(partial(cmd_runner_fmt.as_list, min_len=10), 42, None, ValueError),
+ simple_list_max_len_ok=(partial(cmd_runner_fmt.as_list, max_len=1), 42, ["42"], None),
+ simple_list_max_len_fail=(partial(cmd_runner_fmt.as_list, max_len=2), [42, 42, 42], None, ValueError),
+ simple_map=(partial(cmd_runner_fmt.as_map, {'a': 1, 'b': 2, 'c': 3}), 'b', ["2"], None),
+ simple_default_type__list=(partial(cmd_runner_fmt.as_default_type, "list"), [1, 2, 3, 5, 8], ["--1", "--2", "--3", "--5", "--8"], None),
+ simple_default_type__bool_true=(partial(cmd_runner_fmt.as_default_type, "bool", "what"), True, ["--what"], None),
+ simple_default_type__bool_false=(partial(cmd_runner_fmt.as_default_type, "bool", "what"), False, [], None),
+ simple_default_type__potato=(partial(cmd_runner_fmt.as_default_type, "any-other-type", "potato"), "42", ["--potato", "42"], None),
+ simple_fixed_true=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), True, ["--always-here", "--forever"], None),
+ simple_fixed_false=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), False, ["--always-here", "--forever"], None),
+ simple_fixed_none=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), None, ["--always-here", "--forever"], None),
+ simple_fixed_str=(partial(cmd_runner_fmt.as_fixed, ["--always-here", "--forever"]), "something", ["--always-here", "--forever"], None),
)
if tuple(version_info) >= (3, 1):
from collections import OrderedDict
# needs OrderedDict to provide a consistent key order
TC_FORMATS["simple_default_type__dict"] = ( # type: ignore
- cmd_runner_fmt.as_default_type,
- ("dict",),
+ partial(cmd_runner_fmt.as_default_type, "dict"),
OrderedDict((('a', 1), ('b', 2))),
- ["--a=1", "--b=2"]
+ ["--a=1", "--b=2"],
+ None
)
TC_FORMATS_IDS = sorted(TC_FORMATS.keys())
-@pytest.mark.parametrize('func, fmt_opt, value, expected',
+@pytest.mark.parametrize('func, value, expected, exception',
(TC_FORMATS[tc] for tc in TC_FORMATS_IDS),
ids=TC_FORMATS_IDS)
-def test_arg_format(func, fmt_opt, value, expected):
- fmt_func = func(*fmt_opt)
- actual = fmt_func(value, ctx_ignore_none=True)
- print("formatted string = {0}".format(actual))
- assert actual == expected, "actual = {0}".format(actual)
+def test_arg_format(func, value, expected, exception):
+ fmt_func = func()
+ try:
+ actual = fmt_func(value, ctx_ignore_none=True)
+ print("formatted string = {0}".format(actual))
+ assert actual == expected, "actual = {0}".format(actual)
+ except Exception as e:
+ if exception is None:
+ raise
+ assert isinstance(e, exception)
TC_RUNNER = dict(
diff --git a/ansible_collections/community/general/tests/unit/plugins/module_utils/test_python_runner.py b/ansible_collections/community/general/tests/unit/plugins/module_utils/test_python_runner.py
new file mode 100644
index 000000000..015065bdd
--- /dev/null
+++ b/ansible_collections/community/general/tests/unit/plugins/module_utils/test_python_runner.py
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import os
+
+import pytest
+
+from ansible_collections.community.general.tests.unit.compat.mock import MagicMock, PropertyMock
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
+from ansible_collections.community.general.plugins.module_utils.python_runner import PythonRunner
+
+
+TC_RUNNER = dict(
+ # SAMPLE: This shows all possible elements of a test case. It does not actually run.
+ #
+ # testcase_name=(
+ # # input
+ # dict(
+ # args_bundle = dict(
+ # param1=dict(
+ # type="int",
+ # value=11,
+ # fmt_func=cmd_runner_fmt.as_opt_eq_val,
+ # fmt_arg="--answer",
+ # ),
+ # param2=dict(
+ # fmt_func=cmd_runner_fmt.as_bool,
+ # fmt_arg="--bb-here",
+ # )
+ # ),
+ # runner_init_args = dict(
+ # command="testing",
+ # default_args_order=(),
+ # check_rc=False,
+ # force_lang="C",
+ # path_prefix=None,
+ # environ_update=None,
+ # ),
+ # runner_ctx_args = dict(
+ # args_order=['aa', 'bb'],
+ # output_process=None,
+ # ignore_value_none=True,
+ # ),
+ # ),
+ # # command execution
+ # dict(
+ # runner_ctx_run_args = dict(bb=True),
+ # rc = 0,
+ # out = "",
+ # err = "",
+ # ),
+ # # expected
+ # dict(
+ # results=(),
+ # run_info=dict(
+ # cmd=['/mock/bin/testing', '--answer=11', '--bb-here'],
+ # environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
+ # ),
+ # exc=None,
+ # ),
+ # ),
+ #
+ aa_bb=(
+ dict(
+ args_bundle=dict(
+ aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
+ bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
+ ),
+ runner_init_args=dict(command="testing"),
+ runner_ctx_args=dict(args_order=['aa', 'bb']),
+ ),
+ dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
+ dict(
+ run_info=dict(
+ cmd=['/mock/bin/python', 'testing', '--answer=11', '--bb-here'],
+ environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
+ args_order=('aa', 'bb'),
+ ),
+ ),
+ ),
+ aa_bb_py3=(
+ dict(
+ args_bundle=dict(
+ aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
+ bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
+ ),
+ runner_init_args=dict(command="toasting", python="python3"),
+ runner_ctx_args=dict(args_order=['aa', 'bb']),
+ ),
+ dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
+ dict(
+ run_info=dict(
+ cmd=['/mock/bin/python3', 'toasting', '--answer=11', '--bb-here'],
+ environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
+ args_order=('aa', 'bb'),
+ ),
+ ),
+ ),
+ aa_bb_abspath=(
+ dict(
+ args_bundle=dict(
+ aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
+ bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
+ ),
+ runner_init_args=dict(command="toasting", python="/crazy/local/bin/python3"),
+ runner_ctx_args=dict(args_order=['aa', 'bb']),
+ ),
+ dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
+ dict(
+ run_info=dict(
+ cmd=['/crazy/local/bin/python3', 'toasting', '--answer=11', '--bb-here'],
+ environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'},
+ args_order=('aa', 'bb'),
+ ),
+ ),
+ ),
+ aa_bb_venv=(
+ dict(
+ args_bundle=dict(
+ aa=dict(type="int", value=11, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
+ bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
+ ),
+ runner_init_args=dict(command="toasting", venv="/venv"),
+ runner_ctx_args=dict(args_order=['aa', 'bb']),
+ ),
+ dict(runner_ctx_run_args=dict(bb=True), rc=0, out="", err=""),
+ dict(
+ run_info=dict(
+ cmd=['/venv/bin/python', 'toasting', '--answer=11', '--bb-here'],
+ environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C', 'VIRTUAL_ENV': '/venv', 'PATH': '/venv/bin'},
+ args_order=('aa', 'bb'),
+ ),
+ ),
+ ),
+)
+TC_RUNNER_IDS = sorted(TC_RUNNER.keys())
+
+
+@pytest.mark.parametrize('runner_input, cmd_execution, expected',
+ (TC_RUNNER[tc] for tc in TC_RUNNER_IDS),
+ ids=TC_RUNNER_IDS)
+def test_runner_context(runner_input, cmd_execution, expected):
+ arg_spec = {}
+ params = {}
+ arg_formats = {}
+ for k, v in runner_input['args_bundle'].items():
+ try:
+ arg_spec[k] = {'type': v['type']}
+ except KeyError:
+ pass
+ try:
+ params[k] = v['value']
+ except KeyError:
+ pass
+ try:
+ arg_formats[k] = v['fmt_func'](v['fmt_arg'])
+ except KeyError:
+ pass
+
+ orig_results = tuple(cmd_execution[x] for x in ('rc', 'out', 'err'))
+
+ print("arg_spec={0}\nparams={1}\narg_formats={2}\n".format(
+ arg_spec,
+ params,
+ arg_formats,
+ ))
+
+ module = MagicMock()
+ type(module).argument_spec = PropertyMock(return_value=arg_spec)
+ type(module).params = PropertyMock(return_value=params)
+ module.get_bin_path.return_value = os.path.join(
+ runner_input["runner_init_args"].get("venv", "/mock"),
+ "bin",
+ runner_input["runner_init_args"].get("python", "python")
+ )
+ module.run_command.return_value = orig_results
+
+ runner = PythonRunner(
+ module=module,
+ arg_formats=arg_formats,
+ **runner_input['runner_init_args']
+ )
+
+ def _extract_path(run_info):
+ path = run_info.get("environ_update", {}).get("PATH")
+ if path is not None:
+ run_info["environ_update"] = dict((k, v)
+ for k, v in run_info["environ_update"].items()
+ if k != "PATH")
+ return run_info, path
+
+ def _assert_run_info_env_path(actual, expected):
+ actual2 = set(actual.split(":"))
+ assert expected in actual2, "Missing expected path {0} in output PATH: {1}".format(expected, actual)
+
+ def _assert_run_info(actual, expected):
+ reduced = dict((k, actual[k]) for k in expected.keys())
+ reduced, act_path = _extract_path(reduced)
+ expected, exp_path = _extract_path(expected)
+ if exp_path is not None:
+ _assert_run_info_env_path(act_path, exp_path)
+ assert reduced == expected, "{0}".format(reduced)
+
+ def _assert_run(expected, ctx, results):
+ _assert_run_info(ctx.run_info, expected['run_info'])
+ assert results == expected.get('results', orig_results)
+
+ exc = expected.get("exc")
+ if exc:
+ with pytest.raises(exc):
+ with runner.context(**runner_input['runner_ctx_args']) as ctx:
+ results = ctx.run(**cmd_execution['runner_ctx_run_args'])
+ _assert_run(expected, ctx, results)
+
+ else:
+ with runner.context(**runner_input['runner_ctx_args']) as ctx:
+ results = ctx.run(**cmd_execution['runner_ctx_run_args'])
+ _assert_run(expected, ctx, results)
diff --git a/ansible_collections/community/general/tests/unit/plugins/modules/helper.py b/ansible_collections/community/general/tests/unit/plugins/modules/helper.py
index a7322bf4d..e012980af 100644
--- a/ansible_collections/community/general/tests/unit/plugins/modules/helper.py
+++ b/ansible_collections/community/general/tests/unit/plugins/modules/helper.py
@@ -9,7 +9,6 @@ __metaclass__ = type
import sys
import json
from collections import namedtuple
-from itertools import chain, repeat
import pytest
import yaml
@@ -52,9 +51,9 @@ class _BaseContext(object):
test_flags = self.test_flags()
if test_flags.get("skip"):
- pytest.skip()
+ pytest.skip(test_flags.get("skip"))
if test_flags.get("xfail"):
- pytest.xfail()
+ pytest.xfail(test_flags.get("xfail"))
func()
@@ -76,12 +75,21 @@ class _RunCmdContext(_BaseContext):
self.mock_run_cmd = self._make_mock_run_cmd()
def _make_mock_run_cmd(self):
- call_results = [(x.rc, x.out, x.err) for x in self.run_cmd_calls]
- error_call_results = (123,
- "OUT: testcase has not enough run_command calls",
- "ERR: testcase has not enough run_command calls")
+ def _results():
+ for result in [(x.rc, x.out, x.err) for x in self.run_cmd_calls]:
+ yield result
+ raise Exception("testcase has not enough run_command calls")
+
+ results = _results()
+
+ def side_effect(self_, **kwargs):
+ result = next(results)
+ if kwargs.get("check_rc", False) and result[0] != 0:
+ raise Exception("rc = {0}".format(result[0]))
+ return result
+
mock_run_command = self.mocker.patch('ansible.module_utils.basic.AnsibleModule.run_command',
- side_effect=chain(call_results, repeat(error_call_results)))
+ side_effect=side_effect)
return mock_run_command
def check_results(self, results):
diff --git a/ansible_collections/community/general/tests/unit/plugins/modules/test_cpanm.yaml b/ansible_collections/community/general/tests/unit/plugins/modules/test_cpanm.yaml
index 3ed718d48..4eed95720 100644
--- a/ansible_collections/community/general/tests/unit/plugins/modules/test_cpanm.yaml
+++ b/ansible_collections/community/general/tests/unit/plugins/modules/test_cpanm.yaml
@@ -7,6 +7,7 @@
- id: install_dancer_compatibility
input:
name: Dancer
+ mode: compatibility
output:
changed: true
run_command_calls:
@@ -23,6 +24,7 @@
- id: install_dancer_already_installed_compatibility
input:
name: Dancer
+ mode: compatibility
output:
changed: false
run_command_calls:
@@ -34,7 +36,6 @@
- id: install_dancer
input:
name: Dancer
- mode: new
output:
changed: true
run_command_calls:
@@ -46,6 +47,7 @@
- id: install_distribution_file_compatibility
input:
name: MIYAGAWA/Plack-0.99_05.tar.gz
+ mode: compatibility
output:
changed: true
run_command_calls:
@@ -57,7 +59,6 @@
- id: install_distribution_file
input:
name: MIYAGAWA/Plack-0.99_05.tar.gz
- mode: new
output:
changed: true
run_command_calls:
diff --git a/ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.py b/ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.py
new file mode 100644
index 000000000..ffa9feb39
--- /dev/null
+++ b/ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.py
@@ -0,0 +1,13 @@
+# Copyright (c) Alexei Znamensky (russoz@gmail.com)
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+
+from ansible_collections.community.general.plugins.modules import django_command
+from .helper import Helper
+
+
+Helper.from_module(django_command, __name__)
diff --git a/ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.yaml b/ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.yaml
new file mode 100644
index 000000000..046dd87f0
--- /dev/null
+++ b/ansible_collections/community/general/tests/unit/plugins/modules/test_django_command.yaml
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) Alexei Znamensky (russoz@gmail.com)
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+---
+- id: command_success
+ input:
+ command: check
+ extra_args:
+ - babaloo
+ - yaba
+ - daba
+ - doo
+ settings: whatever.settings
+ run_command_calls:
+ - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, babaloo, yaba, daba, doo]
+ environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
+ rc: 0
+ out: "whatever\n"
+ err: ""
+- id: command_fail
+ input:
+ command: check
+ extra_args:
+ - babaloo
+ - yaba
+ - daba
+ - doo
+ settings: whatever.settings
+ output:
+ failed: true
+ run_command_calls:
+ - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, babaloo, yaba, daba, doo]
+ environ: *env-def
+ rc: 1
+ out: "whatever\n"
+ err: ""
diff --git a/ansible_collections/community/general/tests/unit/plugins/modules/test_homebrew.py b/ansible_collections/community/general/tests/unit/plugins/modules/test_homebrew.py
index f849b433d..d04ca4de5 100644
--- a/ansible_collections/community/general/tests/unit/plugins/modules/test_homebrew.py
+++ b/ansible_collections/community/general/tests/unit/plugins/modules/test_homebrew.py
@@ -2,23 +2,28 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.community.general.tests.unit.compat import unittest
-from ansible_collections.community.general.plugins.modules.homebrew import Homebrew
+from ansible_collections.community.general.plugins.module_utils.homebrew import HomebrewValidate
class TestHomebrewModule(unittest.TestCase):
def setUp(self):
- self.brew_app_names = [
- 'git-ssh',
- 'awscli@1',
- 'bash'
+ self.brew_app_names = ["git-ssh", "awscli@1", "bash"]
+
+ self.invalid_names = [
+ "git ssh",
+ "git*",
]
def test_valid_package_names(self):
for name in self.brew_app_names:
- self.assertTrue(Homebrew.valid_package(name))
+ self.assertTrue(HomebrewValidate.valid_package(name))
+
+ def test_invalid_package_names(self):
+ for name in self.invalid_names:
+ self.assertFalse(HomebrewValidate.valid_package(name))
diff --git a/ansible_collections/community/general/tests/unit/plugins/modules/test_puppet.yaml b/ansible_collections/community/general/tests/unit/plugins/modules/test_puppet.yaml
index 308be9797..7909403cf 100644
--- a/ansible_collections/community/general/tests/unit/plugins/modules/test_puppet.yaml
+++ b/ansible_collections/community/general/tests/unit/plugins/modules/test_puppet.yaml
@@ -190,3 +190,35 @@
rc: 0
out: ""
err: ""
+- id: puppet_agent_waitforlock
+ input:
+ waitforlock: 30
+ output:
+ changed: false
+ run_command_calls:
+ - command: [/testbin/puppet, config, print, agent_disabled_lockfile]
+ environ: *env-def
+ rc: 0
+ out: "blah, anything"
+ err: ""
+ - command:
+ - /testbin/timeout
+ - -s
+ - "9"
+ - 30m
+ - /testbin/puppet
+ - agent
+ - --onetime
+ - --no-daemonize
+ - --no-usecacheonfailure
+ - --no-splay
+ - --detailed-exitcodes
+ - --verbose
+ - --color
+ - "0"
+ - --waitforlock
+ - "30"
+ environ: *env-def
+ rc: 0
+ out: ""
+ err: ""
diff --git a/ansible_collections/community/general/tests/unit/plugins/plugin_utils/test_unsafe.py b/ansible_collections/community/general/tests/unit/plugins/plugin_utils/test_unsafe.py
new file mode 100644
index 000000000..3f35ee933
--- /dev/null
+++ b/ansible_collections/community/general/tests/unit/plugins/plugin_utils/test_unsafe.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+import pytest
+
+from ansible.utils.unsafe_proxy import AnsibleUnsafe
+
+from ansible_collections.community.general.plugins.plugin_utils.unsafe import (
+ make_unsafe,
+)
+
+
+TEST_MAKE_UNSAFE = [
+ (
+ u'text',
+ [],
+ [
+ (),
+ ],
+ ),
+ (
+ u'{{text}}',
+ [
+ (),
+ ],
+ [],
+ ),
+ (
+ b'text',
+ [],
+ [
+ (),
+ ],
+ ),
+ (
+ b'{{text}}',
+ [
+ (),
+ ],
+ [],
+ ),
+ (
+ {
+ 'skey': 'value',
+ 'ukey': '{{value}}',
+ 1: [
+ 'value',
+ '{{value}}',
+ {
+ 1.0: '{{value}}',
+ 2.0: 'value',
+ },
+ ],
+ },
+ [
+ ('ukey', ),
+ (1, 1),
+ (1, 2, 1.0),
+ ],
+ [
+ ('skey', ),
+ (1, 0),
+ (1, 2, 2.0),
+ ],
+ ),
+ (
+ ['value', '{{value}}'],
+ [
+ (1, ),
+ ],
+ [
+ (0, ),
+ ],
+ ),
+]
+
+
+@pytest.mark.parametrize("value, check_unsafe_paths, check_safe_paths", TEST_MAKE_UNSAFE)
+def test_make_unsafe(value, check_unsafe_paths, check_safe_paths):
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for check_path in check_unsafe_paths:
+ obj = unsafe_value
+ for elt in check_path:
+ obj = obj[elt]
+ assert isinstance(obj, AnsibleUnsafe)
+ for check_path in check_safe_paths:
+ obj = unsafe_value
+ for elt in check_path:
+ obj = obj[elt]
+ assert not isinstance(obj, AnsibleUnsafe)
+
+
+def test_make_unsafe_dict_key():
+ value = {
+ b'test': 1,
+ u'test': 2,
+ }
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert not isinstance(obj, AnsibleUnsafe)
+
+ value = {
+ b'{{test}}': 1,
+ u'{{test}}': 2,
+ }
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert isinstance(obj, AnsibleUnsafe)
+
+
+def test_make_unsafe_set():
+ value = set([b'test', u'test'])
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert not isinstance(obj, AnsibleUnsafe)
+
+ value = set([b'{{test}}', u'{{test}}'])
+ unsafe_value = make_unsafe(value)
+ assert unsafe_value == value
+ for obj in unsafe_value:
+ assert isinstance(obj, AnsibleUnsafe)
diff --git a/ansible_collections/community/grafana/.github/workflows/ansible-test.yml b/ansible_collections/community/grafana/.github/workflows/ansible-test.yml
index a5717781f..7d474372b 100644
--- a/ansible_collections/community/grafana/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/grafana/.github/workflows/ansible-test.yml
@@ -45,7 +45,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- grafana_version: ["9.5.14", "8.5.27", "10.2.2"]
+ grafana_version: ["8.5.27", "9.5.18", "10.4.2"]
ansible_version: ["stable-2.15", "stable-2.16", "devel"]
python_version: ["3.10"]
services:
@@ -67,7 +67,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- grafana_version: ["9.5.14", "8.5.27", "10.2.2"]
+ grafana_version: ["8.5.27", "9.5.18", "10.4.2"]
ansible_version: ["stable-2.15", "stable-2.16", "devel"]
python_version: ["3.10"]
services:
@@ -86,7 +86,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --no-cache-dir --upgrade pip
- pip install "git+https://github.com/ansible/ansible@${{ matrix.ansible_version }}" molecule molecule-docker
+ pip install "git+https://github.com/ansible/ansible@${{ matrix.ansible_version }}" molecule molecule-plugins[docker] 'requests<2.32.0'
- name: Test with molecule
run: |
diff --git a/ansible_collections/community/grafana/CHANGELOG.rst b/ansible_collections/community/grafana/CHANGELOG.rst
index 8a40ac18f..9449bdc5c 100644
--- a/ansible_collections/community/grafana/CHANGELOG.rst
+++ b/ansible_collections/community/grafana/CHANGELOG.rst
@@ -4,6 +4,35 @@ Grafana Collection Release Notes
.. contents:: Topics
+v1.9.1
+======
+
+Bugfixes
+--------
+
+- undo removed deprecated `message` argument in `grafana_dashboard`
+
+v1.9.0
+======
+
+Minor Changes
+-------------
+
+- Add new module `grafana_silence` to create and delete silences through the API
+- Add role components for `grafana_silence` module
+- lookup - grafana_dashboards - add `validate_certs` and `ca_path` options to plugin for custom certs validation
+
+Removed Features (previously deprecated)
+----------------------------------------
+
+- removed deprecated `message` argument in `grafana_dashboard`
+
+Bugfixes
+--------
+
+- Handling of desired default state for first `grafana_datasource`
+- Ignore `type` argument for diff comparison if `grafana-postgresq-datasource` alias `postgres` is used
+- Set umask for `grafana_plugin` command
v1.8.0
======
@@ -288,4 +317,3 @@ Release Summary
---------------
Initial migration of Grafana content from Ansible core (2.9/devel)
-
diff --git a/ansible_collections/community/grafana/FILES.json b/ansible_collections/community/grafana/FILES.json
index be95fa2bc..037433bd7 100644
--- a/ansible_collections/community/grafana/FILES.json
+++ b/ansible_collections/community/grafana/FILES.json
@@ -53,7 +53,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e3e774ec33a3dc2a5ea1da40931ab5e6b96d3b67e57454fc867f9009cbc9797f",
+ "chksum_sha256": "cd6239f3c1bd2e8e47e65c2e1504273adabd0debe5034b52c0b3d1817d5ece75",
"format": 1
},
{
@@ -470,6 +470,76 @@
"format": 1
},
{
+ "name": "changelogs/fragments/353-docs-add-influxdb-flux-example.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a07b0c46777ec3102120e2d1374c24f11fa49b643f9ee598697d7cb7931a6fb0",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/354-fix-find-grafana-versions.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "988704ddd40d7a4e6c20a045fa813de4fff2db0ad722f64f97c08af0ebcc3ee6",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/355-rm-dashboard-message-argument.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1f9b81756d099816b1ef211ed9420406256f31e44a1af8e21025d1781ec8c452",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/356-lookup-dashboards-add-custom-certs-verification-logic.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "45e0bb6e524aecb31ef2ed642a981a964164da2871ec3b5167ce79205ef77d3e",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/357-module-grafana-silence.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d4302eaaf80c43b0e4b8d9b919579ec6fbf2156966696b17342ff3caaa4b39a8",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/358-role-grafana-silence.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "44f72091e352d9f720a2c69be372a251ae80371c9bbb3d046a1c92e3169597f9",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/362-plugin-umask.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a8e15e87758848e90e4798e0d8bbf4ae3d69c8df49f36d3f6f4665b7bac175dc",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/364-first-datasource-default.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1706a7f2ab349d835f22e173fc4b1f1abd30d08ddb6a24054a12999254d5f816",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/367-dashboard-undo-breaing-change-message.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d9379b41ea1756af06746c98636b2f29c04b3dcb3d1c05d131d30d84d569e75f",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/368-molecule-pin-requests.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cf41eb78ee4dc1c0b4e70f18040bf236de5764067de76a46c2ca60bb787a0801",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/add-units-datasource.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -543,7 +613,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "641de48bd2e1d3ab8daeace7b522413299bd4d2521204d1f707e8c23bb445480",
+ "chksum_sha256": "58b3c24d8492d4052650bd4595af4f4150984005e7e2cf1fa45d86c6710e3632",
"format": 1
},
{
@@ -571,14 +641,14 @@
"name": "hacking/check_fragment.sh",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "89b848ffbab17ebb115443ad4d599db0238a1f35a95d52ab4eedf990eef097a8",
+ "chksum_sha256": "911f382f8cb1de3f26d67809bba3a950ad75cd0a95cd39de13c2eb24131bc9aa",
"format": 1
},
{
"name": "hacking/find_grafana_versions.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "39acc81ec9733183bbb4eeae0c10c3aeecdeedd1ffc2dabcc675b84e16565f3e",
+ "chksum_sha256": "72518bc80cd4e6c1e6c28aa057bfb05e96231cffd71fb481dba53b76fcb86786",
"format": 1
},
{
@@ -599,7 +669,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6872a5ea5042e0a7a43f2b60fe6c02a24e3e76b25deb50a46567df781345e41b",
+ "chksum_sha256": "0ccfa35f79e37b4162e45d083ec7170e8dd3b3011e506101f58ccbc5d183adbb",
"format": 1
},
{
@@ -620,7 +690,7 @@
"name": "molecule/default/converge.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c1e0e02c807ceafdf7bd707e0def1e9d2118e6389af9af44dc832dfc0483dab9",
+ "chksum_sha256": "707ee0f0231e6bfb2f467ec7d5089125b0b7d77ea85560921ad4eb179453c922",
"format": 1
},
{
@@ -711,7 +781,7 @@
"name": "plugins/lookup/grafana_dashboard.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7483dabbd84c95d3cd603e2d9d905b51f00e9f6ab4974164f31387c3ee63535d",
+ "chksum_sha256": "7e46eff65f8eda5fd1fbd4de9790d018acac261fa5e747dbdc1c9bc6062608cf",
"format": 1
},
{
@@ -753,7 +823,7 @@
"name": "plugins/modules/grafana_datasource.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "23081add13f2aba994b4cddb264972d219bee823ac1e4f454931d5a6a374bd94",
+ "chksum_sha256": "108ff562f0e37620ddcf6751f144aad05432bd7f3369bfbfc957e9df49310001",
"format": 1
},
{
@@ -788,7 +858,14 @@
"name": "plugins/modules/grafana_plugin.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fb0ee164a2936bc35381cf79026b6725c7a1df139e71d58989f8912432043c00",
+ "chksum_sha256": "a6e739390d7afc946f656dc2080e96ab0c2e630e016fc20aaa2351ec909b5d64",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/grafana_silence.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1a90d5e29905a481dfed1fbd573a342984cf1e891c3643be5c13541302810cc5",
"format": 1
},
{
@@ -830,7 +907,7 @@
"name": "roles/grafana/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ee6026b2dd62777a731f2214949124f45d73309102123cad31ad55489a90ca45",
+ "chksum_sha256": "bce677aac146e75eee5d57c22d7ad1bdff128abb52d4bf05f8cd30f47d6c4105",
"format": 1
},
{
@@ -844,7 +921,7 @@
"name": "roles/grafana/meta/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "192ef2ac687cd5594febffbc0ab6f3d184cceed34dc66c11ff217db19f4ccfc2",
+ "chksum_sha256": "840995ce8972789e894e6c9be6d2fcd030fd3c478da292e7e363cb40c6f462c9",
"format": 1
},
{
@@ -858,14 +935,14 @@
"name": "roles/grafana/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0de2cd11feb7e45f3427d063c3123024f94401bc5c1b48eaecea9716efcc03d5",
+ "chksum_sha256": "beb75cb00b20421fd4f4c81d72d32d13986005e809dd2c550a15290f09f1b9a2",
"format": 1
},
{
"name": "roles/grafana/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ab4f69856777b7b0c208c3c3d06a9771c98f81a729618dc94df80ea981b1b6ab",
+ "chksum_sha256": "f04e735d327e90a7bf9b51ce09c4834f8ed6c6e5ba6d635cdd4e92d807171794",
"format": 1
},
{
@@ -1054,7 +1131,7 @@
"name": "tests/integration/targets/grafana_datasource/tasks/elastic.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "69fba433ef869f3bb1916f2036a43985af48d21118f08e969f6020532a963d43",
+ "chksum_sha256": "c2db61ab9613c93dc35ed793aca09451ae672ab5e24c43b456a970ad0ff63f56",
"format": 1
},
{
@@ -1096,7 +1173,7 @@
"name": "tests/integration/targets/grafana_datasource/tasks/postgres.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4ed316aab332c0dfcc005213ef28087ea49ed011c0a73bdd0e5f8481e9403de4",
+ "chksum_sha256": "bdd63b0df46202a010b8d06b6658c303ed3a8893733e807ff79dd13ca042d8b7",
"format": 1
},
{
@@ -1499,6 +1576,55 @@
"format": 1
},
{
+ "name": "tests/integration/targets/grafana_silence",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_silence/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_silence/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d7d3a06f224d1576e39fcc2083e33261f30e3ceac18506f17772d8bcb72315c2",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_silence/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_silence/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "330c281b5f69223f9f6292aab612dc3ebe4511c87b2f9748b386d1aaca2f5a89",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_silence/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b9aa6c8dadef0b4ce9cb08a05d0cf6c40f882d04f9e698bff795b26896e8853c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_silence/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "9c2b6df4d70c00df0765796d40ef1dbaa673984ce30a06c0e89569c1a7bcaea2",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/grafana_team",
"ftype": "dir",
"chksum_type": null,
@@ -1649,14 +1775,14 @@
"name": "tests/sanity/ignore-2.15.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0908af1f4e86722688b3f158cfa9cc81c931ef40c0a166c398f47a4af69a93f9",
+ "chksum_sha256": "743d0edd0ef882d4dca19699436e4ea09d2acb4e3418385c8e7b89cfaf6e415e",
"format": 1
},
{
"name": "tests/sanity/ignore-2.16.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0908af1f4e86722688b3f158cfa9cc81c931ef40c0a166c398f47a4af69a93f9",
+ "chksum_sha256": "743d0edd0ef882d4dca19699436e4ea09d2acb4e3418385c8e7b89cfaf6e415e",
"format": 1
},
{
@@ -1667,6 +1793,13 @@
"format": 1
},
{
+ "name": "tests/sanity/ignore-2.18.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "743d0edd0ef882d4dca19699436e4ea09d2acb4e3418385c8e7b89cfaf6e415e",
+ "format": 1
+ },
+ {
"name": "tests/sanity/ignore-2.9.txt",
"ftype": "file",
"chksum_type": "sha256",
@@ -1719,7 +1852,21 @@
"name": "tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ada20cb8aef9852aee7b79afddd78f144f813c9df55baf3b8adc1b3863a8e9db",
+ "chksum_sha256": "9564a8a336726addac97b13fb19813c1d97824d5ca65e6cdc55b9c940554c255",
+ "format": 1
+ },
+ {
+ "name": "tests/unit/modules/grafana/grafana_silence",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/unit/modules/grafana/grafana_silence/test_grafana_silence.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7b6a2c19e99236c08e318b25fb9ee100ee79f6ce07abd9853254f17c64d4c1c8",
"format": 1
},
{
@@ -1782,7 +1929,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e20df0ad2408ce9c311cf3bf18c99b2362c6eee388db48286b13be28ecedd8db",
+ "chksum_sha256": "70056dd2063eee72103302580afc77a58435eca179f53de3a2fefb3ad1798b09",
"format": 1
},
{
@@ -1796,7 +1943,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8e93c6a3ce656865252643666a94835e98d904107d7a678f0a74774445f91125",
+ "chksum_sha256": "f7151290ee62498487eb8bbb7fb07383ac448d6f192b519f069bd99f453d2385",
"format": 1
},
{
diff --git a/ansible_collections/community/grafana/MANIFEST.json b/ansible_collections/community/grafana/MANIFEST.json
index 71f9afdc1..2c1f7f1a0 100644
--- a/ansible_collections/community/grafana/MANIFEST.json
+++ b/ansible_collections/community/grafana/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "grafana",
- "version": "1.8.0",
+ "version": "1.9.1",
"authors": [
"R\u00e9mi REY (@rrey)",
"Thierry Sall\u00e9 (@seuf)"
@@ -25,7 +25,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "98a10c2378e1ad46d7031d895c557d33af10809314832b9e3af5c2e607099e0b",
+ "chksum_sha256": "4ff85c9d6729fe479fe05c2e56a41833f87286a8ee1af5b2b730ccd876c04ebb",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/grafana/README.md b/ansible_collections/community/grafana/README.md
index 6d23f1b96..9ba981ae7 100644
--- a/ansible_collections/community/grafana/README.md
+++ b/ansible_collections/community/grafana/README.md
@@ -31,13 +31,14 @@ Click on the name of a plugin or module to view that content's documentation:
- [grafana_plugin](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_plugin_module.html)
- [grafana_team](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_team_module.html)
- [grafana_user](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_user_module.html)
+ - [grafana_silence](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_silence_module.html)
## Supported Grafana versions
We aim at keeping the last 3 Major versions of Grafana tested.
This collection is currently testing the modules against following versions of Grafana:
```
-grafana_version: ["9.5.14", "8.5.27", "10.2.2"]
+grafana_version: ["8.5.27", "9.5.18", "10.4.2"]
```
## Installation and Usage
diff --git a/ansible_collections/community/grafana/changelogs/changelog.yaml b/ansible_collections/community/grafana/changelogs/changelog.yaml
index 465b42bc3..f8d3f898b 100644
--- a/ansible_collections/community/grafana/changelogs/changelog.yaml
+++ b/ansible_collections/community/grafana/changelogs/changelog.yaml
@@ -279,3 +279,36 @@ releases:
- 349-role-notification-channel.yml
- 350-python3.12.yml
release_date: '2024-02-21'
+ 1.9.0:
+ changes:
+ bugfixes:
+ - Handling of desired default state for first `grafana_datasource`
+ - Ignore `type` argument for diff comparison if `grafana-postgresq-datasource`
+ alias `postgres` is used
+ - Set umask for `grafana_plugin` command
+ minor_changes:
+ - Add new module `grafana_silence` to create and delete silences through the
+ API
+ - Add role components for `grafana_silence` module
+ - lookup - grafana_dashboards - add `validate_certs` and `ca_path` options to
+ plugin for custom certs validation
+ removed_features:
+ - removed deprecated `message` argument in `grafana_dashboard`
+ fragments:
+ - 353-docs-add-influxdb-flux-example.yml
+ - 354-fix-find-grafana-versions.yml
+ - 355-rm-dashboard-message-argument.yml
+ - 356-lookup-dashboards-add-custom-certs-verification-logic.yml
+ - 357-module-grafana-silence.yml
+ - 358-role-grafana-silence.yml
+ - 362-plugin-umask.yml
+ - 364-first-datasource-default.yml
+ release_date: '2024-04-30'
+ 1.9.1:
+ changes:
+ bugfixes:
+ - undo removed deprecated `message` argument in `grafana_dashboard`
+ fragments:
+ - 367-dashboard-undo-breaing-change-message.yml
+ - 368-molecule-pin-requests.yml
+ release_date: '2024-05-21'
diff --git a/ansible_collections/community/grafana/changelogs/fragments/353-docs-add-influxdb-flux-example.yml b/ansible_collections/community/grafana/changelogs/fragments/353-docs-add-influxdb-flux-example.yml
new file mode 100644
index 000000000..b3baa1bc5
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/353-docs-add-influxdb-flux-example.yml
@@ -0,0 +1,3 @@
+---
+trivial:
+ - grafana_datasource - (docs) add influxdb v2 flux example \ No newline at end of file
diff --git a/ansible_collections/community/grafana/changelogs/fragments/354-fix-find-grafana-versions.yml b/ansible_collections/community/grafana/changelogs/fragments/354-fix-find-grafana-versions.yml
new file mode 100644
index 000000000..4ba22771a
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/354-fix-find-grafana-versions.yml
@@ -0,0 +1,3 @@
+---
+trivial:
+ - fix find grafana versions python script comparation
diff --git a/ansible_collections/community/grafana/changelogs/fragments/355-rm-dashboard-message-argument.yml b/ansible_collections/community/grafana/changelogs/fragments/355-rm-dashboard-message-argument.yml
new file mode 100644
index 000000000..3f54afa5e
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/355-rm-dashboard-message-argument.yml
@@ -0,0 +1,3 @@
+---
+removed_features:
+ - removed deprecated `message` argument in `grafana_dashboard`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/356-lookup-dashboards-add-custom-certs-verification-logic.yml b/ansible_collections/community/grafana/changelogs/fragments/356-lookup-dashboards-add-custom-certs-verification-logic.yml
new file mode 100644
index 000000000..182822d9b
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/356-lookup-dashboards-add-custom-certs-verification-logic.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - lookup - grafana_dashboards - add `validate_certs` and `ca_path` options to plugin for custom certs validation
diff --git a/ansible_collections/community/grafana/changelogs/fragments/357-module-grafana-silence.yml b/ansible_collections/community/grafana/changelogs/fragments/357-module-grafana-silence.yml
new file mode 100644
index 000000000..a9ff03703
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/357-module-grafana-silence.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Add new module `grafana_silence` to create and delete silences through the API
diff --git a/ansible_collections/community/grafana/changelogs/fragments/358-role-grafana-silence.yml b/ansible_collections/community/grafana/changelogs/fragments/358-role-grafana-silence.yml
new file mode 100644
index 000000000..a72161f04
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/358-role-grafana-silence.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Add role components for `grafana_silence` module \ No newline at end of file
diff --git a/ansible_collections/community/grafana/changelogs/fragments/362-plugin-umask.yml b/ansible_collections/community/grafana/changelogs/fragments/362-plugin-umask.yml
new file mode 100644
index 000000000..cbef21ffd
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/362-plugin-umask.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - Set umask for `grafana_plugin` command
diff --git a/ansible_collections/community/grafana/changelogs/fragments/364-first-datasource-default.yml b/ansible_collections/community/grafana/changelogs/fragments/364-first-datasource-default.yml
new file mode 100644
index 000000000..3d39e9a0a
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/364-first-datasource-default.yml
@@ -0,0 +1,3 @@
+bugfixes:
+ - Handling of desired default state for first `grafana_datasource`
+ - Ignore `type` argument for diff comparison if `grafana-postgresq-datasource` alias `postgres` is used
diff --git a/ansible_collections/community/grafana/changelogs/fragments/367-dashboard-undo-breaing-change-message.yml b/ansible_collections/community/grafana/changelogs/fragments/367-dashboard-undo-breaing-change-message.yml
new file mode 100644
index 000000000..085ae0cb8
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/367-dashboard-undo-breaing-change-message.yml
@@ -0,0 +1,3 @@
+---
+bugfixes:
+ - undo removed deprecated `message` argument in `grafana_dashboard`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/368-molecule-pin-requests.yml b/ansible_collections/community/grafana/changelogs/fragments/368-molecule-pin-requests.yml
new file mode 100644
index 000000000..6e60e0348
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/368-molecule-pin-requests.yml
@@ -0,0 +1,3 @@
+---
+trivial:
+ - pin version of requests package for molecule tests
diff --git a/ansible_collections/community/grafana/hacking/check_fragment.sh b/ansible_collections/community/grafana/hacking/check_fragment.sh
index bf90cae65..3173b342f 100755
--- a/ansible_collections/community/grafana/hacking/check_fragment.sh
+++ b/ansible_collections/community/grafana/hacking/check_fragment.sh
@@ -1,7 +1,7 @@
-#!/bin/bash
+#!/usr/bin/env bash
function fail() {
- cat << EOF
+ cat <<EOF
Dear contributor,
Thank you for you Pull Request !
@@ -10,7 +10,7 @@ function fail() {
It will help your change be released faster !
Thank you !
EOF
- exit 1
+ exit 1
}
FRAGMENTS=$(git fetch && git diff --name-only --diff-filter=ACMRT origin/main..HEAD | grep "changelogs")
diff --git a/ansible_collections/community/grafana/hacking/find_grafana_versions.py b/ansible_collections/community/grafana/hacking/find_grafana_versions.py
index b31fc530a..716f877a8 100644
--- a/ansible_collections/community/grafana/hacking/find_grafana_versions.py
+++ b/ansible_collections/community/grafana/hacking/find_grafana_versions.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
import json
import requests
@@ -7,12 +7,12 @@ import requests
def get_by_major(version):
if version.startswith("v"):
version = version[1:]
- return (version[0], version, int(version.replace(".", "")))
+ return int(version.split(".")[0]), version, tuple(map(int, version.split(".")))
def get_grafana_releases():
r = requests.get(
- "https://api.github.com/repos/grafana/grafana/releases?per_page=50",
+ "https://api.github.com/repos/grafana/grafana/releases?per_page=100",
headers={"Accept": "application/vnd.github.v3+json"},
)
if r.status_code != 200:
@@ -20,19 +20,20 @@ def get_grafana_releases():
return r.json()
-by_major = {}
-
if __name__ == "__main__":
releases = get_grafana_releases()
- for item in releases:
- if item.get("prerelease"):
+ by_major = {}
+
+ for release in releases:
+ if release.get("prerelease") or any(
+ char in release.get("tag_name") for char in "-+"
+ ):
continue
- major, version, as_int = get_by_major(item.get("tag_name"))
- if major not in by_major.keys() or by_major[major]["as_int"] < as_int:
- by_major[major] = {"version": version, "as_int": as_int}
- latest_3_majors = sorted(list(by_major.keys()), reverse=True)[:3]
-
- latest_releases = []
- for idx in latest_3_majors:
- latest_releases.append(by_major[idx]["version"])
+ major, version, as_tuple = get_by_major(release.get("tag_name"))
+ if major not in by_major.keys() or by_major[major]["as_tuple"] < as_tuple:
+ by_major[major] = {"version": version, "as_tuple": as_tuple}
+
+ latest_3_majors = sorted(list(by_major.keys()))[:3]
+ latest_releases = [by_major[idx]["version"] for idx in latest_3_majors]
+
print(json.dumps(latest_releases))
diff --git a/ansible_collections/community/grafana/meta/runtime.yml b/ansible_collections/community/grafana/meta/runtime.yml
index 15f5554fc..d29f1dda8 100644
--- a/ansible_collections/community/grafana/meta/runtime.yml
+++ b/ansible_collections/community/grafana/meta/runtime.yml
@@ -11,3 +11,4 @@ action_groups:
- grafana_plugin
- grafana_team
- grafana_user
+ - grafana_silence
diff --git a/ansible_collections/community/grafana/molecule/default/converge.yml b/ansible_collections/community/grafana/molecule/default/converge.yml
index b1e1cf20b..4046e3369 100644
--- a/ansible_collections/community/grafana/molecule/default/converge.yml
+++ b/ansible_collections/community/grafana/molecule/default/converge.yml
@@ -45,4 +45,15 @@
path: test_dashboard.json
overwrite: true
+ grafana_silences:
+ - comment: molecule test
+ created_by: ansible
+ ends_at: "2030-01-01T00:00:00.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: false
+ name: environment
+ value: test
+ starts_at: "2029-12-31T23:23:59.000Z"
+
roles: [{role: community.grafana.grafana}]
diff --git a/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py b/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py
index c7fa31574..83ee250f7 100644
--- a/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py
+++ b/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py
@@ -41,6 +41,13 @@ options:
description: optional filter for dashboard search.
env:
- name: GRAFANA_DASHBOARD_SEARCH
+ validate_certs:
+ description: flag to control SSL certificate validation
+ type: boolean
+ default: true
+ ca_path:
+ description: string of the file system path to CA cert bundle to use for validation
+ type: string
"""
EXAMPLES = """
@@ -51,13 +58,25 @@ EXAMPLES = """
- name: get all grafana dashboards
set_fact:
grafana_dashboards: "{{ lookup('grafana_dashboard', 'grafana_url=http://grafana.company.com grafana_api_key=' ~ grafana_api_key) }}"
+
+- name: get project foo grafana dashboards (validate SSL certificates of the instance with custom CA Certificate Bundle)
+ set_fact:
+ grafana_dashboards: |
+ {{
+ lookup(
+ 'grafana_dashboard',
+ 'grafana_url=https://grafana.company.com grafana_user=admin grafana_password=admin search=foo',
+ validate_certs=true,
+ ca_path='/path/to/chain.crt'
+ )
+ }}
"""
import json
import os
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
-from ansible.module_utils.urls import basic_auth_header, open_url
+from ansible.module_utils.urls import basic_auth_header, open_url, SSLValidationError
from ansible.module_utils._text import to_native
from ansible.module_utils.six.moves.urllib.error import HTTPError
from ansible.utils.display import Display
@@ -96,13 +115,15 @@ class GrafanaAPIException(Exception):
class GrafanaAPI:
- def __init__(self, **kwargs):
+ def __init__(self, validate_certs, ca_path, **kwargs):
self.grafana_url = kwargs.get("grafana_url", ANSIBLE_GRAFANA_URL)
self.grafana_api_key = kwargs.get("grafana_api_key", ANSIBLE_GRAFANA_API_KEY)
self.grafana_user = kwargs.get("grafana_user", ANSIBLE_GRAFANA_USER)
self.grafana_password = kwargs.get("grafana_password", ANSIBLE_GRAFANA_PASSWORD)
self.grafana_org_id = kwargs.get("grafana_org_id", ANSIBLE_GRAFANA_ORG_ID)
self.search = kwargs.get("search", ANSIBLE_GRAFANA_DASHBOARD_SEARCH)
+ self.validate_certs = validate_certs
+ self.ca_path = ca_path
def grafana_switch_organisation(self, headers):
try:
@@ -110,12 +131,19 @@ class GrafanaAPI:
"%s/api/user/using/%s" % (self.grafana_url, self.grafana_org_id),
headers=headers,
method="POST",
+ validate_certs=self.validate_certs,
+ ca_path=self.ca_path,
)
except HTTPError as e:
raise GrafanaAPIException(
"Unable to switch to organization %s : %s"
% (self.grafana_org_id, to_native(e))
)
+ except SSLValidationError as e:
+ raise GrafanaAPIException(
+ "Unable to validate server's certificate with %s: %s"
+ % (self.ca_path, to_native(e))
+ )
if r.getcode() != 200:
raise GrafanaAPIException(
"Unable to switch to organization %s : %s"
@@ -153,13 +181,24 @@ class GrafanaAPI:
"%s/api/search?query=%s" % (self.grafana_url, self.search),
headers=headers,
method="GET",
+ validate_certs=self.validate_certs,
+ ca_path=self.ca_path,
)
else:
r = open_url(
- "%s/api/search/" % self.grafana_url, headers=headers, method="GET"
+ "%s/api/search/" % self.grafana_url,
+ headers=headers,
+ method="GET",
+ validate_certs=self.validate_certs,
+ ca_path=self.ca_path,
)
except HTTPError as e:
raise GrafanaAPIException("Unable to search dashboards : %s" % to_native(e))
+ except SSLValidationError as e:
+ raise GrafanaAPIException(
+ "Unable to validate server's certificate with %s: %s"
+ % (self.ca_path, to_native(e))
+ )
if r.getcode() == 200:
try:
dashboard_list = json.loads(r.read())
@@ -175,6 +214,7 @@ class GrafanaAPI:
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
+ self.set_options(var_options=variables, direct=kwargs)
grafana_args = terms[0].split(" ")
grafana_dict = {}
ret = []
@@ -189,7 +229,11 @@ class LookupModule(LookupBase):
)
grafana_dict[key] = value
- grafana = GrafanaAPI(**grafana_dict)
+ grafana = GrafanaAPI(
+ **grafana_dict,
+ validate_certs=self.get_option("validate_certs"),
+ ca_path=self.get_option("ca_path"),
+ )
ret = grafana.grafana_list_dashboards()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py b/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py
index 29cdbea7c..b011e5db1 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py
@@ -400,6 +400,23 @@ EXAMPLES = """
time_interval: ">10s"
tls_ca_cert: "/etc/ssl/certs/ca.pem"
+- name: Create influxdbv2 datasource using fluxql
+ community.grafana.grafana_datasource:
+ name: "datasource-influxdb-flux"
+ grafana_url: "https://grafana.company.com"
+ grafana_user: "admin"
+ grafana_password: "xxxxxx"
+ org_id: "1"
+ ds_type: "influxdb"
+ ds_url: "https://influx.company.com:8086"
+ additional_json_data:
+ version: "Flux"
+ organization: "organization"
+ defaultBucket: "bucket"
+ tlsSkipVerify: false
+ additional_secure_json_data:
+ token: "token"
+
- name: Create postgres datasource
community.grafana.grafana_datasource:
name: "datasource-postgres"
@@ -536,6 +553,9 @@ def compare_datasources(new, current, compareSecureData=True):
del current["password"]
if "basicAuthPassword" in current:
del current["basicAuthPassword"]
+ if current["type"] == "grafana-postgresql-datasource" and new["type"] == "postgres":
+ del current["type"]
+ del new["type"]
# check if secureJsonData should be compared
if not compareSecureData:
@@ -928,6 +948,9 @@ def main():
if ds is None:
grafana_iface.create_datasource(payload)
ds = grafana_iface.datasource_by_name(name)
+ if ds.get("isDefault") != module.params["is_default"]:
+ grafana_iface.update_datasource(ds.get("id"), payload)
+ ds = grafana_iface.datasource_by_name(name)
module.exit_json(
changed=True, datasource=ds, msg="Datasource %s created" % name
)
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py b/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py
index c510f02ba..db1e8553a 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py
@@ -223,7 +223,7 @@ def grafana_plugin(module, params):
else:
cmd = "{0} uninstall {1}".format(grafana_cli, params["name"])
- rc, stdout, stderr = module.run_command(cmd)
+ rc, stdout, stderr = module.run_command(cmd, umask=0o0022)
if rc == 0:
stdout_lines = stdout.split("\n")
for line in stdout_lines:
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_silence.py b/ansible_collections/community/grafana/plugins/modules/grafana_silence.py
new file mode 100644
index 000000000..35f54a3d8
--- /dev/null
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_silence.py
@@ -0,0 +1,369 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright: (c) 2023, flkhndlr (@flkhndlr)
+
+from __future__ import absolute_import, division, print_function
+
+DOCUMENTATION = """
+module: grafana_silence
+author:
+ - flkhndlr (@flkhndlr)
+version_added: "1.8.0"
+short_description: Manage Grafana Silences
+description:
+ - Create/delete Grafana Silences through the Alertmanager Silence API.
+requirements:
+ - The Alertmanager API is only available starting Grafana 8 and the module will fail if the server version is lower than version 8.
+options:
+ comment:
+ description:
+ - The comment that describes the silence.
+ required: true
+ type: str
+ created_by:
+ description:
+ - The author that creates the silence.
+ required: true
+ type: str
+ starts_at:
+ description:
+ - ISO 8601 Timestamp with milliseconds e.g. "2029-07-29T08:45:45.000Z" when the silence starts.
+ type: str
+ required: true
+ ends_at:
+ description:
+ - ISO 8601 Timestamp with milliseconds e.g. "2029-07-29T08:45:45.000Z" when the silence will end.
+ type: str
+ required: true
+ matchers:
+ description:
+ - List of matchers to select which alerts are affected by the silence.
+ type: list
+ elements: dict
+ required: true
+ state:
+ description:
+ - Delete the first occurrence of a silence with the same settings. Can be "absent" or "present".
+ default: present
+ type: str
+ choices: ["present", "absent"]
+ skip_version_check:
+ description:
+ - Skip Grafana version check and try to reach api endpoint anyway.
+ - This parameter can be useful if you enabled `hide_version` in grafana.ini
+ required: False
+ type: bool
+ default: False
+extends_documentation_fragment:
+- community.grafana.basic_auth
+- community.grafana.api_key
+"""
+
+EXAMPLES = """
+---
+- name: Create a silence
+ community.grafana.grafana_silence:
+ grafana_url: "https://grafana.example.com"
+ grafana_api_key: "{{ some_api_token_value }}"
+ comment: "a testcomment"
+ created_by: "me"
+ starts_at: "2029-07-29T08:45:45.000Z"
+ ends_at: "2029-07-29T08:55:45.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: true
+ name: environment
+ value: test
+ state: present
+
+- name: Delete a silence
+ community.grafana.grafana_silence:
+ grafana_url: "https://grafana.example.com"
+ grafana_api_key: "{{ some_api_token_value }}"
+ comment: "a testcomment"
+ created_by: "me"
+ starts_at: "2029-07-29T08:45:45.000Z"
+ ends_at: "2029-07-29T08:55:45.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: true
+ name: environment
+ value: test
+ state: absent
+"""
+
+RETURN = """
+---
+silence:
+ description: Information about the silence
+ returned: On success
+ type: complex
+ contains:
+ id:
+ description: The id of the silence
+ returned: success
+ type: str
+ sample:
+ - ec27df6b-ac3c-412f-ae0b-6e3e1f41c9c3
+ comment:
+ description: The comment of the silence
+ returned: success
+ type: str
+ sample:
+ - this is a test
+ createdBy:
+ description: The author of the silence
+ returned: success
+ type: str
+ sample:
+ - me
+ startsAt:
+ description: The begin timestamp of the silence
+ returned: success
+ type: str
+ sample:
+ - "2029-07-29T08:45:45.000Z"
+ endsAt:
+ description: The end timestamp of the silence
+ returned: success
+ type: str
+ sample:
+ - "2029-07-29T08:55:45.000Z"
+ matchers:
+ description: The matchers of the silence
+ returned: success
+ type: list
+ sample:
+ - [{"isEqual": true, "isRegex": true, "name": "environment", "value": "test"}]
+ status:
+ description: The status of the silence
+ returned: success
+ type: dict
+ sample:
+ - {"state": "pending"}
+ updatedAt:
+ description: The timestamp of the last update for the silence
+ returned: success
+ type: str
+ sample:
+ - "2023-07-27T13:27:33.042Z"
+"""
+
+import json
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.urls import fetch_url, basic_auth_header
+from ansible.module_utils._text import to_text
+from ansible_collections.community.grafana.plugins.module_utils import base
+
+__metaclass__ = type
+
+
+class GrafanaError(Exception):
+ pass
+
+
+class GrafanaSilenceInterface(object):
+ def __init__(self, module):
+ self._module = module
+ # {{{ Authentication header
+ self.headers = {"Content-Type": "application/json"}
+ module.params["force_basic_auth"] = True
+ if module.params.get("grafana_api_key", None):
+ self.headers["Authorization"] = (
+ "Bearer %s" % module.params["grafana_api_key"]
+ )
+ else:
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
+ # }}}
+ self.grafana_url = base.clean_url(module.params.get("url"))
+ if module.params.get("skip_version_check") is False:
+ try:
+ grafana_version = self.get_version()
+ except GrafanaError as e:
+ self._module.fail_json(failed=True, msg=to_text(e))
+ if grafana_version["major"] < 8:
+ self._module.fail_json(
+ failed=True,
+ msg="Silences API is available starting with Grafana v8",
+ )
+
+ def _send_request(self, url, data=None, headers=None, method="GET"):
+ if data is not None:
+ data = json.dumps(data)
+ if not headers:
+ headers = []
+
+ full_url = "{grafana_url}{path}".format(grafana_url=self.grafana_url, path=url)
+ resp, info = fetch_url(
+ self._module, full_url, data=data, headers=headers, method=method
+ )
+ status_code = info["status"]
+ if status_code == 404:
+ return None
+ elif status_code == 401:
+ self._module.fail_json(
+ failed=True,
+ msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url),
+ )
+ elif status_code == 403:
+ self._module.fail_json(failed=True, msg="Permission Denied")
+ elif status_code in [200, 202]:
+ return self._module.from_json(resp.read())
+ elif status_code == 400:
+ self._module.fail_json(failed=True, msg=info)
+ self._module.fail_json(
+ failed=True, msg="Grafana Silences API answered with HTTP %d" % status_code
+ )
+
+ def get_version(self):
+ url = "/api/health"
+ response = self._send_request(
+ url, data=None, headers=self.headers, method="GET"
+ )
+ version = response.get("version")
+ if version is not None:
+ major, minor, rev = version.split(".")
+ return {"major": int(major), "minor": int(minor), "rev": int(rev)}
+ raise GrafanaError("Failed to retrieve version from '%s'" % url)
+
+ def create_silence(self, comment, created_by, starts_at, ends_at, matchers):
+ url = "/api/alertmanager/grafana/api/v2/silences"
+ silence = dict(
+ comment=comment,
+ createdBy=created_by,
+ endsAt=ends_at,
+ matchers=matchers,
+ startsAt=starts_at,
+ )
+ response = self._send_request(
+ url, data=silence, headers=self.headers, method="POST"
+ )
+ if self.get_version()["major"] == 8:
+ response["silenceID"] = response["id"]
+ response.pop("id", None)
+ return response
+
+ def get_silence(self, comment, created_by, starts_at, ends_at, matchers):
+ url = "/api/alertmanager/grafana/api/v2/silences"
+
+ responses = self._send_request(url, headers=self.headers, method="GET")
+
+ for response in responses:
+ if (
+ response["comment"] == comment
+ and response["createdBy"] == created_by
+ and response["startsAt"] == starts_at
+ and response["endsAt"] == ends_at
+ and response["matchers"] == matchers
+ ):
+ return response
+ return None
+
+ def get_silence_by_id(self, silence_id):
+ url = "/api/alertmanager/grafana/api/v2/silence/{SilenceId}".format(
+ SilenceId=silence_id
+ )
+ response = self._send_request(url, headers=self.headers, method="GET")
+ return response
+
+ def get_silences(self):
+ url = "/api/alertmanager/grafana/api/v2/silences"
+ response = self._send_request(url, headers=self.headers, method="GET")
+ return response
+
+ def delete_silence(self, silence_id):
+ url = "/api/alertmanager/grafana/api/v2/silence/{SilenceId}".format(
+ SilenceId=silence_id
+ )
+ response = self._send_request(url, headers=self.headers, method="DELETE")
+ return response
+
+
+def setup_module_object():
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=False,
+ required_together=base.grafana_required_together(),
+ mutually_exclusive=base.grafana_mutually_exclusive(),
+ )
+ return module
+
+
+argument_spec = base.grafana_argument_spec()
+argument_spec.update(
+ comment=dict(type="str", required=True),
+ state=dict(type="str", choices=["present", "absent"], default="present"),
+ created_by=dict(type="str", required=True),
+ starts_at=dict(type="str", required=True),
+ ends_at=dict(type="str", required=True),
+ matchers=dict(type="list", elements="dict", required=True),
+ skip_version_check=dict(type="bool", default=False),
+)
+
+
+def main():
+
+ module = setup_module_object()
+ comment = module.params["comment"]
+ created_by = module.params["created_by"]
+ starts_at = module.params["starts_at"]
+ ends_at = module.params["ends_at"]
+ matchers = module.params["matchers"]
+ state = module.params["state"]
+
+ changed = False
+ failed = False
+ grafana_iface = GrafanaSilenceInterface(module)
+
+ silence = grafana_iface.get_silence(
+ comment, created_by, starts_at, ends_at, matchers
+ )
+
+ if state == "present":
+
+ if not silence:
+ silence = grafana_iface.create_silence(
+ comment, created_by, starts_at, ends_at, matchers
+ )
+ silence = grafana_iface.get_silence_by_id(silence["silenceID"])
+ changed = True
+ else:
+ module.exit_json(
+ failed=failed,
+ changed=changed,
+ msg="Silence with same parameters already exists! eg. '%s'"
+ % silence["id"],
+ )
+ elif state == "absent":
+ if silence:
+ grafana_iface.delete_silence(silence["id"])
+ changed = True
+ else:
+ module.exit_json(
+ failed=False,
+ changed=changed,
+ msg="Silence does not exist",
+ )
+ module.exit_json(failed=failed, changed=changed, silence=silence)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/community/grafana/roles/grafana/README.md b/ansible_collections/community/grafana/roles/grafana/README.md
index f46434edf..f76e687fc 100644
--- a/ansible_collections/community/grafana/roles/grafana/README.md
+++ b/ansible_collections/community/grafana/roles/grafana/README.md
@@ -163,6 +163,13 @@ Configure Grafana organizations, dashboards, folders, datasources, teams and use
| webhook_password | no |
| webhook_url | no |
| webhook_username | no |
+| [**grafana_silence**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_silence_module.html) |
+| comment | yes |
+| created_by | yes |
+| ends_at | yes |
+| matchers | yes |
+| starts_at | yes |
+| state | no |
## Example Playbook
diff --git a/ansible_collections/community/grafana/roles/grafana/defaults/main.yml b/ansible_collections/community/grafana/roles/grafana/defaults/main.yml
index 6a84370d3..9756a1331 100644
--- a/ansible_collections/community/grafana/roles/grafana/defaults/main.yml
+++ b/ansible_collections/community/grafana/roles/grafana/defaults/main.yml
@@ -7,3 +7,4 @@ grafana_datasources: []
grafana_folders: []
grafana_dashboards: []
grafana_notification_channels: []
+grafana_silences: []
diff --git a/ansible_collections/community/grafana/roles/grafana/meta/main.yml b/ansible_collections/community/grafana/roles/grafana/meta/main.yml
index 47d4af5b7..b5df42193 100644
--- a/ansible_collections/community/grafana/roles/grafana/meta/main.yml
+++ b/ansible_collections/community/grafana/roles/grafana/meta/main.yml
@@ -2,7 +2,7 @@
galaxy_info:
role_name: grafana
author: community
- description: Configure Grafana organizations, dashboards, folders, datasources, teams and users
+ description: Configure Grafana organizations, dashboards, folders, datasources, silences, teams and users
license: GPLv3
min_ansible_version: "2.14"
galaxy_tags: [grafana, monitoring]
diff --git a/ansible_collections/community/grafana/roles/grafana/tasks/main.yml b/ansible_collections/community/grafana/roles/grafana/tasks/main.yml
index 82bbc633d..1665a8562 100644
--- a/ansible_collections/community/grafana/roles/grafana/tasks/main.yml
+++ b/ansible_collections/community/grafana/roles/grafana/tasks/main.yml
@@ -201,3 +201,15 @@
loop: "{{ grafana_dashboards }}"
loop_control: {loop_var: dashboard}
tags: [dashboard, molecule-idempotence-notest]
+
+ - name: Manage silence
+ community.grafana.grafana_silence:
+ comment: "{{ silence.comment }}"
+ created_by: "{{ silence.created_by }}"
+ starts_at: "{{ silence.starts_at }}"
+ ends_at: "{{ silence.ends_at }}"
+ matchers: "{{ silence.matchers }}"
+ state: "{{ silence.state | default(omit) }}"
+ loop: "{{ grafana_silences }}"
+ loop_control: {loop_var: silence}
+ tags: silence
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml
index ff05b93f5..be5873574 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml
@@ -286,6 +286,32 @@
- result.datasource.secureJsonFields.secureTest == true
- result.diff.after.secureJsonData is defined
+- name: Delete elasticsearch legacy datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: datasource/elasticLegacy
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed
+
+- name: Delete elasticsearch legacy datasource (idempotency)
+ register: result
+ community.grafana.grafana_datasource:
+ name: datasource/elasticLegacy
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - not result.changed
+
- name: Delete elasticsearch datasource
register: result
community.grafana.grafana_datasource:
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml
index b07bc752b..8945e2bdd 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml
@@ -56,7 +56,7 @@
- result.datasource.jsonData.timescaledb == true
- result.datasource.name == 'datasource-postgres'
- result.datasource.orgId == 1
- - result.datasource.type == 'postgres'
+ - result.datasource.type in ['postgres', 'grafana-postgresql-datasource']
- result.datasource.url == 'postgres.company.com:5432'
- result.datasource.user == 'postgres'
- result.datasource.withCredentials == false
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/defaults/main.yml
new file mode 100644
index 000000000..4abf9bb43
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/runme.sh
new file mode 100755
index 000000000..867afb0d3
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/site.yml
new file mode 100644
index 000000000..791582277
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_silence
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_silence
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/tasks/main.yml
new file mode 100644
index 000000000..ad4cfa25d
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_silence/tasks/main.yml
@@ -0,0 +1,89 @@
+---
+- name: Create new silence
+ community.grafana.grafana_silence:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ comment: "a testcomment"
+ created_by: "me"
+ starts_at: "2029-07-29T08:45:45.000Z"
+ ends_at: "2029-07-29T08:55:45.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: true
+ name: environment
+ value: test
+ state: present
+ register: result
+- assert:
+ that:
+ - "result.changed == true"
+ - "result.failed == false"
+ - "result.silence.id != ''"
+
+- name: Check idempotency on silence creation
+ community.grafana.grafana_silence:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ comment: "a testcomment"
+ created_by: "me"
+ starts_at: "2029-07-29T08:45:45.000Z"
+ ends_at: "2029-07-29T08:55:45.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: true
+ name: environment
+ value: test
+ state: present
+ register: result
+- assert:
+ that:
+ - "result.changed == false"
+ - "result.msg != ''"
+
+- name: Delete the silence
+ community.grafana.grafana_silence:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ comment: "a testcomment"
+ created_by: "me"
+ starts_at: "2029-07-29T08:45:45.000Z"
+ ends_at: "2029-07-29T08:55:45.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: true
+ name: environment
+ value: test
+ state: absent
+ register: result
+- assert:
+ that:
+ - "result.changed == true"
+ - "result.failed == false"
+ - "result.silence.id != ''"
+ - - "result.silence.createdBy != 'me'"
+
+- name: Check idempotency on silence deletion
+ community.grafana.grafana_silence:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ comment: "a testcomment"
+ created_by: "me"
+ starts_at: "2029-07-29T08:45:45.000Z"
+ ends_at: "2029-07-29T08:55:45.000Z"
+ matchers:
+ - isEqual: true
+ isRegex: true
+ name: environment
+ value: test
+ state: absent
+ register: result
+ ignore_errors: yes
+- assert:
+ that:
+ - "result.changed == false"
+ - "result.failed == false"
+ - "result.msg == 'Silence does not exist'" \ No newline at end of file
diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.15.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.15.txt
index 5c82494f9..0a40a23d5 100644
--- a/ansible_collections/community/grafana/tests/sanity/ignore-2.15.txt
+++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.15.txt
@@ -1,4 +1 @@
plugins/modules/grafana_dashboard.py validate-modules:invalid-argument-name
-tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py pep8:W291
-hacking/check_fragment.sh shebang
-hacking/find_grafana_versions.py shebang
diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt
index 5c82494f9..0a40a23d5 100644
--- a/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt
+++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt
@@ -1,4 +1 @@
plugins/modules/grafana_dashboard.py validate-modules:invalid-argument-name
-tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py pep8:W291
-hacking/check_fragment.sh shebang
-hacking/find_grafana_versions.py shebang
diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.18.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.18.txt
new file mode 100644
index 000000000..0a40a23d5
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.18.txt
@@ -0,0 +1 @@
+plugins/modules/grafana_dashboard.py validate-modules:invalid-argument-name
diff --git a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py
index ec691a467..7cc04a99a 100644
--- a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py
+++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py
@@ -21,7 +21,7 @@ Restart grafana after installing plugins . <service grafana-server restart>
def run_command_install_zip():
STDERR = ""
STDOUT = """
-installing alexanderzobnin-grafana-zabbix @
+installing alexanderzobnin-grafana-zabbix @
from: /home/grafana//alexanderzobnin-grafana-zabbix-v3.10.5-1-g2219691.zip
into: /var/lib/grafana/plugins
diff --git a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_silence/test_grafana_silence.py b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_silence/test_grafana_silence.py
new file mode 100644
index 000000000..96522c2af
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_silence/test_grafana_silence.py
@@ -0,0 +1,211 @@
+from __future__ import absolute_import, division, print_function
+
+from unittest import TestCase
+from unittest.mock import patch
+from ansible_collections.community.grafana.plugins.modules import grafana_silence
+from ansible.module_utils._text import to_bytes
+from ansible.module_utils import basic
+from ansible.module_utils.urls import basic_auth_header
+import json
+
+__metaclass__ = type
+
+
+class MockedReponse(object):
+ def __init__(self, data):
+ self.data = data
+
+ def read(self):
+ return self.data
+
+
+def exit_json(*args, **kwargs):
+ """function to patch over exit_json; package return data into an exception"""
+ if "changed" not in kwargs:
+ kwargs["changed"] = False
+ raise AnsibleExitJson(kwargs)
+
+
+def fail_json(*args, **kwargs):
+ """function to patch over fail_json; package return data into an exception"""
+ kwargs["failed"] = True
+ raise AnsibleFailJson(kwargs)
+
+
+class AnsibleExitJson(Exception):
+ """Exception class to be raised by module.exit_json and caught by the test case"""
+
+ pass
+
+
+class AnsibleFailJson(Exception):
+ """Exception class to be raised by module.fail_json and caught by the test case"""
+
+ pass
+
+
+def set_module_args(args):
+ """prepare arguments so that they will be picked up during module creation"""
+ args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
+ basic._ANSIBLE_ARGS = to_bytes(args)
+
+
+def silence_deleted_resp():
+ server_response = json.dumps({"message": "silence deleted"})
+ return (MockedReponse(server_response), {"status": 200})
+
+
+def silence_created_resp():
+ server_response = json.dumps({"silenceID": "470b7116-8f06-4bb6-9e6c-6258aa92218e"})
+ return (MockedReponse(server_response), {"status": 200})
+
+
+def silence_get_resp():
+ server_response = json.dumps([], sort_keys=True)
+ return (MockedReponse(server_response), {"status": 200})
+
+
+def get_silence_by_id_resp():
+ server_response = json.dumps([], sort_keys=True)
+ return (MockedReponse(server_response), {"status": 200})
+
+
+def get_version_resp():
+ return {"major": 10, "minor": 0, "rev": 0}
+
+
+class GrafanaSilenceTest(TestCase):
+ def setUp(self):
+ self.authorization = basic_auth_header("admin", "changeme")
+ self.mock_module_helper = patch.multiple(
+ basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json
+ )
+ self.mock_module_helper.start()
+ self.addCleanup(self.mock_module_helper.stop)
+
+ # create a new silence
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_silence.GrafanaSilenceInterface.get_silence"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_silence.GrafanaSilenceInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_silence.fetch_url"
+ )
+ def test_create_silence_new_silence(
+ self, mock_fetch_url, mock_get_version, mock_get_silence
+ ):
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "changeme",
+ "comment": "a testcomment",
+ "created_by": "me",
+ "starts_at": "2029-07-29T08:45:45.000Z",
+ "ends_at": "2029-07-29T08:55:45.000Z",
+ "matchers": [
+ {
+ "isEqual": True,
+ "isRegex": True,
+ "name": "environment",
+ "value": "test",
+ }
+ ],
+ "state": "present",
+ }
+ )
+ module = grafana_silence.setup_module_object()
+ mock_get_version.return_value = get_version_resp()
+ mock_fetch_url.return_value = silence_created_resp()
+ mock_get_silence.return_value = silence_get_resp()
+
+ grafana_iface = grafana_silence.GrafanaSilenceInterface(module)
+ result = grafana_iface.create_silence(
+ "a testcomment",
+ "me",
+ "2029-07-29T08:45:45.000Z",
+ "2029-07-29T08:55:45.000Z",
+ [
+ {
+ "isEqual": True,
+ "isRegex": True,
+ "name": "environment",
+ "value": "test",
+ }
+ ],
+ )
+ mock_fetch_url.assert_called_once_with(
+ module,
+ "https://grafana.example.com/api/alertmanager/grafana/api/v2/silences",
+ data=json.dumps(
+ {
+ "comment": "a testcomment",
+ "createdBy": "me",
+ "startsAt": "2029-07-29T08:45:45.000Z",
+ "endsAt": "2029-07-29T08:55:45.000Z",
+ "matchers": [
+ {
+ "isEqual": True,
+ "isRegex": True,
+ "name": "environment",
+ "value": "test",
+ }
+ ],
+ },
+ sort_keys=True,
+ ),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="POST",
+ )
+ self.assertEquals(result, {"silenceID": "470b7116-8f06-4bb6-9e6c-6258aa92218e"})
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_silence.GrafanaSilenceInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_silence.fetch_url"
+ )
+ def test_delete_silence(self, mock_fetch_url, mock_get_version):
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "changeme",
+ "comment": "a testcomment",
+ "created_by": "me",
+ "ends_at": "2029-07-29T08:55:45.000Z",
+ "matchers": [
+ {
+ "isEqual": True,
+ "isRegex": True,
+ "name": "environment",
+ "value": "test",
+ }
+ ],
+ "starts_at": "2029-07-29T08:45:45.000Z",
+ "state": "present",
+ }
+ )
+ module = grafana_silence.setup_module_object()
+ mock_fetch_url.return_value = silence_deleted_resp()
+ mock_get_version.return_value = get_version_resp()
+
+ grafana_iface = grafana_silence.GrafanaSilenceInterface(module)
+ silence_id = "470b7116-8f06-4bb6-9e6c-6258aa92218e"
+ result = grafana_iface.delete_silence(silence_id)
+ mock_fetch_url.assert_called_once_with(
+ module,
+ "https://grafana.example.com/api/alertmanager/grafana/api/v2/silence/470b7116-8f06-4bb6-9e6c-6258aa92218e",
+ data=None,
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="DELETE",
+ )
+ self.assertEquals(result, {"message": "silence deleted"})
diff --git a/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml b/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml
index 6aadd1b4f..fe133e857 100644
--- a/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml
@@ -26,53 +26,29 @@ jobs:
ansible:
# It's important that Sanity is tested against all stable-X.Y branches
# Testing against `devel` may fail as new tests are added.
- - stable-2.9
- - stable-2.10
- - stable-2.11
- - stable-2.12
- - stable-2.13
- stable-2.14
- stable-2.15
- stable-2.16
- stable-2.17
- devel
- # Ansible-test on various stable branches does not yet work well with cgroups v2.
- # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
- # image for these stable branches. The list of branches where this is necessary will
- # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
- # for the latest list.
- runs-on: >-
- ${{ contains(fromJson(
- '["stable-2.9", "stable-2.10", "stable-2.11"]'
- ), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
+ runs-on: ubuntu-latest
steps:
- name: Perform sanity testing
uses: felixfontein/ansible-test-gh-action@main
with:
ansible-core-version: ${{ matrix.ansible }}
testing-type: sanity
+ pre-test-cmd: >-
+ git clone --depth=1 --single-branch --branch stable-1 https://github.com/ansible-collections/community.library_inventory_filtering.git ../../community/library_inventory_filtering_v1
units:
- # Ansible-test on various stable branches does not yet work well with cgroups v2.
- # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
- # image for these stable branches. The list of branches where this is necessary will
- # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28
- # for the latest list.
- runs-on: >-
- ${{ contains(fromJson(
- '["stable-2.9", "stable-2.10", "stable-2.11"]'
- ), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }}
+ runs-on: ubuntu-latest
name: Units (â’¶${{ matrix.ansible }})
strategy:
# As soon as the first unit test fails, cancel the others to free up the CI queue
fail-fast: true
matrix:
ansible:
- - stable-2.9
- - stable-2.10
- - stable-2.11
- - stable-2.12
- - stable-2.13
- stable-2.14
- stable-2.15
- stable-2.16
@@ -87,6 +63,6 @@ jobs:
with:
ansible-core-version: ${{ matrix.ansible }}
testing-type: units
- # NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
- pre-test-cmd: >-
- git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ../../community/internal_test_tools
+ test-deps: >-
+ git+https://github.com/ansible-collections/community.internal_test_tools.git,main
+ git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1
diff --git a/ansible_collections/community/hrobot/.github/workflows/ee.yml b/ansible_collections/community/hrobot/.github/workflows/ee.yml
index c4e751a79..ba356758d 100644
--- a/ansible_collections/community/hrobot/.github/workflows/ee.yml
+++ b/ansible_collections/community/hrobot/.github/workflows/ee.yml
@@ -62,22 +62,6 @@ jobs:
ansible_runner: ansible-runner
base_image: quay.io/centos/centos:stream9
pre_base: '"#"'
- - name: ansible-core 2.13 @ RHEL UBI 8
- ansible_core: https://github.com/ansible/ansible/archive/stable-2.13.tar.gz
- ansible_runner: ansible-runner
- other_deps: |2
- python_interpreter:
- package_system: python39 python39-pip python39-wheel python39-cryptography
- base_image: docker.io/redhat/ubi8:latest
- pre_base: '"#"'
- - name: ansible-core 2.12 @ CentOS Stream 8
- ansible_core: https://github.com/ansible/ansible/archive/stable-2.12.tar.gz
- ansible_runner: ansible-runner
- other_deps: |2
- python_interpreter:
- package_system: python39 python39-pip python39-wheel python39-cryptography
- base_image: quay.io/centos/centos:stream8
- pre_base: '"#"'
runs-on: ubuntu-latest
steps:
- name: Check out code
@@ -88,7 +72,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Install ansible-builder and ansible-navigator
run: pip install ansible-builder ansible-navigator
diff --git a/ansible_collections/community/hrobot/.github/workflows/extra-tests.yml b/ansible_collections/community/hrobot/.github/workflows/extra-tests.yml
index ee8964c3f..9b9e56009 100644
--- a/ansible_collections/community/hrobot/.github/workflows/extra-tests.yml
+++ b/ansible_collections/community/hrobot/.github/workflows/extra-tests.yml
@@ -33,15 +33,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: '3.12'
- name: Install ansible-core
run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
- name: Install collection dependencies
- run: git clone --depth=1 --single-branch https://github.com/ansible-collections/community.internal_test_tools.git ./ansible_collections/community/internal_test_tools
- # NOTE: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
- # run: ansible-galaxy collection install community.internal_test_tools -p .
+ run: >-
+ ansible-galaxy collection install -p .
+ git+https://github.com/ansible-collections/community.internal_test_tools.git,main
+ git+https://github.com/ansible-collections/community.library_inventory_filtering.git,stable-1
- name: Run sanity tests
run: ../../community/internal_test_tools/tools/run.py --color
diff --git a/ansible_collections/community/hrobot/CHANGELOG.md b/ansible_collections/community/hrobot/CHANGELOG.md
index fec73109e..d995f8d6d 100644
--- a/ansible_collections/community/hrobot/CHANGELOG.md
+++ b/ansible_collections/community/hrobot/CHANGELOG.md
@@ -2,77 +2,111 @@
**Topics**
-- <a href="#v1-9-2">v1\.9\.2</a>
+- <a href="#v2-0-0">v2\.0\.0</a>
- <a href="#release-summary">Release Summary</a>
+ - <a href="#major-changes">Major Changes</a>
+ - <a href="#minor-changes">Minor Changes</a>
+ - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
+ - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
+- <a href="#v1-9-2">v1\.9\.2</a>
+ - <a href="#release-summary-1">Release Summary</a>
- <a href="#bugfixes">Bugfixes</a>
- <a href="#v1-9-1">v1\.9\.1</a>
- - <a href="#release-summary-1">Release Summary</a>
+ - <a href="#release-summary-2">Release Summary</a>
- <a href="#security-fixes">Security Fixes</a>
- <a href="#v1-9-0">v1\.9\.0</a>
- - <a href="#release-summary-2">Release Summary</a>
- - <a href="#minor-changes">Minor Changes</a>
+ - <a href="#release-summary-3">Release Summary</a>
+ - <a href="#minor-changes-1">Minor Changes</a>
- <a href="#deprecated-features">Deprecated Features</a>
- <a href="#v1-8-2">v1\.8\.2</a>
- - <a href="#release-summary-3">Release Summary</a>
+ - <a href="#release-summary-4">Release Summary</a>
- <a href="#bugfixes-1">Bugfixes</a>
- <a href="#v1-8-1">v1\.8\.1</a>
- - <a href="#release-summary-4">Release Summary</a>
+ - <a href="#release-summary-5">Release Summary</a>
- <a href="#known-issues">Known Issues</a>
- <a href="#v1-8-0">v1\.8\.0</a>
- - <a href="#release-summary-5">Release Summary</a>
- - <a href="#major-changes">Major Changes</a>
- - <a href="#minor-changes-1">Minor Changes</a>
-- <a href="#v1-7-0">v1\.7\.0</a>
- <a href="#release-summary-6">Release Summary</a>
+ - <a href="#major-changes-1">Major Changes</a>
+ - <a href="#minor-changes-2">Minor Changes</a>
+- <a href="#v1-7-0">v1\.7\.0</a>
+ - <a href="#release-summary-7">Release Summary</a>
- <a href="#new-modules">New Modules</a>
- <a href="#v1-6-0">v1\.6\.0</a>
- - <a href="#release-summary-7">Release Summary</a>
- - <a href="#minor-changes-2">Minor Changes</a>
-- <a href="#v1-5-2">v1\.5\.2</a>
- <a href="#release-summary-8">Release Summary</a>
- <a href="#minor-changes-3">Minor Changes</a>
-- <a href="#v1-5-1">v1\.5\.1</a>
+- <a href="#v1-5-2">v1\.5\.2</a>
- <a href="#release-summary-9">Release Summary</a>
-- <a href="#v1-5-0">v1\.5\.0</a>
- - <a href="#release-summary-10">Release Summary</a>
- <a href="#minor-changes-4">Minor Changes</a>
-- <a href="#v1-4-0">v1\.4\.0</a>
+- <a href="#v1-5-1">v1\.5\.1</a>
+ - <a href="#release-summary-10">Release Summary</a>
+- <a href="#v1-5-0">v1\.5\.0</a>
- <a href="#release-summary-11">Release Summary</a>
- <a href="#minor-changes-5">Minor Changes</a>
-- <a href="#v1-3-1">v1\.3\.1</a>
+- <a href="#v1-4-0">v1\.4\.0</a>
- <a href="#release-summary-12">Release Summary</a>
+ - <a href="#minor-changes-6">Minor Changes</a>
+- <a href="#v1-3-1">v1\.3\.1</a>
+ - <a href="#release-summary-13">Release Summary</a>
- <a href="#bugfixes-2">Bugfixes</a>
- <a href="#v1-3-0">v1\.3\.0</a>
- - <a href="#release-summary-13">Release Summary</a>
- - <a href="#minor-changes-6">Minor Changes</a>
+ - <a href="#release-summary-14">Release Summary</a>
+ - <a href="#minor-changes-7">Minor Changes</a>
- <a href="#bugfixes-3">Bugfixes</a>
- <a href="#v1-2-3">v1\.2\.3</a>
- - <a href="#release-summary-14">Release Summary</a>
-- <a href="#v1-2-2">v1\.2\.2</a>
- <a href="#release-summary-15">Release Summary</a>
+- <a href="#v1-2-2">v1\.2\.2</a>
+ - <a href="#release-summary-16">Release Summary</a>
- <a href="#bugfixes-4">Bugfixes</a>
- <a href="#v1-2-1">v1\.2\.1</a>
- - <a href="#release-summary-16">Release Summary</a>
- - <a href="#minor-changes-7">Minor Changes</a>
-- <a href="#v1-2-0">v1\.2\.0</a>
- <a href="#release-summary-17">Release Summary</a>
- <a href="#minor-changes-8">Minor Changes</a>
+- <a href="#v1-2-0">v1\.2\.0</a>
+ - <a href="#release-summary-18">Release Summary</a>
+ - <a href="#minor-changes-9">Minor Changes</a>
- <a href="#new-modules-1">New Modules</a>
- <a href="#v1-1-1">v1\.1\.1</a>
- - <a href="#release-summary-18">Release Summary</a>
+ - <a href="#release-summary-19">Release Summary</a>
- <a href="#bugfixes-5">Bugfixes</a>
- <a href="#v1-1-0">v1\.1\.0</a>
- - <a href="#release-summary-19">Release Summary</a>
+ - <a href="#release-summary-20">Release Summary</a>
- <a href="#new-plugins">New Plugins</a>
- <a href="#inventory">Inventory</a>
- <a href="#v1-0-0">v1\.0\.0</a>
- - <a href="#release-summary-20">Release Summary</a>
- - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
+ - <a href="#release-summary-21">Release Summary</a>
+ - <a href="#breaking-changes--porting-guide-1">Breaking Changes / Porting Guide</a>
+
+<a id="v2-0-0"></a>
+## v2\.0\.0
+
+<a id="release-summary"></a>
+### Release Summary
+
+\.\.\.
+
+<a id="major-changes"></a>
+### Major Changes
+
+* The <code>community\.hrobot</code> collection now depends on the <code>community\.library\_inventory\_filtering\_v1</code> collection\. This utility collection provides host filtering functionality for inventory plugins\. If you use the Ansible community package\, both collections are included and you do not have to do anything special\. If you install the collection with <code>ansible\-galaxy collection install</code>\, it will be installed automatically\. If you install the collection by copying the files of the collection to a place where ansible\-core can find it\, for example by cloning the git repository\, you need to make sure that you also have to install the dependency if you are using the inventory plugin \([https\://github\.com/ansible\-collections/community\.hrobot/pull/101](https\://github\.com/ansible\-collections/community\.hrobot/pull/101)\)\.
+
+<a id="minor-changes"></a>
+### Minor Changes
+
+* robot inventory plugin \- add <code>filter</code> option which allows to include and exclude hosts based on Jinja2 conditions \([https\://github\.com/ansible\-collections/community\.hrobot/pull/101](https\://github\.com/ansible\-collections/community\.hrobot/pull/101)\)\.
+
+<a id="breaking-changes--porting-guide"></a>
+### Breaking Changes / Porting Guide
+
+* robot inventory plugin \- <code>filters</code> is now no longer an alias of <code>simple\_filters</code>\, but a new\, different option \([https\://github\.com/ansible\-collections/community\.hrobot/pull/101](https\://github\.com/ansible\-collections/community\.hrobot/pull/101)\)\.
+
+<a id="removed-features-previously-deprecated"></a>
+### Removed Features \(previously deprecated\)
+
+* The collection no longer supports Ansible\, ansible\-base\, and ansible\-core releases that are currently End of Life at the time of the 2\.0\.0 release\. This means that Ansible 2\.9\, ansible\-base 2\.10\, ansible\-core 2\.11\, ansible\-core 2\.12\, ansible\-core 2\.13\, and ansible\-core 2\.14 are no longer supported\. The collection might still work with these versions\, but it can stop working at any moment without advance notice\, and this will not be considered a bug \([https\://github\.com/ansible\-collections/community\.hrobot/pull/101](https\://github\.com/ansible\-collections/community\.hrobot/pull/101)\)\.
<a id="v1-9-2"></a>
## v1\.9\.2
-<a id="release-summary"></a>
+<a id="release-summary-1"></a>
### Release Summary
Bugfix release\.
@@ -85,7 +119,7 @@ Bugfix release\.
<a id="v1-9-1"></a>
## v1\.9\.1
-<a id="release-summary-1"></a>
+<a id="release-summary-2"></a>
### Release Summary
Bugfix release\.
@@ -98,12 +132,12 @@ Bugfix release\.
<a id="v1-9-0"></a>
## v1\.9\.0
-<a id="release-summary-2"></a>
+<a id="release-summary-3"></a>
### Release Summary
Feature and maintenance release\.
-<a id="minor-changes"></a>
+<a id="minor-changes-1"></a>
### Minor Changes
* robot inventory plugin \- the <code>filters</code> option has been renamed to <code>simple\_filters</code>\. The old name still works until community\.hrobot 2\.0\.0\. Then it will change to allow more complex filtering with the <code>community\.library\_inventory\_filtering\_v1</code> collection\'s functionality \([https\://github\.com/ansible\-collections/community\.hrobot/pull/94](https\://github\.com/ansible\-collections/community\.hrobot/pull/94)\)\.
@@ -116,7 +150,7 @@ Feature and maintenance release\.
<a id="v1-8-2"></a>
## v1\.8\.2
-<a id="release-summary-3"></a>
+<a id="release-summary-4"></a>
### Release Summary
Maintenance release with updated documentation\.
@@ -129,7 +163,7 @@ Maintenance release with updated documentation\.
<a id="v1-8-1"></a>
## v1\.8\.1
-<a id="release-summary-4"></a>
+<a id="release-summary-5"></a>
### Release Summary
Maintenance release with updated documentation\.
@@ -150,17 +184,17 @@ for the rendered HTML version of the documentation of the latest release\.
<a id="v1-8-0"></a>
## v1\.8\.0
-<a id="release-summary-5"></a>
+<a id="release-summary-6"></a>
### Release Summary
Feature release for the Hetzner firewall changes\.
-<a id="major-changes"></a>
+<a id="major-changes-1"></a>
### Major Changes
* firewall \- Hetzner added output rules support to the firewall\. This change unfortunately means that using old versions of the firewall module will always set the output rule list to empty\, thus disallowing the server to send out packets \([https\://github\.com/ansible\-collections/community\.hrobot/issues/75](https\://github\.com/ansible\-collections/community\.hrobot/issues/75)\, [https\://github\.com/ansible\-collections/community\.hrobot/pull/76](https\://github\.com/ansible\-collections/community\.hrobot/pull/76)\)\.
-<a id="minor-changes-1"></a>
+<a id="minor-changes-2"></a>
### Minor Changes
* firewall\, firewall\_info \- add <code>filter\_ipv6</code> and <code>rules\.output</code> output to support the new IPv6 filtering and output rules features \([https\://github\.com/ansible\-collections/community\.hrobot/issues/75](https\://github\.com/ansible\-collections/community\.hrobot/issues/75)\, [https\://github\.com/ansible\-collections/community\.hrobot/pull/76](https\://github\.com/ansible\-collections/community\.hrobot/pull/76)\)\.
@@ -169,7 +203,7 @@ Feature release for the Hetzner firewall changes\.
<a id="v1-7-0"></a>
## v1\.7\.0
-<a id="release-summary-6"></a>
+<a id="release-summary-7"></a>
### Release Summary
Feature release\.
@@ -182,12 +216,12 @@ Feature release\.
<a id="v1-6-0"></a>
## v1\.6\.0
-<a id="release-summary-7"></a>
+<a id="release-summary-8"></a>
### Release Summary
Feature release with improved documentation\.
-<a id="minor-changes-2"></a>
+<a id="minor-changes-3"></a>
### Minor Changes
* Added a <code>community\.hrobot\.robot</code> module defaults group / action group\. Use with <code>group/community\.hrobot\.robot</code> to provide options for all Hetzner Robot modules \([https\://github\.com/ansible\-collections/community\.hrobot/pull/65](https\://github\.com/ansible\-collections/community\.hrobot/pull/65)\)\.
@@ -195,12 +229,12 @@ Feature release with improved documentation\.
<a id="v1-5-2"></a>
## v1\.5\.2
-<a id="release-summary-8"></a>
+<a id="release-summary-9"></a>
### Release Summary
Maintenance release with a documentation improvement\.
-<a id="minor-changes-3"></a>
+<a id="minor-changes-4"></a>
### Minor Changes
* The collection repository conforms to the [REUSE specification](https\://reuse\.software/spec/) except for the changelog fragments \([https\://github\.com/ansible\-collections/community\.hrobot/pull/60](https\://github\.com/ansible\-collections/community\.hrobot/pull/60)\)\.
@@ -208,7 +242,7 @@ Maintenance release with a documentation improvement\.
<a id="v1-5-1"></a>
## v1\.5\.1
-<a id="release-summary-9"></a>
+<a id="release-summary-10"></a>
### Release Summary
Maintenance release with small documentation fixes\.
@@ -216,12 +250,12 @@ Maintenance release with small documentation fixes\.
<a id="v1-5-0"></a>
## v1\.5\.0
-<a id="release-summary-10"></a>
+<a id="release-summary-11"></a>
### Release Summary
Maintenance release changing the way licenses are declared\. No functional changes\.
-<a id="minor-changes-4"></a>
+<a id="minor-changes-5"></a>
### Minor Changes
* All software licenses are now in the <code>LICENSES/</code> directory of the collection root\. Moreover\, <code>SPDX\-License\-Identifier\:</code> is used to declare the applicable license for every file that is not automatically generated \([https\://github\.com/ansible\-collections/community\.hrobot/pull/52](https\://github\.com/ansible\-collections/community\.hrobot/pull/52)\)\.
@@ -229,12 +263,12 @@ Maintenance release changing the way licenses are declared\. No functional chang
<a id="v1-4-0"></a>
## v1\.4\.0
-<a id="release-summary-11"></a>
+<a id="release-summary-12"></a>
### Release Summary
Feature release\.
-<a id="minor-changes-5"></a>
+<a id="minor-changes-6"></a>
### Minor Changes
* robot inventory plugin \- allow to template <code>hetzner\_user</code> and <code>hetzner\_password</code> \([https\://github\.com/ansible\-collections/community\.hrobot/pull/49](https\://github\.com/ansible\-collections/community\.hrobot/pull/49)\)\.
@@ -242,7 +276,7 @@ Feature release\.
<a id="v1-3-1"></a>
## v1\.3\.1
-<a id="release-summary-12"></a>
+<a id="release-summary-13"></a>
### Release Summary
Maintenance release\.
@@ -255,12 +289,12 @@ Maintenance release\.
<a id="v1-3-0"></a>
## v1\.3\.0
-<a id="release-summary-13"></a>
+<a id="release-summary-14"></a>
### Release Summary
Feature and bugfix release\.
-<a id="minor-changes-6"></a>
+<a id="minor-changes-7"></a>
### Minor Changes
* Prepare collection for inclusion in an Execution Environment by declaring its dependencies \([https\://github\.com/ansible\-collections/community\.hrobot/pull/45](https\://github\.com/ansible\-collections/community\.hrobot/pull/45)\)\.
@@ -273,7 +307,7 @@ Feature and bugfix release\.
<a id="v1-2-3"></a>
## v1\.2\.3
-<a id="release-summary-14"></a>
+<a id="release-summary-15"></a>
### Release Summary
Docs update release\.
@@ -281,7 +315,7 @@ Docs update release\.
<a id="v1-2-2"></a>
## v1\.2\.2
-<a id="release-summary-15"></a>
+<a id="release-summary-16"></a>
### Release Summary
Bugfix release\.
@@ -294,12 +328,12 @@ Bugfix release\.
<a id="v1-2-1"></a>
## v1\.2\.1
-<a id="release-summary-16"></a>
+<a id="release-summary-17"></a>
### Release Summary
Maintenance release\.
-<a id="minor-changes-7"></a>
+<a id="minor-changes-8"></a>
### Minor Changes
* Generic module HTTP support code \- fix usage of <code>fetch\_url</code> with changes in latest ansible\-core <code>devel</code> branch \([https\://github\.com/ansible\-collections/community\.hrobot/pull/30](https\://github\.com/ansible\-collections/community\.hrobot/pull/30)\)\.
@@ -307,12 +341,12 @@ Maintenance release\.
<a id="v1-2-0"></a>
## v1\.2\.0
-<a id="release-summary-17"></a>
+<a id="release-summary-18"></a>
### Release Summary
Feature release with multiple new modules\.
-<a id="minor-changes-8"></a>
+<a id="minor-changes-9"></a>
### Minor Changes
* Avoid internal ansible\-core module\_utils in favor of equivalent public API available since at least Ansible 2\.9 \([https\://github\.com/ansible\-collections/community\.hrobot/pull/18](https\://github\.com/ansible\-collections/community\.hrobot/pull/18)\)\.
@@ -334,7 +368,7 @@ Feature release with multiple new modules\.
<a id="v1-1-1"></a>
## v1\.1\.1
-<a id="release-summary-18"></a>
+<a id="release-summary-19"></a>
### Release Summary
Bugfix release which reduces the number of HTTPS queries for the modules and plugins\.
@@ -347,7 +381,7 @@ Bugfix release which reduces the number of HTTPS queries for the modules and plu
<a id="v1-1-0"></a>
## v1\.1\.0
-<a id="release-summary-19"></a>
+<a id="release-summary-20"></a>
### Release Summary
Release with a new inventory plugin\.
@@ -363,12 +397,12 @@ Release with a new inventory plugin\.
<a id="v1-0-0"></a>
## v1\.0\.0
-<a id="release-summary-20"></a>
+<a id="release-summary-21"></a>
### Release Summary
The <code>community\.hrobot</code> continues the work on the Hetzner Robot modules from their state in <code>community\.general</code> 1\.2\.0\. The changes listed here are thus relative to the modules <code>community\.general\.hetzner\_\*</code>\.
-<a id="breaking-changes--porting-guide"></a>
+<a id="breaking-changes--porting-guide-1"></a>
### Breaking Changes / Porting Guide
* firewall \- now requires the [ipaddress](https\://pypi\.org/project/ipaddress/) library \([https\://github\.com/ansible\-collections/community\.hrobot/pull/2](https\://github\.com/ansible\-collections/community\.hrobot/pull/2)\)\.
diff --git a/ansible_collections/community/hrobot/CHANGELOG.rst b/ansible_collections/community/hrobot/CHANGELOG.rst
index fdb9c4a23..18407d29f 100644
--- a/ansible_collections/community/hrobot/CHANGELOG.rst
+++ b/ansible_collections/community/hrobot/CHANGELOG.rst
@@ -4,6 +4,34 @@ Community Hetzner Robot Collection Release Notes
.. contents:: Topics
+v2.0.0
+======
+
+Release Summary
+---------------
+
+...
+
+Major Changes
+-------------
+
+- The ``community.hrobot`` collection now depends on the ``community.library_inventory_filtering_v1`` collection. This utility collection provides host filtering functionality for inventory plugins. If you use the Ansible community package, both collections are included and you do not have to do anything special. If you install the collection with ``ansible-galaxy collection install``, it will be installed automatically. If you install the collection by copying the files of the collection to a place where ansible-core can find it, for example by cloning the git repository, you need to make sure that you also have to install the dependency if you are using the inventory plugin (https://github.com/ansible-collections/community.hrobot/pull/101).
+
+Minor Changes
+-------------
+
+- robot inventory plugin - add ``filter`` option which allows to include and exclude hosts based on Jinja2 conditions (https://github.com/ansible-collections/community.hrobot/pull/101).
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- robot inventory plugin - ``filters`` is now no longer an alias of ``simple_filters``, but a new, different option (https://github.com/ansible-collections/community.hrobot/pull/101).
+
+Removed Features (previously deprecated)
+----------------------------------------
+
+- The collection no longer supports Ansible, ansible-base, and ansible-core releases that are currently End of Life at the time of the 2.0.0 release. This means that Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14 are no longer supported. The collection might still work with these versions, but it can stop working at any moment without advance notice, and this will not be considered a bug (https://github.com/ansible-collections/community.hrobot/pull/101).
+
v1.9.2
======
diff --git a/ansible_collections/community/hrobot/FILES.json b/ansible_collections/community/hrobot/FILES.json
index e5964a9b0..1f4f1fc3f 100644
--- a/ansible_collections/community/hrobot/FILES.json
+++ b/ansible_collections/community/hrobot/FILES.json
@@ -25,7 +25,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6745e283a9f1578108ad5f14efed6558cdfb1a25c5e04426836b343baa7f1ccc",
+ "chksum_sha256": "597f0f97a3486451bdf364c20f5b4b899486c0350422811b76fc57922ee50f6a",
"format": 1
},
{
@@ -46,14 +46,14 @@
"name": ".github/workflows/ee.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "03c5a4a0a65ebe7d5b9683d95f2752cdbbcac4d4b8cca513d4332d80dd1c79c2",
+ "chksum_sha256": "bd2cbf8bd79099e4f848a41d3fbf00e5b6d14037cfd2e9a2b4674d36c3ef0ae4",
"format": 1
},
{
"name": ".github/workflows/extra-tests.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3d4972a65972c0091b7343e287eba10382716e29fd184091b1f8b4df4892fe44",
+ "chksum_sha256": "445358ff7ba521cc629303462ab71eccd79aa840b17b90b1c7f4d1dab82fffe7",
"format": 1
},
{
@@ -137,7 +137,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e941d53c423339dae173424865a5f4e2c892aa52818bebd6999d2444ff2188a3",
+ "chksum_sha256": "44809fb2e5dc28dd9948e07f4987e0785b1835f56d82129d2feabd0ac6acd699",
"format": 1
},
{
@@ -200,7 +200,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "24fe3900ecea43c7ba9092f959869454c77877400c6af713fb56f0c8465d564e",
+ "chksum_sha256": "dcc07fa47601566d57bf94bccf30fd3d495865324899761ce689e96f6b6ce6e9",
"format": 1
},
{
@@ -242,7 +242,7 @@
"name": "plugins/inventory/robot.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9ebb90b3fa1ce6a294b1d56b7d943e86ada342b9e288bdd416bde2e39e9989db",
+ "chksum_sha256": "db25dddf103d07d71c2f20727b40d7ced1420056095573074a96ed969297e972",
"format": 1
},
{
@@ -683,7 +683,7 @@
"name": "tests/unit/plugins/inventory/test_robot.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e77768bf19cc0b1743641419d4b0360b6725b8dbb4e79d2ecacfac69d0886db9",
+ "chksum_sha256": "9dd685da29afd94c09b74f057e78c98326c8b4931b5bbe4e86bc42e0a2e0c8f2",
"format": 1
},
{
@@ -823,7 +823,7 @@
"name": "CHANGELOG.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ec9612359cac38411b264cb53d67607a383a08d1a2bffc3ff84cdb1d9ad1de4c",
+ "chksum_sha256": "86fd0f752604f3fa70164f00acf0ad9e5d1567c6499701e555eeeedd59c6fbc7",
"format": 1
},
{
@@ -837,7 +837,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "84b7a7e9f7b8280abe9151db53d4fc3235b37db19686030e8d8fd000513e41ad",
+ "chksum_sha256": "e8ca25b706ccb628b73cd623cc1720c34df09756bc716aa07827c161648207a1",
"format": 1
},
{
@@ -858,7 +858,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "df4f5e5e0c88eb6caf14a6b2d3916a5849ac18a2ee6c748d0276d1788d145911",
+ "chksum_sha256": "4a16caa53d97e1924daaabaf372ab085aba6fc95af3cca830d1eda04f22ae41d",
"format": 1
},
{
diff --git a/ansible_collections/community/hrobot/MANIFEST.json b/ansible_collections/community/hrobot/MANIFEST.json
index 1ac2e2da3..65cba09e0 100644
--- a/ansible_collections/community/hrobot/MANIFEST.json
+++ b/ansible_collections/community/hrobot/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "hrobot",
- "version": "1.9.2",
+ "version": "2.0.0",
"authors": [
"Felix Fontein (github.com/felixfontein)"
],
@@ -20,7 +20,9 @@
"BSD-2-Clause"
],
"license_file": null,
- "dependencies": {},
+ "dependencies": {
+ "community.library_inventory_filtering_v1": ">=1.0.0"
+ },
"repository": "https://github.com/ansible-collections/community.hrobot",
"documentation": "https://docs.ansible.com/ansible/devel/collections/community/hrobot/",
"homepage": "https://github.com/ansible-collections/community.hrobot",
@@ -30,7 +32,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a5c77f86ec2889eb57623d0ccd7ffbae9635537c46dc4539324e8da92b7ddf27",
+ "chksum_sha256": "47a01d4394191e0a36c408e3add9b1a0434bfcf4fd39a7d11ba1d7b4cd2f39b8",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/hrobot/README.md b/ansible_collections/community/hrobot/README.md
index bdc481de9..8ef8be19b 100644
--- a/ansible_collections/community/hrobot/README.md
+++ b/ansible_collections/community/hrobot/README.md
@@ -15,7 +15,7 @@ Please note that this collection does **not** support Windows targets.
## Tested with Ansible
-Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, and ansible-core 2.17 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
+Tested with the current ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, and ansible-core 2.17 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
## External requirements
diff --git a/ansible_collections/community/hrobot/changelogs/changelog.yaml b/ansible_collections/community/hrobot/changelogs/changelog.yaml
index eca36fc8f..1862813f3 100644
--- a/ansible_collections/community/hrobot/changelogs/changelog.yaml
+++ b/ansible_collections/community/hrobot/changelogs/changelog.yaml
@@ -290,3 +290,34 @@ releases:
- 1.9.2.yml
- 102-unsafe.yml
release_date: '2024-04-16'
+ 2.0.0:
+ changes:
+ breaking_changes:
+ - robot inventory plugin - ``filters`` is now no longer an alias of ``simple_filters``,
+ but a new, different option (https://github.com/ansible-collections/community.hrobot/pull/101).
+ major_changes:
+ - The ``community.hrobot`` collection now depends on the ``community.library_inventory_filtering_v1``
+ collection. This utility collection provides host filtering functionality
+ for inventory plugins. If you use the Ansible community package, both collections
+ are included and you do not have to do anything special. If you install the
+ collection with ``ansible-galaxy collection install``, it will be installed
+ automatically. If you install the collection by copying the files of the collection
+ to a place where ansible-core can find it, for example by cloning the git
+ repository, you need to make sure that you also have to install the dependency
+ if you are using the inventory plugin (https://github.com/ansible-collections/community.hrobot/pull/101).
+ minor_changes:
+ - robot inventory plugin - add ``filter`` option which allows to include and
+ exclude hosts based on Jinja2 conditions (https://github.com/ansible-collections/community.hrobot/pull/101).
+ release_summary: '...
+
+ '
+ removed_features:
+ - The collection no longer supports Ansible, ansible-base, and ansible-core
+ releases that are currently End of Life at the time of the 2.0.0 release.
+ This means that Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core
+ 2.12, ansible-core 2.13, and ansible-core 2.14 are no longer supported. The
+ collection might still work with these versions, but it can stop working at
+ any moment without advance notice, and this will not be considered a bug (https://github.com/ansible-collections/community.hrobot/pull/101).
+ fragments:
+ - 2.0.0.yml
+ release_date: '2024-05-11'
diff --git a/ansible_collections/community/hrobot/meta/runtime.yml b/ansible_collections/community/hrobot/meta/runtime.yml
index 7ea33e019..77e68505d 100644
--- a/ansible_collections/community/hrobot/meta/runtime.yml
+++ b/ansible_collections/community/hrobot/meta/runtime.yml
@@ -3,7 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
-requires_ansible: '>=2.9.10'
+requires_ansible: '>=2.14.0'
action_groups:
robot:
- boot
diff --git a/ansible_collections/community/hrobot/plugins/inventory/robot.py b/ansible_collections/community/hrobot/plugins/inventory/robot.py
index 409c90992..675be7f2c 100644
--- a/ansible_collections/community/hrobot/plugins/inventory/robot.py
+++ b/ansible_collections/community/hrobot/plugins/inventory/robot.py
@@ -25,6 +25,7 @@ DOCUMENTATION = r"""
- ansible.builtin.constructed
- ansible.builtin.inventory_cache
- community.hrobot.robot
+ - community.library_inventory_filtering_v1.inventory_filter
notes:
- The O(hetzner_user) and O(hetzner_password) options can be templated.
options:
@@ -43,12 +44,13 @@ DOCUMENTATION = r"""
- A dictionary of filter value pairs.
- Available filters are listed here are keys of server like C(status) or C(server_ip).
- See U(https://robot.your-server.de/doc/webservice/en.html#get-server) for all values that can be used.
- - This option has been renamed from O(filters) to O(simple_filters) in community.hrobot 1.9.0.
- The old name can still be used until community.hrobot 2.0.0.
+ - This option used to be called O(filters) before community.hrobot 2.0.0. It has been renamed from
+ O(filters) to O(simple_filters) in community.hrobotdns 1.9.0, and the old name was still available
+ as an alias until community.hrobot 2.0.0. O(filters) is now used for something else.
type: dict
default: {}
- aliases:
- - filters
+ filters:
+ version_added: 2.0.0
"""
EXAMPLES = r"""
@@ -58,12 +60,18 @@ plugin: community.hrobot.robot
filters:
status: ready
-# Example showing encrypted credentials
+# Example showing encrypted credentials and using filters
# (This assumes that Mozilla sops was used to encrypt keys/hetzner.sops.yaml, which contains two values
# hetzner_username and hetzner_password. Needs the community.sops collection to decode that file.)
plugin: community.hrobot.robot
hetzner_user: '{{ (lookup("community.sops.sops", "keys/hetzner.sops.yaml") | from_yaml).hetzner_username }}'
hetzner_password: '{{ (lookup("community.sops.sops", "keys/hetzner.sops.yaml") | from_yaml).hetzner_password }}'
+filters:
+ # Accept all servers in FSN1-DC1 and FSN1-DC2
+ - include: >-
+ hrobot_dc in ["FSN1-DC1", "FSN1-DC2"]
+ # Exclude all servers that didn't match any of the above filters
+ - exclude: true
# Example using constructed features to create groups
plugin: community.hrobot.robot
@@ -86,6 +94,8 @@ from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cachea
from ansible.template import Templar
from ansible.utils.display import Display
+from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host
+
from ansible_collections.community.hrobot.plugins.module_utils.robot import (
BASE_URL,
PluginException,
@@ -114,18 +124,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
def parse(self, inventory, loader, path, cache=True):
super(InventoryModule, self).parse(inventory, loader, path)
servers = {}
- orig_config = self._read_config_data(path)
+ self._read_config_data(path)
self.load_cache_plugin()
cache_key = self.get_cache_key(path)
- if 'filters' in orig_config:
- display.deprecated(
- 'The `filters` option of the community.hrobot.robot inventory plugin has been renamed to `simple_filters`. '
- 'The old name will stop working in community.hrobot 2.0.0.',
- collection_name='community.hrobot',
- version='2.0.0',
- )
-
self.templar = Templar(loader=loader)
# cache may be True or False at this point to indicate if the inventory is being refreshed
@@ -156,16 +158,26 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self.populate(servers)
def populate(self, servers):
- filters = self.get_option('simple_filters')
+ simple_filters = self.get_option('simple_filters')
+ filters = parse_filters(self.get_option('filters'))
strict = self.get_option('strict')
server_lists = []
for server in servers:
s = server['server']
server_name = s.get('server_name') or s.get('server_ip') or str(s['server_number'])
- matched = self.filter(s, filters)
+ matched = self.filter(s, simple_filters)
if not matched:
continue
+ facts = {}
+ if 'server_ip' in s:
+ facts['ansible_host'] = make_unsafe(s['server_ip'])
+ for hostvar, hostval in s.items():
+ facts["{0}_{1}".format('hrobot', hostvar)] = make_unsafe(hostval)
+
+ if not filter_host(self, server_name, facts, filters):
+ continue
+
if server_name in server_lists:
display.warning('Two of your Hetzner servers use the same server name ({0}). '
'Please make sure that your server names are unique. '
@@ -174,10 +186,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self.inventory.add_host(server_name)
server_lists.append(server_name)
- if 'server_ip' in s:
- self.inventory.set_variable(server_name, 'ansible_host', make_unsafe(s['server_ip']))
- for hostvar, hostval in s.items():
- self.inventory.set_variable(server_name, "{0}_{1}".format('hrobot', hostvar), make_unsafe(hostval))
+ for key, value in facts.items():
+ self.inventory.set_variable(server_name, key, value)
# Composed variables
server_vars = self.inventory.get_host(server_name).get_vars()
@@ -189,9 +199,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# Create groups based on variable values and add the corresponding hosts to it
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), server, server_name, strict=strict)
- def filter(self, server, filters):
+ def filter(self, server, simple_filters):
matched = True
- for key, value in filters.items():
+ for key, value in simple_filters.items():
if server.get(key) != value:
matched = False
break
diff --git a/ansible_collections/community/hrobot/tests/unit/plugins/inventory/test_robot.py b/ansible_collections/community/hrobot/tests/unit/plugins/inventory/test_robot.py
index c10524f7e..eb8c52a8f 100644
--- a/ansible_collections/community/hrobot/tests/unit/plugins/inventory/test_robot.py
+++ b/ansible_collections/community/hrobot/tests/unit/plugins/inventory/test_robot.py
@@ -63,6 +63,8 @@ def inventory():
def get_option(option):
if option == 'simple_filters':
return {}
+ if option == 'filters':
+ return []
if option == 'hetzner_user':
return 'test'
if option == 'hetzner_password':
diff --git a/ansible_collections/community/mongodb/CHANGELOG.rst b/ansible_collections/community/mongodb/CHANGELOG.rst
index efe8e7a47..6bb98a0a9 100644
--- a/ansible_collections/community/mongodb/CHANGELOG.rst
+++ b/ansible_collections/community/mongodb/CHANGELOG.rst
@@ -4,6 +4,19 @@ Community.MongoDB Release Notes
.. contents:: Topics
+v1.7.4:
+=========
+
+Release Summary
+----------------
+
+This release is a maintenance release.
+
+Minor Changes
+-------------
+
+- 644 - mongodb_shell - Add ssl/tls options.
+
v1.7.3:
=========
diff --git a/ansible_collections/community/mongodb/FILES.json b/ansible_collections/community/mongodb/FILES.json
index f94843a96..ababe90bd 100644
--- a/ansible_collections/community/mongodb/FILES.json
+++ b/ansible_collections/community/mongodb/FILES.json
@@ -95,7 +95,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d7e3cf154cb0134ac530a4ec411e69e5d21ed2d500e5bc219ddc983625779f64",
+ "chksum_sha256": "804197bdc9c22ac7d7217004da5b984dfaf3cc90193eb0c7c955e85ca7c6510f",
"format": 1
},
{
@@ -368,7 +368,7 @@
"name": "plugins/modules/mongodb_shell.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9ca34eb689335da81215f97904a77f42eac95406f01986ea61b36e3f71f2b963",
+ "chksum_sha256": "643fc68eecb01e46cc69b5a47212e6b24f8ec04e74e0849db1db4f8003da4ad1",
"format": 1
},
{
@@ -2370,7 +2370,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dd8f971dbb162351148320dbed19aa7fb8e49aa683205224ea51defff77fe3f3",
+ "chksum_sha256": "32fd83c1f49e6ee9cc991c66b52c524a2816652658a1baeef5808f0ef6cfde9b",
"format": 1
},
{
@@ -2384,7 +2384,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "65a9319fb932c67923de4f992f3119feae296f85411b5cffb00aa04b93a44f29",
+ "chksum_sha256": "94362aca9a294e736fa71510ec537ca0db93c2018496d44a681abb0bc6fa6fd8",
"format": 1
},
{
diff --git a/ansible_collections/community/mongodb/MANIFEST.json b/ansible_collections/community/mongodb/MANIFEST.json
index aa6035a5e..c9ddd1e0d 100644
--- a/ansible_collections/community/mongodb/MANIFEST.json
+++ b/ansible_collections/community/mongodb/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "mongodb",
- "version": "1.7.3",
+ "version": "1.7.4",
"authors": [
"Ansible (https://github.com/ansible)",
"Rhys Campbell (https://github.com/rhysmeister)",
@@ -36,7 +36,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "72e4c95bc97cb1a5e68ca35b8c8dffa1bda536bae32ca66bdaa676747ba0244f",
+ "chksum_sha256": "0c106846fbfff63ae2d1cc38e3528523a6a8b63a5e7662c7732c71a251d97a92",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/mongodb/README.md b/ansible_collections/community/mongodb/README.md
index 66e50daef..6ce5a3a41 100644
--- a/ansible_collections/community/mongodb/README.md
+++ b/ansible_collections/community/mongodb/README.md
@@ -145,6 +145,7 @@ cd git/ansible_collections/community
```bash
git clone https://github.com/ansible-collections/community.mongodb.git ./mongodb
git clone https://github.com/ansible-collections/community.general.git ./general
+git clone https://github.com/ansible-collections/community.crypto.git ./crypto
```
* Create and activate a virtual environment.
diff --git a/ansible_collections/community/mongodb/changelogs/changelog.yaml b/ansible_collections/community/mongodb/changelogs/changelog.yaml
index 641f7c62f..26cac23f0 100644
--- a/ansible_collections/community/mongodb/changelogs/changelog.yaml
+++ b/ansible_collections/community/mongodb/changelogs/changelog.yaml
@@ -335,3 +335,8 @@ releases:
This release is a maintenance release.
bugfixes:
- 641 - mongodb_mongod - Add test condition for storage option in mongod.conf template file.
+ 1.7.4:
+ release_summary: |
+ This release is a maintenance release.
+ minor_changes:
+ - 644 - mongodb_shell - Add ssl/tls options.
diff --git a/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py b/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py
index 618cafae9..b9c9462b0 100644
--- a/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py
+++ b/ansible_collections/community/mongodb/plugins/modules/mongodb_shell.py
@@ -24,6 +24,7 @@ description:
extends_documentation_fragment:
- community.mongodb.login_options
+ - community.mongodb.ssl_options
options:
mongo_cmd:
@@ -195,7 +196,7 @@ import os
__metaclass__ = type
from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import (
- mongodb_common_argument_spec
+ load_mongocnf, mongodb_common_argument_spec
)
from ansible_collections.community.mongodb.plugins.module_utils.mongodb_shell import (
@@ -208,7 +209,7 @@ from ansible_collections.community.mongodb.plugins.module_utils.mongodb_shell im
def main():
- argument_spec = mongodb_common_argument_spec(ssl_options=False)
+ argument_spec = mongodb_common_argument_spec(ssl_options=True)
argument_spec.update(
mongo_cmd=dict(type='str', default="mongosh"),
file=dict(type='str', required=False),
@@ -267,16 +268,34 @@ def main():
omit = module.params['omit']
+ username = module.params['login_user']
+ password = module.params['login_password']
+
+ credentials = load_mongocnf()
+ if credentials:
+ if not username:
+ username = credentials['user']
+ if not password:
+ password = credentials['password']
+
args = add_arg_to_cmd(args, "--host", module.params['login_host'], omit=omit)
args = add_arg_to_cmd(args, "--port", module.params['login_port'], omit=omit)
- args = add_arg_to_cmd(args, "--username", module.params['login_user'], omit=omit)
- args = add_arg_to_cmd(args, "--password", module.params['login_password'], omit=omit)
+ args = add_arg_to_cmd(args, "--username", username, omit=omit)
+ args = add_arg_to_cmd(args, "--password", password, omit=omit)
args = add_arg_to_cmd(args, "--authenticationDatabase", module.params['login_database'], omit=omit)
+ args = add_arg_to_cmd(args, "--authenticationMechanism", module.params['auth_mechanism'], omit=omit)
args = add_arg_to_cmd(args, "--eval", module.params['eval'], omit=omit)
args = add_arg_to_cmd(args, "--nodb", None, module.params['nodb'], omit=omit)
args = add_arg_to_cmd(args, "--norc", None, module.params['norc'], omit=omit)
args = add_arg_to_cmd(args, "--quiet", None, module.params['quiet'], omit=omit)
+ args = add_arg_to_cmd(args, "--tls", None, module.params['ssl'], omit=omit)
+ args = add_arg_to_cmd(args, "--tlsAllowInvalidCertificates", None, module.params['ssl_cert_reqs'] in ('CERT_NONE', 'CERT_OPTIONAL'), omit=omit)
+ args = add_arg_to_cmd(args, "--tlsCAFile", module.params['ssl_ca_certs'], omit=omit)
+ args = add_arg_to_cmd(args, "--tlsCRLFile", module.params['ssl_crlfile'], omit=omit)
+ args = add_arg_to_cmd(args, "--tlsCertificateKeyFile", module.params['ssl_keyfile'], omit=omit)
+ args = add_arg_to_cmd(args, "--tlsCertificateKeyFilePassword", module.params['ssl_pem_passphrase'], omit=omit)
+
additional_args = module.params['additional_args']
if additional_args is not None:
for key, value in additional_args.items():
diff --git a/ansible_collections/community/okd/.config/ansible-lint.yml b/ansible_collections/community/okd/.config/ansible-lint.yml
new file mode 100644
index 000000000..7c92b22ab
--- /dev/null
+++ b/ansible_collections/community/okd/.config/ansible-lint.yml
@@ -0,0 +1,5 @@
+---
+profile: production
+exclude_paths:
+ - molecule
+ - tests/sanity
diff --git a/ansible_collections/community/okd/.github/patchback.yml b/ansible_collections/community/okd/.github/patchback.yml
new file mode 100644
index 000000000..113fc5294
--- /dev/null
+++ b/ansible_collections/community/okd/.github/patchback.yml
@@ -0,0 +1,4 @@
+---
+backport_branch_prefix: patchback/backports/
+backport_label_prefix: backport-
+target_branch_prefix: stable-
diff --git a/ansible_collections/community/okd/.github/settings.yml b/ansible_collections/community/okd/.github/settings.yml
new file mode 100644
index 000000000..35f78e110
--- /dev/null
+++ b/ansible_collections/community/okd/.github/settings.yml
@@ -0,0 +1,6 @@
+---
+# DO NOT MODIFY
+
+# Settings: https://probot.github.io/apps/settings/
+# Pull settings from https://github.com/ansible-collections/.github/blob/master/.github/settings.yml
+_extends: ".github"
diff --git a/ansible_collections/community/okd/.github/stale.yml b/ansible_collections/community/okd/.github/stale.yml
new file mode 100644
index 000000000..230cf78a6
--- /dev/null
+++ b/ansible_collections/community/okd/.github/stale.yml
@@ -0,0 +1,60 @@
+---
+# Configuration for probot-stale - https://github.com/probot/stale
+
+# Number of days of inactivity before an Issue or Pull Request becomes stale
+daysUntilStale: 90
+
+# Number of days of inactivity before an Issue or Pull Request with the stale
+# label is closed. Set to false to disable. If disabled, issues still need to be
+# closed manually, but will remain marked as stale.
+daysUntilClose: 30
+
+# Only issues or pull requests with all of these labels are check if stale.
+# Defaults to `[]` (disabled)
+onlyLabels: []
+
+# Issues or Pull Requests with these labels will never be considered stale. Set
+# to `[]` to disable
+exemptLabels:
+ - security
+ - planned
+ - priority/critical
+ - lifecycle/frozen
+ - verified
+
+# Set to true to ignore issues in a project (defaults to false)
+exemptProjects: false
+
+# Set to true to ignore issues in a milestone (defaults to false)
+exemptMilestones: true
+
+# Set to true to ignore issues with an assignee (defaults to false)
+exemptAssignees: false
+
+# Label to use when marking as stale
+staleLabel: lifecycle/stale
+
+# Limit the number of actions per hour, from 1-30. Default is 30
+limitPerRun: 30
+
+pulls:
+ markComment: |-
+ PRs go stale after 90 days of inactivity.
+ If there is no further activity, the PR will be closed in another 30 days.
+
+ unmarkComment: >-
+ This pull request is no longer stale.
+
+ closeComment: >-
+ This pull request has been closed due to inactivity.
+
+issues:
+ markComment: |-
+ Issues go stale after 90 days of inactivity.
+ If there is no further activity, the issue will be closed in another 30 days.
+
+ unmarkComment: >-
+ This issue is no longer stale.
+
+ closeComment: >-
+ This issue has been closed due to inactivity.
diff --git a/ansible_collections/community/okd/.github/workflows/changelog.yml b/ansible_collections/community/okd/.github/workflows/changelog.yml
new file mode 100644
index 000000000..569e334fe
--- /dev/null
+++ b/ansible_collections/community/okd/.github/workflows/changelog.yml
@@ -0,0 +1,23 @@
+---
+name: Changelog
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ pull_request:
+ types:
+ - opened
+ - reopened
+ - labeled
+ - unlabeled
+ - synchronize
+ branches:
+ - main
+ - stable-*
+ tags:
+ - '*'
+
+jobs:
+ changelog:
+ uses: ansible-network/github_actions/.github/workflows/changelog.yml@main
diff --git a/ansible_collections/community/okd/.github/workflows/linters.yml b/ansible_collections/community/okd/.github/workflows/linters.yml
new file mode 100644
index 000000000..11258aaf3
--- /dev/null
+++ b/ansible_collections/community/okd/.github/workflows/linters.yml
@@ -0,0 +1,29 @@
+---
+name: Linters
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ pull_request:
+ types:
+ - opened
+ - reopened
+ - labeled
+ - unlabeled
+ - synchronize
+ branches:
+ - main
+ - stable-*
+ tags:
+ - '*'
+jobs:
+ linters:
+ uses: ansible-network/github_actions/.github/workflows/tox-linters.yml@main
+ ansible-lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: ansible-network/github_actions/.github/actions/checkout_dependency@main
+
+ - name: Run ansible-lint
+ uses: ansible/ansible-lint@v6.21.0
diff --git a/ansible_collections/community/okd/.github/workflows/sanity-tests.yml b/ansible_collections/community/okd/.github/workflows/sanity-tests.yml
new file mode 100644
index 000000000..49359de9b
--- /dev/null
+++ b/ansible_collections/community/okd/.github/workflows/sanity-tests.yml
@@ -0,0 +1,23 @@
+---
+name: Sanity tests
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ pull_request:
+ types:
+ - opened
+ - reopened
+ - synchronize
+ branches:
+ - main
+ - stable-*
+ tags:
+ - '*'
+
+jobs:
+ sanity:
+ uses: ansible-network/github_actions/.github/workflows/sanity.yml@main
+ with:
+ collection_pre_install: '-r source/tests/sanity/requirements.yml'
diff --git a/ansible_collections/community/okd/.github/workflows/unit-tests.yml b/ansible_collections/community/okd/.github/workflows/unit-tests.yml
new file mode 100644
index 000000000..d3aa3b0ce
--- /dev/null
+++ b/ansible_collections/community/okd/.github/workflows/unit-tests.yml
@@ -0,0 +1,21 @@
+---
+name: Unit tests
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ pull_request:
+ types:
+ - opened
+ - reopened
+ - synchronize
+ branches:
+ - main
+ - stable-*
+ tags:
+ - '*'
+
+jobs:
+ unit-source:
+ uses: ansible-network/github_actions/.github/workflows/unit_source.yml@main
diff --git a/ansible_collections/community/okd/.yamllint b/ansible_collections/community/okd/.yamllint
index 882767605..ac5297cdf 100644
--- a/ansible_collections/community/okd/.yamllint
+++ b/ansible_collections/community/okd/.yamllint
@@ -1,33 +1,15 @@
---
-# Based on ansible-lint config
-extends: default
-
rules:
- braces:
- max-spaces-inside: 1
- level: error
- brackets:
- max-spaces-inside: 1
- level: error
- colons:
- max-spaces-after: -1
- level: error
- commas:
- max-spaces-after: -1
- level: error
- comments: disable
- comments-indentation: disable
- document-start: disable
- empty-lines:
- max: 3
- level: error
- hyphens:
- level: error
- indentation: disable
- key-duplicates: enable
- line-length: disable
- new-line-at-end-of-file: disable
- new-lines:
- type: unix
- trailing-spaces: disable
- truthy: disable
+ indentation:
+ ignore: &default_ignores |
+ # automatically generated, we can't control it
+ changelogs/changelog.yaml
+ # Will be gone when we release and automatically reformatted
+ changelogs/fragments/*
+ document-start:
+ ignore: *default_ignores
+ line-length:
+ ignore: *default_ignores
+ max: 160
+
+ignore-from-file: .gitignore
diff --git a/ansible_collections/community/okd/CHANGELOG.rst b/ansible_collections/community/okd/CHANGELOG.rst
index b86a7c409..254bf5393 100644
--- a/ansible_collections/community/okd/CHANGELOG.rst
+++ b/ansible_collections/community/okd/CHANGELOG.rst
@@ -5,6 +5,34 @@ OKD Collection Release Notes
.. contents:: Topics
+v3.0.1
+======
+
+Release Summary
+---------------
+
+This patch release fixes an issue in building the downstream collection.
+
+
+v3.0.0
+======
+
+Release Summary
+---------------
+
+This major release drops support for ansible-core versions lower than 2.14 and Python versions lower than 3.9. It also deprecates ``openshift`` inventory plugin.
+
+Breaking Changes / Porting Guide
+--------------------------------
+
+- Bump minimum Python suupported version to 3.9 (https://github.com/openshift/community.okd/pull/202).
+- Remove support for ansible-core < 2.14 (https://github.com/openshift/community.okd/pull/202).
+
+Deprecated Features
+-------------------
+
+- openshift - the ``openshift`` inventory plugin has been deprecated and will be removed in release 4.0.0 (https://github.com/ansible-collections/kubernetes.core/issues/31).
+
v2.3.0
======
diff --git a/ansible_collections/community/okd/FILES.json b/ansible_collections/community/okd/FILES.json
index f4086aab1..de9bf3950 100644
--- a/ansible_collections/community/okd/FILES.json
+++ b/ansible_collections/community/okd/FILES.json
@@ -8,570 +8,605 @@
"format": 1
},
{
- "name": ".yamllint",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "5845e18e9f23155f423207df9abac970aed687c638620bc2c9ee06706191054b",
- "format": 1
- },
- {
- "name": "tests",
+ "name": ".config",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "tests/config.yml",
+ "name": ".config/ansible-lint.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9a009a349eaaf78c93ff56072d2ef171937bdb884e4976592ab5aaa9c68e1044",
+ "chksum_sha256": "2bbd9eb3d8f8d6af779720000dc297955b780ab053807e2dfc5a59f24707b530",
"format": 1
},
{
- "name": "tests/unit",
+ "name": ".github",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "tests/unit/requirements.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8004a972c3d5c274d8c808e8d8afe03b9aca8af8eebf3df4298f114d8008b754",
- "format": 1
- },
- {
- "name": "tests/unit/plugins",
+ "name": ".github/workflows",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "tests/unit/plugins/module_utils",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": ".github/workflows/changelog.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "859dc36574b2741d827d47c03bdc725646c486e8c3c7c975f7bb2e29c750ca41",
"format": 1
},
{
- "name": "tests/unit/plugins/module_utils/test_openshift_docker_image.py",
+ "name": ".github/workflows/linters.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2645a4d02f3adc9e4bbb8b69ecb9b327836c142d1115f616c2e0eb05f0414299",
+ "chksum_sha256": "4e72e9b4d746793d9b2766bac960c2535db37061613792c0559113415e7ac196",
"format": 1
},
{
- "name": "tests/unit/plugins/module_utils/test_ldap_dn.py",
+ "name": ".github/workflows/sanity-tests.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5e692237cc900dce4c6bd3a1512c4027e6bb2c0a23e5d473a55c9137751c3559",
+ "chksum_sha256": "e1c58db0639ceee1498911aa4c265166f1ad510a09567bc9a06fe7bd0b210619",
"format": 1
},
{
- "name": "tests/unit/plugins/module_utils/test_ldap_sync_config.py",
+ "name": ".github/workflows/unit-tests.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d1647944d9370d05aedc63b115f427d037a3354f670b45e94bb3f4f4f95b162f",
+ "chksum_sha256": "a774d39eadf33235ba9490d9bfa69be9659533c18be73e75212fa11084bad4d2",
"format": 1
},
{
- "name": "tests/unit/plugins/modules",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": ".github/patchback.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ed69f87ea46171cb574fb77dc74fdbd7a269d4cad8d5ba6494d64d99842ef8e4",
"format": 1
},
{
- "name": "tests/unit/plugins/modules/test_openshift_adm_migrate_template_instances.py",
+ "name": ".github/settings.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4c426c87d28313524cbd378f917a2d70242f333571f942d44bc9bf8c7e591586",
+ "chksum_sha256": "bec830af2dc0266fc961c9c47bff160476c32878720cd1d7902581ec30a15c18",
"format": 1
},
{
- "name": "tests/sanity",
+ "name": ".github/stale.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "923b49f6fb8b325ea890d05a42537b3f9c5aaf26b64a704c0fef4b696aa6a4bb",
+ "format": 1
+ },
+ {
+ "name": "changelogs",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "tests/sanity/ignore-2.14.txt",
+ "name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
+ "chksum_sha256": "dc1cb3339cbc9332acb6d7e964b9deaddaf6b371bd954d50376edb07389be62d",
"format": 1
},
{
- "name": "tests/sanity/ignore-2.10.txt",
+ "name": "changelogs/config.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ba2285dad70183ce56e9d43ed97d4b7a1b12e7cdd3f4e5856fb3cf380148a5ee",
+ "chksum_sha256": "77ecb61675531e89ac5c09471a86ca6fe440167361fb6d42e30b8208c2514809",
"format": 1
},
{
- "name": "tests/sanity/ignore-2.13.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
+ "name": "ci",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "tests/sanity/ignore-2.9.txt",
+ "name": "ci/Dockerfile",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cf94385a1d8a2b51f40f88879b59922c8a8b07b8f1e0ac511a2454e257361995",
+ "chksum_sha256": "10c6a10838ba7e78ec6b0782d45217311b7faf7c80d466c9e23a52ac9447efa0",
"format": 1
},
{
- "name": "tests/sanity/ignore-2.12.txt",
+ "name": "ci/doc_fragment_modules.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
+ "chksum_sha256": "e5f5e24396a2cc86faedf6d0b7a3835db06bbe6fc7b534018ed85ebecfa39e09",
"format": 1
},
{
- "name": "tests/sanity/ignore-2.11.txt",
+ "name": "ci/downstream.sh",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dc0294c142585d8904331fd57755efc876e592ce8242e42e1159bcfddd4adbba",
+ "chksum_sha256": "acc4c04397c247ae716e133f9df25c8a301b606416425a6fdbf191e096ab76b0",
"format": 1
},
{
- "name": "tests/sanity/ignore-2.15.txt",
+ "name": "ci/downstream_fragments.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
+ "chksum_sha256": "9815e2aa84aef5d396fd07ddb371fa87362ade6fbe72d829e4d5983abe8af453",
"format": 1
},
{
- "name": "README.md",
+ "name": "ci/incluster_integration.sh",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a49ac5f1fa3cdb032a5274e9d0d8a8fadcc5dd3ee1a0d3f872ca969a22be3056",
+ "chksum_sha256": "012ffb20a006094a4e8a00ead7947a196c477c4eb071a1dad5ffe42f509935e1",
"format": 1
},
{
- "name": "changelogs",
+ "name": "docs",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "changelogs/changelog.yaml",
+ "name": "docs/ansible_turbo_mode.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "36a4108575c00ad25e2774bcae35c32e4022d8d1b563ed72e536ec796b22b46f",
+ "chksum_sha256": "a9bcd000c20de1d1ad35f5516f4fdffce07c8e28a5ebee572629a3b9cb867152",
"format": 1
},
{
- "name": "changelogs/config.yaml",
+ "name": "docs/community.okd.k8s_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "46bf50de40f3abb6bc0497f3b188dba66c295a2c764337abf4dda636644cb0d9",
+ "chksum_sha256": "07204d20c2e6d6c65841abed30d0801ddb26112e74ca544f364781feda2c5008",
"format": 1
},
{
- "name": "changelogs/.plugin-cache.yaml",
+ "name": "docs/community.okd.oc_connection.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e9fb32d9dfa89439d04e50697ea1e8a5c77a2411dd6a061d2eddb5e328753abf",
+ "chksum_sha256": "92709a3843099a4df82f3fb7978b6dc45c9a607387e490dbeaa37d68e2969b13",
"format": 1
},
{
- "name": "CONTRIBUTING.md",
+ "name": "docs/community.okd.openshift_adm_groups_sync_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4156016c23606d288b98c4fa0eafc6afe1cf28e695fb5a267bcc3d337a7bfef0",
+ "chksum_sha256": "11db9878e4227634e58b1512dee0b3893191edec658adb65691756c16f5174e8",
"format": 1
},
{
- "name": "requirements.txt",
+ "name": "docs/community.okd.openshift_adm_migrate_template_instances_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d20fa49248fb968b70381346d2b2f6195e19dc1ddded06856bc4aefa6a25d431",
+ "chksum_sha256": "c91df00cdec670c92d452cc7d10abaebd705756b7bb643c767c2309a22bd6859",
"format": 1
},
{
- "name": "meta",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "docs/community.okd.openshift_adm_prune_auth_module.rst",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f16dbc021ee73369585efa88fd7d56bf02898317e8602f303eab9d6601d4ddf0",
"format": 1
},
{
- "name": "meta/runtime.yml",
+ "name": "docs/community.okd.openshift_adm_prune_builds_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "369f3c5a13d3d8400d0f662ec26d211c4e135f1b8b661c66346d899ad371b534",
+ "chksum_sha256": "b0662928fe5aff419369743708efe29cb0e951c19e41ab7bb26dc23969cf5d1d",
"format": 1
},
{
- "name": ".gitignore",
+ "name": "docs/community.okd.openshift_adm_prune_deployments_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8344abb7aafbdb654f0c88532af7ab557dad7a6a7cba60f4834f33c2a1f8524f",
+ "chksum_sha256": "7e4781b3a321298041396560a8764bcbfb8ddbd3c0bac20a54fb5cb046e3c4d8",
"format": 1
},
{
- "name": "test-requirements.txt",
+ "name": "docs/community.okd.openshift_adm_prune_images_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "34db46c861b289148eb3ebff5ff7786aa091eec38c0f3d1606bf2e3d9f030b94",
+ "chksum_sha256": "d273a042aaabf92298b5a38f887e0593047472314afe36f831f9a9aa3989ced5",
"format": 1
},
{
- "name": "codecov.yml",
+ "name": "docs/community.okd.openshift_auth_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "caa848a2e02be5014890c5cbc7727e9a00d40394637c90886eb813d60f82c9c3",
+ "chksum_sha256": "d7e0110a88d5e2d1033f803cfef7ab821eef3fd2aeba9ab3d16203f336f39394",
"format": 1
},
{
- "name": "setup.cfg",
+ "name": "docs/community.okd.openshift_build_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "125fefc5c9470b8e72cffc06937c30e2bc073f4ca6c1a593f131a6e1fd76edf2",
+ "chksum_sha256": "50c1219f5524d60a4b46bc58c6df30d8af7b6e6ecc20fd4d15cf3e0fc352c05e",
"format": 1
},
{
- "name": "OWNERS",
+ "name": "docs/community.okd.openshift_import_image_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "771ebefb6c2b0154bf043cc537cc55b8421ddd4058248b00a62cdc9b190131da",
+ "chksum_sha256": "889c62212325e583f2a36fb0dd66f392d6bd4058af089c1f829f6f97972577d1",
"format": 1
},
{
- "name": "LICENSE",
+ "name": "docs/community.okd.openshift_inventory.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8b1ba204bb69a0ade2bfcf65ef294a920f6bb361b317dba43c7ef29d96332b9b",
+ "chksum_sha256": "e5df6651617abc50c0b054c34e57601bc7ea889167800658b1013d61beb236e2",
"format": 1
},
{
- "name": "OWNERS_ALIASES",
+ "name": "docs/community.okd.openshift_process_module.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fee153ef8daa4ed6170434daf598b3efdcaf80db39e5b4ef9f2ab8cd4f8f4c30",
+ "chksum_sha256": "ca7f93a6fa0ac3d38f982076ef491438338bb7face86bede1799de9bdb66175a",
"format": 1
},
{
- "name": "plugins",
+ "name": "docs/community.okd.openshift_registry_info_module.rst",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e980ae3c9f683a90b9cfbb79aa36cb345a262a16fd4d2079e0147e9124d376e3",
+ "format": 1
+ },
+ {
+ "name": "docs/community.okd.openshift_route_module.rst",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e23a6df2370bc8bebc1e77dd70ac239d15ade8cc1eedb0c3201692d2218f20d0",
+ "format": 1
+ },
+ {
+ "name": "meta",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/doc_fragments",
+ "name": "meta/runtime.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cc700e426626ae08f404ae2fe82224e9dd7e98a7e1a3ab91823fd7cf3930feac",
+ "format": 1
+ },
+ {
+ "name": "molecule",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/module_utils",
+ "name": "molecule/default",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/module_utils/openshift_common.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "cbbbbe8693629763781768801033674d80fdcc5ae2b5d19eb35922bc50eee8ed",
+ "name": "molecule/default/files",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/module_utils/openshift_registry.py",
+ "name": "molecule/default/files/crd-resource.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a2a40dbcae3074de050c5d9be2d1e4352cf0698ad8385fd81c03ce73805a6e93",
+ "chksum_sha256": "4921362ac3c4afac5f42ebb90b37bcb75e1fe20929bb0e45d0df4c190d28f577",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_adm_prune_deployments.py",
+ "name": "molecule/default/files/example.env",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8fa9b77a5d2326893c1ecd9841d4b9e30e3e7bd788d7455efcbad45d010683f5",
+ "chksum_sha256": "3701367ea0a79158d476e168c1b1e64639f703da926e63045cba5cfdbb6c3576",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_images_common.py",
+ "name": "molecule/default/files/kuard-extra-property.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d61fbb7ced206c7cbde4a610e643aa4a824e7856648ba598c5f630978bbafdaa",
+ "chksum_sha256": "27a06de7ca760698dc1d3c46ef12e40e214ae319a791a3965806b30adca06de0",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_process.py",
+ "name": "molecule/default/files/kuard-invalid-type.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a7f5b99e0f07aba90fd2744f6311c82a59698424e5904ceda7b2e0eaa3e080af",
+ "chksum_sha256": "c0e8aa083eecb5c4d92108af83f9a2c931a2e5bbb766af4792adc4fb9fd9d32d",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_builds.py",
+ "name": "molecule/default/files/nginx.env",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f7b18ce9225cb1fb06a970a591662ab9cd1c3015f18bae86570e4f2345b0449e",
+ "chksum_sha256": "a68c2914576119a809943116ce0050ca221c5b8f3a6722fa6abbf15dababde5f",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_ldap.py",
+ "name": "molecule/default/files/pod-template.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "894c0aa5a40d6c227b73cb83c3e4217a6ed081cda9c3a89a0606b66a65b52287",
+ "chksum_sha256": "255bfc8684edf514bac8d4da1ca2c53c26ef3cf190d68e9cbdf7423254e9407e",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_import_image.py",
+ "name": "molecule/default/files/setup-crd.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "47819d3ab99b61593b5db881b6d93855caf45ae3df71b77ad7b6528a1b51bbbd",
+ "chksum_sha256": "509878fff22a19715f1c491930eefd23430c0f571716b463c3ab9a754d0fb250",
"format": 1
},
{
- "name": "plugins/module_utils/k8s.py",
+ "name": "molecule/default/files/simple-template.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "386788c253525ffe4350e4b6fbbc1380e03f703bfe6fa3ca4506615e93b9173d",
+ "chksum_sha256": "4df5821a40d53323c398a786ffa81cbdb22aa759f54ffdf98d9d3f4e6f119604",
"format": 1
},
{
- "name": "plugins/module_utils/openshift_adm_prune_images.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "cd027fb0716b5c92ac6176f6a46236c0379e9680cd9d743c5fd40617461502f8",
+ "name": "molecule/default/roles",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/module_utils/openshift_adm_prune_auth.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "76a26d3ab75396a28fc546c19b1a8e215aa8a5fd59fc4491539e2ef6d5537d8c",
+ "name": "molecule/default/roles/openshift_adm_groups",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/module_utils/openshift_docker_image.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d23dfbad39579c35a2a39bbf0e18e2e0e8bc3a0122c37d0fc87c2ea125f5af2c",
+ "name": "molecule/default/roles/openshift_adm_groups/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/module_utils/openshift_groups.py",
+ "name": "molecule/default/roles/openshift_adm_groups/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f583086177b63a87fca75c3d41d1bce4bc4cecaf68c60a9008ca1ecb31d1c38a",
+ "chksum_sha256": "1bd380f6c0cdf0c2b25e6bf27e4304566f6b9efbbeaf15da3847a9744d685a72",
"format": 1
},
{
- "name": "plugins/connection",
+ "name": "molecule/default/roles/openshift_adm_groups/library",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/connection/oc.py",
+ "name": "molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cb192532153b1625ec97437f5ac7177cfa78d8cba5c5eaa4633fab63ba54ca09",
+ "chksum_sha256": "8e0d7d997ba74938fef19fead2cf1d2151644ad999e2285b0d769c89804abf5e",
"format": 1
},
{
- "name": "plugins/inventory",
+ "name": "molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ccbf989315dfac69f1a62fb08067f4359e5b2a13d33baa9fba4ccbcbb8ad7f47",
+ "format": 1
+ },
+ {
+ "name": "molecule/default/roles/openshift_adm_groups/meta",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/inventory/openshift.py",
+ "name": "molecule/default/roles/openshift_adm_groups/meta/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bb798a479803548cc8eeddb6fdb565d1b0f7b3222af445c42447247203953849",
+ "chksum_sha256": "8d57e1f764ed7af7cf34d0b039ef97eb206fd846d31025ac08ddefa855a83204",
"format": 1
},
{
- "name": "plugins/modules",
+ "name": "molecule/default/roles/openshift_adm_groups/tasks",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/modules/openshift_adm_groups_sync.py",
+ "name": "molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "80197c296c50931b3b0ed2a4841dd46ab98b6d0de3c923ddc8d60abd49cdecee",
+ "chksum_sha256": "522791250e95623a0750d13e335db874f3afc888dd513b234d4de0553ba0bcf8",
"format": 1
},
{
- "name": "plugins/modules/openshift_registry_info.py",
+ "name": "molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "abf945aba0bb5d769783c7e3ee1b19c2e4cd4f9e932a51e88dcb298a664cc677",
+ "chksum_sha256": "9685339b4984a7d72f2fcf56e2f444298f789539243205d70288a9211c52d9f9",
"format": 1
},
{
- "name": "plugins/modules/openshift_auth.py",
+ "name": "molecule/default/roles/openshift_adm_groups/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a293bf87c5f13c610fd2e6032a76e2c813bfdae4953c7b33e2c6cbf3bf8249e1",
+ "chksum_sha256": "dbf4a75120762ad728524e355345807111fb02dd4be9496ee5ecd00b5a7a9fc2",
"format": 1
},
{
- "name": "plugins/modules/openshift_route.py",
+ "name": "molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "78e6b48f0dcc76cecc8c0272768cfdeab62364b3658984fdddf888492f61dd03",
+ "chksum_sha256": "243678c2bbdca70ab4064027e32ad81c1e50dc59e6af595a9fdf29c789487322",
"format": 1
},
{
- "name": "plugins/modules/openshift_build.py",
+ "name": "molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a0aff179625071a085d0d9014cfa8999dceb96ba2394db5f33991eca1a9c85c5",
+ "chksum_sha256": "1bed08f558010eac88ba66c291c828866843784939e12d4fbc0cb55593bb2e90",
"format": 1
},
{
- "name": "plugins/modules/openshift_adm_prune_deployments.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "9dc9dcfce2107deecd3da2144f0dee455a442afcd04428c042bd48d598978bd2",
+ "name": "molecule/default/roles/openshift_adm_groups/templates",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/modules/openshift_process.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "271370fe6c7eba007bd282d4bea738100278b4294df88d55b69f951309867a4e",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/ad",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/modules/openshift_import_image.py",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/ad/definition.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dc18021e7be860b0accbe89fc51e2de1ca03938bb159907ba45558527f808c2f",
+ "chksum_sha256": "f59a7ee4f37de0040f293b615b45092f5bc9fb36f832d81ea6f0a7155bb2c1bd",
"format": 1
},
{
- "name": "plugins/modules/k8s.py",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/ad/sync-config.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ffca7a5e4ed3d2122106a601b511589507b99ab65a138e4c912dcd76fcb2d430",
+ "chksum_sha256": "fef496b8ba026e34cdef374f373a15948db2bf6147bff5eb4ebdba4d1b3a4381",
"format": 1
},
{
- "name": "plugins/modules/openshift_adm_prune_images.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "c1f6d6e041d08ccd548a812c6bee4a972b260ebb86dbe35783140001c9bea681",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/augmented-ad",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "plugins/modules/openshift_adm_prune_auth.py",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/augmented-ad/definition.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "63c667799f92fdf025b577e2a6a3c84220389e35d357d95177f7acdb773d3da2",
+ "chksum_sha256": "a2db659cc8d7467e4d9e78029027d6fff6cc1fd38e54c6ca954a9a64633470d0",
"format": 1
},
{
- "name": "plugins/modules/openshift_adm_prune_builds.py",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/augmented-ad/sync-config.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d40236b25580fa9fb242d42b43304865f51fceef82d6e1eb0ca158cf18a6253e",
+ "chksum_sha256": "76c20cd498ced5c2417a71611b35bde1b22b537fd106b5d8fecf1b896d7d5074",
"format": 1
},
{
- "name": "plugins/modules/openshift_adm_migrate_template_instances.py",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/rfc2307",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "molecule/default/roles/openshift_adm_groups/templates/rfc2307/definition.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0f6f0fd8d617700bdb22953555bb6fe2dd7dbe9c297264cf191cfca651dbb0b4",
+ "chksum_sha256": "5e2d7b8287dd1b1ad0067eb8a38d282ff43f95e3a91c3778b86205a14988b434",
"format": 1
},
{
- "name": "Makefile",
+ "name": "molecule/default/roles/openshift_adm_groups/templates/rfc2307/sync-config.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "afa91ff62ed42d4b0fb73fa47899a01cde478809866d99c63787130074d5a039",
+ "chksum_sha256": "64cdf5017cb257f3b26d7eb858c8295313684b1147f0baee3f657fc3dc36c1f9",
"format": 1
},
{
- "name": "molecule",
+ "name": "molecule/default/tasks",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cf0ce2145e226c480622e9166a3f3792948f8ab671dfc71b49fd8a334ce7db36",
"format": 1
},
{
- "name": "molecule/default/prepare.yml",
+ "name": "molecule/default/tasks/openshift_adm_prune_auth_roles.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d9765b6cd95ab121281ca53b24f5a0954b211801ca070aa9402f746e593195df",
+ "chksum_sha256": "503cbc3b57838463568fc4d92a5cdf273eefe94d3585d8ca8c095385a68fc7e6",
"format": 1
},
{
- "name": "molecule/default/README.md",
+ "name": "molecule/default/tasks/openshift_adm_prune_deployments.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "75d6935060001109bea00ffcf6d289b29e7aa6afeaba2e1e1b85d767062f4da8",
+ "chksum_sha256": "9f279837a7539985a4663f0522186d704675c4c55fc8145f1c4e7c6905fe988c",
"format": 1
},
{
- "name": "molecule/default/tasks",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "molecule/default/tasks/openshift_auth.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0d8b02f57bd1ff3b9a65d46c40914a2ff765f6bd96901ebfa7ce1751154d1802",
+ "format": 1
+ },
+ {
+ "name": "molecule/default/tasks/openshift_builds.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f9e00bcbc3d7758ccc307207c0251d968e028cacca64bade4b73675fa6969004",
"format": 1
},
{
"name": "molecule/default/tasks/openshift_import_images.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0697c9bcd3f8b67cc778ddd5a4eaedf170f925501dae4e5836434b897a30d5dd",
+ "chksum_sha256": "5c295e6733b977323a9113220137891428e47582ebca88a3f2186b8d5f55a905",
"format": 1
},
{
- "name": "molecule/default/tasks/validate_installed.yml",
+ "name": "molecule/default/tasks/openshift_process.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a6abad4a4d33a77ca736a4835db0f5d11dc7742100ff4d9d36a9942e1f4b55e9",
+ "chksum_sha256": "999932ada001df7be263ab2158592c6325d2827ee372ad38e9f0197b807cbf52",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_adm_prune_deployments.yml",
+ "name": "molecule/default/tasks/openshift_prune_images.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "16b97fda417204c8df08a294c4f46011ad6bc617964d3b2a8c860134793ea175",
+ "chksum_sha256": "7b2b85f65cf92d5a572f7f85cc006d5fd7b6ebc2d913f8ae9f16d2def362d071",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_builds.yml",
+ "name": "molecule/default/tasks/openshift_route.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dd3532196ebb99d4a467fb2cc4b958a1d5e551969c00224b07694c76b959dd45",
+ "chksum_sha256": "3d4fc8dd62b012f339a517d0e7c73767031bda416b4bfac1975c5425ee462c8b",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_adm_prune_auth_roles.yml",
+ "name": "molecule/default/tasks/validate_installed.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d83689cc8e59c041386545fb0afdde5ec3157bea33db35303529595ddffb5fe9",
+ "chksum_sha256": "a6abad4a4d33a77ca736a4835db0f5d11dc7742100ff4d9d36a9942e1f4b55e9",
"format": 1
},
{
@@ -582,493 +617,542 @@
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_prune_images.yml",
+ "name": "molecule/default/vars",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "molecule/default/vars/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "706dec431bd424212a1b43e7c7aa86bc9a01c3fd392d170f6486b1732ebcc317",
+ "chksum_sha256": "d065ea53707a373ac5928ee6091224569ac791023daa1cf26f70a099812a51cf",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_auth.yml",
+ "name": "molecule/default/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0d8b02f57bd1ff3b9a65d46c40914a2ff765f6bd96901ebfa7ce1751154d1802",
+ "chksum_sha256": "75d6935060001109bea00ffcf6d289b29e7aa6afeaba2e1e1b85d767062f4da8",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_route.yml",
+ "name": "molecule/default/converge.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "20d0f4944902de207884fe0a0a987070b9b3716a436d76264400cb67f53c38c3",
+ "chksum_sha256": "2da549e774063f37985fa720bb55ce6a5d70375d1ac2171564c29b63794342bf",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml",
+ "name": "molecule/default/destroy.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bc631199609c00aa4f669ccde1c351921ad43eec335c7abe6185f97c2b903f11",
+ "chksum_sha256": "26670c28263a4f354e646c222e2c59ccfcb3cd807fe07d531e9874fc3748a44c",
"format": 1
},
{
- "name": "molecule/default/tasks/openshift_process.yml",
+ "name": "molecule/default/molecule.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "999932ada001df7be263ab2158592c6325d2827ee372ad38e9f0197b807cbf52",
+ "chksum_sha256": "53e1ed3199bf98922cbabb2d30dc2b4df6594790b0dee4cb271aaeba739bdf72",
"format": 1
},
{
- "name": "molecule/default/destroy.yml",
+ "name": "molecule/default/prepare.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "26670c28263a4f354e646c222e2c59ccfcb3cd807fe07d531e9874fc3748a44c",
+ "chksum_sha256": "e346146e7c1bf70e7255c26241de861c5df4cc1fcc00d3f66c10aa14ce883d0d",
"format": 1
},
{
- "name": "molecule/default/roles",
+ "name": "molecule/default/verify.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0aa66e5d35f985e47345d47e378816189d77cb131520e115f05c8eea2ab3bfc6",
+ "format": 1
+ },
+ {
+ "name": "plugins",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups",
+ "name": "plugins/connection",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/tasks",
+ "name": "plugins/connection/oc.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1fcf101432828f7519c411ec7b1be81f42a366759cc07935cc34ad1b85edac6f",
+ "format": 1
+ },
+ {
+ "name": "plugins/inventory",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml",
+ "name": "plugins/inventory/openshift.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "05a6759b51bcd97f154db6d344367c55eb424533163fccce1493c49dd5913973",
+ "chksum_sha256": "c1c98feecbde5e6ab84e1040351234c482e34dcaf95dd6e9ce1ca41980a97acc",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/tasks/main.yml",
+ "name": "plugins/module_utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/module_utils/k8s.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d7b676aa4dd79463ad48beebb3b29dd7d73f65bad7df406ea8787214a9fa7004",
+ "chksum_sha256": "c8bd794e43782ceb9bf24c552584bf6b22817c273503838e38ba3acbf41f7e9b",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml",
+ "name": "plugins/module_utils/openshift_adm_prune_auth.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ad25bcfb4431257ab481f12cfcbae23620d8826fa25d38e93ed9a81ef646aa68",
+ "chksum_sha256": "40e03e4fda07b0995fb4ead3937424746f4ad2e0302cf1be6b1709244534f4fd",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml",
+ "name": "plugins/module_utils/openshift_adm_prune_deployments.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5e2758c9d39c94892ca9976f8e5d7b360bfccb134ea7b95f83ba51c46b1d9195",
+ "chksum_sha256": "e688fef20fcca0454f5d66be41959ef2caae94f655ea6b6e232df9153321be89",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml",
+ "name": "plugins/module_utils/openshift_adm_prune_images.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "87966533bdb6f1f62208f8c6e85ba38acdb3dfd44c6312eb5dca5026b4c9ea0e",
+ "chksum_sha256": "2e80eb099994a60a38ccb2d3d47963597999c11215cbd1746a558101592369ee",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/library",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "plugins/module_utils/openshift_builds.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "498738d81ec6249b0f8309a8aaa215a918bf9646c2e5f15c243395626d8f64dd",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry.py",
+ "name": "plugins/module_utils/openshift_common.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8e0d7d997ba74938fef19fead2cf1d2151644ad999e2285b0d769c89804abf5e",
+ "chksum_sha256": "6af4aa60cd80d06fc7f42af7ecf526b9c53a49173b7f896a7236a3b521c4ade9",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py",
+ "name": "plugins/module_utils/openshift_docker_image.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0b98d02bb07c0ae7ba4da80ef95c02d2476a0106bd8f198779d296c81323bbfe",
+ "chksum_sha256": "92a9a5b72dc08177f3f3ea78773da262371df7ae9629a25c8b3ad0c199f074d3",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/meta",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "plugins/module_utils/openshift_groups.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "28aab970ca56b3e6ce985dde4db867073756edb7504ee56b0df6859fde321e9f",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/meta/main.yml",
+ "name": "plugins/module_utils/openshift_images_common.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8d57e1f764ed7af7cf34d0b039ef97eb206fd846d31025ac08ddefa855a83204",
+ "chksum_sha256": "c8f211ba01c590ac57e4df775c0a58699c0ae25c631b635566ae2ff9aabe4b55",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "plugins/module_utils/openshift_import_image.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7cf4e412c985be34ed4cd9e7510db5ab7364508c298458006e148809fd407e82",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/ad",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "plugins/module_utils/openshift_ldap.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3f60ab29cc0f32f3e895e170d9f9288e2b084deef377f9969c342ce51ebc58f8",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/ad/definition.j2",
+ "name": "plugins/module_utils/openshift_process.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f59a7ee4f37de0040f293b615b45092f5bc9fb36f832d81ea6f0a7155bb2c1bd",
+ "chksum_sha256": "004b12313ab35b10521146d1c0bd05a5838f1f25a33d2d465f5bb4aa9dc1d9f6",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/ad/sync-config.j2",
+ "name": "plugins/module_utils/openshift_registry.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fef496b8ba026e34cdef374f373a15948db2bf6147bff5eb4ebdba4d1b3a4381",
+ "chksum_sha256": "97235ea3a40a714e532d85b636fb81ea2eb8afdfbdea7da33a387408c692a272",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/augmented-ad",
+ "name": "plugins/modules",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/augmented-ad/definition.j2",
+ "name": "plugins/modules/k8s.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a2db659cc8d7467e4d9e78029027d6fff6cc1fd38e54c6ca954a9a64633470d0",
+ "chksum_sha256": "56f8482a9638fa5d9b223fafa6d6b62f805bdf7cfe65c96e257631b065ee0e3e",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/augmented-ad/sync-config.j2",
+ "name": "plugins/modules/openshift_adm_groups_sync.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "76c20cd498ced5c2417a71611b35bde1b22b537fd106b5d8fecf1b896d7d5074",
+ "chksum_sha256": "1285e0be18423cd12a1a5ee715a6b6e2a9c6ee84d265a256dc041377ec86831a",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/rfc2307",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "plugins/modules/openshift_adm_migrate_template_instances.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1db241bd4b22890659fc73ef8de575b3f2d61f6819920e67dacea664d58e3620",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/rfc2307/definition.j2",
+ "name": "plugins/modules/openshift_adm_prune_auth.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5e2d7b8287dd1b1ad0067eb8a38d282ff43f95e3a91c3778b86205a14988b434",
+ "chksum_sha256": "2c7fd42950f839f827503c5de4a8111d235629d200ce13833f39f3193d854a8c",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/templates/rfc2307/sync-config.j2",
+ "name": "plugins/modules/openshift_adm_prune_builds.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "64cdf5017cb257f3b26d7eb858c8295313684b1147f0baee3f657fc3dc36c1f9",
+ "chksum_sha256": "d372ad2d48b33ca7210e4f642597fd31ccdca1eb310a949d3af9a6636328a68e",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/defaults",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "plugins/modules/openshift_adm_prune_deployments.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5482e4282ce36f550b06f9184086f4e6a75ea5e5a216104b4fded399bf548267",
"format": 1
},
{
- "name": "molecule/default/roles/openshift_adm_groups/defaults/main.yml",
+ "name": "plugins/modules/openshift_adm_prune_images.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1bd380f6c0cdf0c2b25e6bf27e4304566f6b9efbbeaf15da3847a9744d685a72",
+ "chksum_sha256": "31f370fe2e70ea88a7cbd517285965a43b9363107a5b66956f2542b0f1412fa0",
"format": 1
},
{
- "name": "molecule/default/molecule.yml",
+ "name": "plugins/modules/openshift_auth.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0e6bfb7aa0d20362717eebbcf8c8bee26211fc1d83bf23bdd5f8fb7046155c47",
+ "chksum_sha256": "9237d7254c4773ff8f1cbb568af501ad0f5c6b00a089b495c67a131f201b017a",
"format": 1
},
{
- "name": "molecule/default/converge.yml",
+ "name": "plugins/modules/openshift_build.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bdd1f1cc563c232b34226f0316eb78d229ca562028e37e281ad76261131da044",
+ "chksum_sha256": "90aa16f9cbb70213bbfaea856f06a745627f46c4bdfe4bed25676bcb3beb4ba2",
"format": 1
},
{
- "name": "molecule/default/files",
+ "name": "plugins/modules/openshift_import_image.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1116270865430b4d5aac0d8ea4041a76f940554b4f1b42bff2508d1e503a6b26",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/openshift_process.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "97656e3d189e4905db8dc435b707b58181ef22f134ec559152e836f5d54d4bd9",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/openshift_registry_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e204f2672c2daa88228e6c19b5d556c05bfab5b1ec3b07b4e97fa0139626b9cc",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/openshift_route.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "27b4eab0a052bcbc0619d08104f2b040ad1b773b325d5f8b90c70fa54aa9d74f",
+ "format": 1
+ },
+ {
+ "name": "tests",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default/files/nginx.env",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "a68c2914576119a809943116ce0050ca221c5b8f3a6722fa6abbf15dababde5f",
+ "name": "tests/sanity",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "molecule/default/files/setup-crd.yml",
+ "name": "tests/sanity/ignore-2.10.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "509878fff22a19715f1c491930eefd23430c0f571716b463c3ab9a754d0fb250",
+ "chksum_sha256": "ba2285dad70183ce56e9d43ed97d4b7a1b12e7cdd3f4e5856fb3cf380148a5ee",
"format": 1
},
{
- "name": "molecule/default/files/pod-template.yaml",
+ "name": "tests/sanity/ignore-2.11.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5fcb22787bccf2a5e1b6b90617f1aabadb71e9c9a906763e68b8573ef468f09a",
+ "chksum_sha256": "dc0294c142585d8904331fd57755efc876e592ce8242e42e1159bcfddd4adbba",
"format": 1
},
{
- "name": "molecule/default/files/simple-template.yaml",
+ "name": "tests/sanity/ignore-2.12.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "acbc61a1278772f1fd80a1bdb6546b6022842f7fd1c1b9aaf8bd65b606d93a2b",
+ "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
"format": 1
},
{
- "name": "molecule/default/files/kuard-invalid-type.yml",
+ "name": "tests/sanity/ignore-2.13.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c0e8aa083eecb5c4d92108af83f9a2c931a2e5bbb766af4792adc4fb9fd9d32d",
+ "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
"format": 1
},
{
- "name": "molecule/default/files/example.env",
+ "name": "tests/sanity/ignore-2.14.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3701367ea0a79158d476e168c1b1e64639f703da926e63045cba5cfdbb6c3576",
+ "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
"format": 1
},
{
- "name": "molecule/default/files/kuard-extra-property.yml",
+ "name": "tests/sanity/ignore-2.15.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "27a06de7ca760698dc1d3c46ef12e40e214ae319a791a3965806b30adca06de0",
+ "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
"format": 1
},
{
- "name": "molecule/default/files/crd-resource.yml",
+ "name": "tests/sanity/ignore-2.16.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4921362ac3c4afac5f42ebb90b37bcb75e1fe20929bb0e45d0df4c190d28f577",
+ "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
"format": 1
},
{
- "name": "molecule/default/verify.yml",
+ "name": "tests/sanity/ignore-2.17.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0aa66e5d35f985e47345d47e378816189d77cb131520e115f05c8eea2ab3bfc6",
+ "chksum_sha256": "43bc048d24e8dd8fca8052b6135daaf59207e462f72cb9848f65de9c6e09552c",
"format": 1
},
{
- "name": "molecule/default/vars",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
+ "name": "tests/sanity/ignore-2.9.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cf94385a1d8a2b51f40f88879b59922c8a8b07b8f1e0ac511a2454e257361995",
"format": 1
},
{
- "name": "molecule/default/vars/main.yml",
+ "name": "tests/sanity/requirements.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "75f11fae6d7f1e6574152509a4d7ad306966fc94eda2e610dfdb8a529a531228",
+ "chksum_sha256": "c21e5168cbc64df9b025b078fa382484d308e6a633977cc57a3dd0c5fc1c70ed",
"format": 1
},
{
- "name": "ci",
+ "name": "tests/unit",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "ci/downstream.sh",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "75816fd56cb1a00c37234e84b4b2109f49cfad60901429a96e36f528202d3c2e",
+ "name": "tests/unit/plugins",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "ci/downstream_fragments.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "9815e2aa84aef5d396fd07ddb371fa87362ade6fbe72d829e4d5983abe8af453",
+ "name": "tests/unit/plugins/module_utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
"format": 1
},
{
- "name": "ci/doc_fragment_modules.py",
+ "name": "tests/unit/plugins/module_utils/test_ldap_dn.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e5f5e24396a2cc86faedf6d0b7a3835db06bbe6fc7b534018ed85ebecfa39e09",
+ "chksum_sha256": "08829b431c2006a4a99bbbc4d5eb6c61612c7542dd1865893dd2f811c9a2b1a4",
"format": 1
},
{
- "name": "ci/incluster_integration.sh",
+ "name": "tests/unit/plugins/module_utils/test_ldap_sync_config.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "012ffb20a006094a4e8a00ead7947a196c477c4eb071a1dad5ffe42f509935e1",
+ "chksum_sha256": "ab45e3fc6bcce7029a506464376bae9803a48cf99d1e3aa7b07caa475da561c2",
"format": 1
},
{
- "name": "ci/Dockerfile",
+ "name": "tests/unit/plugins/module_utils/test_openshift_docker_image.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "372a61931849250f7805a630fd5fc8b854f457d2752e1a70912beaa4773855ec",
+ "chksum_sha256": "3f058b71343cf91986e8a106444d6bc5f033d8bce6d1e6c9bb04d04d5deeb2db",
"format": 1
},
{
- "name": "docs",
+ "name": "tests/unit/plugins/modules",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
- "name": "docs/community.okd.openshift_route_module.rst",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "979c41e0c3ec23b57267104feaa400b798ddbb3f3157e77a22dad0b05d067d19",
- "format": 1
- },
- {
- "name": "docs/community.okd.openshift_adm_prune_images_module.rst",
+ "name": "tests/unit/plugins/modules/test_openshift_adm_migrate_template_instances.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4b5a9d72104e8cfee2e7973f094aaf8af666a2bdec615cee482411261f5dfa57",
+ "chksum_sha256": "4c426c87d28313524cbd378f917a2d70242f333571f942d44bc9bf8c7e591586",
"format": 1
},
{
- "name": "docs/community.okd.k8s_module.rst",
+ "name": "tests/unit/requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5d8bf2916753820405f62f00174687e62756dd2b610faea666f1ba077a02d573",
+ "chksum_sha256": "8004a972c3d5c274d8c808e8d8afe03b9aca8af8eebf3df4298f114d8008b754",
"format": 1
},
{
- "name": "docs/community.okd.openshift_inventory.rst",
+ "name": "tests/config.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "551e42026b2affd901c51f2be85fb69d9911e037edf424667eacc1b21aa00583",
+ "chksum_sha256": "4129945061440c8d8c281590b8054b194f5958833c722aa40e878b09038c380e",
"format": 1
},
{
- "name": "docs/ansible_turbo_mode.rst",
+ "name": ".gitignore",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a9bcd000c20de1d1ad35f5516f4fdffce07c8e28a5ebee572629a3b9cb867152",
+ "chksum_sha256": "8344abb7aafbdb654f0c88532af7ab557dad7a6a7cba60f4834f33c2a1f8524f",
"format": 1
},
{
- "name": "docs/community.okd.openshift_process_module.rst",
+ "name": ".yamllint",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3910d82ee4a8a31d84b6cbac6b7e6d6331d1ef9fe2b4331ce82e3065090baf66",
+ "chksum_sha256": "20f14c567d8ba0813a1ae58e298093a8004e4657baed321e4567de0f676beeaf",
"format": 1
},
{
- "name": "docs/community.okd.openshift_adm_groups_sync_module.rst",
+ "name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f8c405bb2c291cbdb3a0f4398bb9b205864dbb941cb0b0024e7cfa74d6ae49bd",
+ "chksum_sha256": "16845876aa6654eef1928c3cfddbe2a8846125d6165af1297c12564202901604",
"format": 1
},
{
- "name": "docs/community.okd.openshift_auth_module.rst",
+ "name": "CONTRIBUTING.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9c361ea64a0005fb0682c8fbd863cb7ef7cd0eb45f52383cc1123690e91fed11",
+ "chksum_sha256": "4156016c23606d288b98c4fa0eafc6afe1cf28e695fb5a267bcc3d337a7bfef0",
"format": 1
},
{
- "name": "docs/community.okd.oc_connection.rst",
+ "name": "LICENSE",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c0ffee1276ab6cfa6677b42fed2fcd8b46622ed5cb4c8ee0f9c9cac4db870f75",
+ "chksum_sha256": "8b1ba204bb69a0ade2bfcf65ef294a920f6bb361b317dba43c7ef29d96332b9b",
"format": 1
},
{
- "name": "docs/community.okd.openshift_adm_prune_auth_module.rst",
+ "name": "Makefile",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fbad4ddccea64f4ed415cf86d54b7d6fc3e6a7be46c19d11fb20202b527275dd",
+ "chksum_sha256": "624803bcb735d2b0c3ea45893d4d4640940044a0442815f3bd4047d1a09afd3a",
"format": 1
},
{
- "name": "docs/community.okd.openshift_adm_prune_builds_module.rst",
+ "name": "OWNERS",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d4762b6900b787b6efc27fbeede84044839e083fa5bd06165eb5c1b17f203a31",
+ "chksum_sha256": "771ebefb6c2b0154bf043cc537cc55b8421ddd4058248b00a62cdc9b190131da",
"format": 1
},
{
- "name": "docs/community.okd.openshift_import_image_module.rst",
+ "name": "OWNERS_ALIASES",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f031bc1985bda8784a3cb684767db28a469216ba7e47940bf7c49844acc87b08",
+ "chksum_sha256": "9ca328507f3e791383a7ab414eb73ab6d6becc4c637f2fdaace691e8be494774",
"format": 1
},
{
- "name": "docs/community.okd.openshift_build_module.rst",
+ "name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "50c1219f5524d60a4b46bc58c6df30d8af7b6e6ecc20fd4d15cf3e0fc352c05e",
+ "chksum_sha256": "957df67ccf2961757af99aa031a59310cbbe7addb7852c84717bbd6cab8dffa7",
"format": 1
},
{
- "name": "docs/community.okd.openshift_registry_info_module.rst",
+ "name": "codecov.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c66f8f9adb98eedcfda0e31034f5d14e881e9a41d3793fb36a3f311635166e69",
+ "chksum_sha256": "caa848a2e02be5014890c5cbc7727e9a00d40394637c90886eb813d60f82c9c3",
"format": 1
},
{
- "name": "docs/community.okd.openshift_adm_prune_deployments_module.rst",
+ "name": "requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "02693279a5b1c52eaf4fd70d8f01d87750f9b0554cd1d550892192b7070f558a",
+ "chksum_sha256": "d20fa49248fb968b70381346d2b2f6195e19dc1ddded06856bc4aefa6a25d431",
"format": 1
},
{
- "name": "docs/community.okd.openshift_adm_migrate_template_instances_module.rst",
+ "name": "requirements.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "99634e05dde50a01bd4cba0c696e3622864b744b6ea2f6103094c3809238ffd9",
+ "chksum_sha256": "c3d472e03d26b6fdeb1a9a3e986fb9df54ae2435406507e83050acc20433aedc",
"format": 1
},
{
- "name": "CHANGELOG.rst",
+ "name": "test-requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b22ef082f56193da0b6bd2984c3eff9beb4e5980017a7fcb4bcdad7898ff5112",
+ "chksum_sha256": "518d4932bf69764d9e3b577eb15452a40665b270dddcd5a9d58fec8ac6b26239",
"format": 1
},
{
- "name": "requirements.yml",
+ "name": "tox.ini",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a020e70b5ab59096b404e97d4f4a04a3d0b63627dbbcede89b3e131050fcccb4",
+ "chksum_sha256": "a61868a5974ff417ea848cd6ab079ff0441f30dc652d0c470ddc742658213f84",
"format": 1
}
],
diff --git a/ansible_collections/community/okd/MANIFEST.json b/ansible_collections/community/okd/MANIFEST.json
index dd2937e35..f12873236 100644
--- a/ansible_collections/community/okd/MANIFEST.json
+++ b/ansible_collections/community/okd/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "okd",
- "version": "2.3.0",
+ "version": "3.0.1",
"authors": [
"geerlingguy (https://www.jeffgeerling.com/)",
"fabianvf (https://github.com/fabianvf)",
@@ -23,7 +23,7 @@
"license": [],
"license_file": "LICENSE",
"dependencies": {
- "kubernetes.core": ">=2.4.0"
+ "kubernetes.core": ">=3.0.0"
},
"repository": "https://github.com/openshift/community.okd",
"documentation": "",
@@ -34,7 +34,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6e3f825a7ea74f2f591751d9ee4aac800f99ca344e86a5d00477306b14419ae8",
+ "chksum_sha256": "2e0de6ad088440b5ec4eb9313aa6dfacb5ae6be46f491cfc1302a8b321178167",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/okd/Makefile b/ansible_collections/community/okd/Makefile
index 7990f8447..b897aedb4 100644
--- a/ansible_collections/community/okd/Makefile
+++ b/ansible_collections/community/okd/Makefile
@@ -1,7 +1,7 @@
.PHONY: molecule
# Also needs to be updated in galaxy.yml
-VERSION = 2.3.0
+VERSION = 3.0.1
SANITY_TEST_ARGS ?= --docker --color
UNITS_TEST_ARGS ?= --docker --color
@@ -16,7 +16,7 @@ build: clean
ansible-galaxy collection build
install: build
- ansible-galaxy collection install -p ansible_collections community-okd-$(VERSION).tar.gz
+ ansible-galaxy collection install --force -p ansible_collections community-okd-$(VERSION).tar.gz
sanity: install
cd ansible_collections/community/okd && ansible-test sanity -v --python $(PYTHON_VERSION) $(SANITY_TEST_ARGS)
diff --git a/ansible_collections/community/okd/OWNERS_ALIASES b/ansible_collections/community/okd/OWNERS_ALIASES
index f65b7d7aa..16c8602e3 100644
--- a/ansible_collections/community/okd/OWNERS_ALIASES
+++ b/ansible_collections/community/okd/OWNERS_ALIASES
@@ -1,19 +1,11 @@
aliases:
community.okd-approvers:
- gravesm
- - akasurde
- - fabianvf
- - tima
- - goneri
- jillr
- alinabuzachis
- abikouo
community.okd-reviewers:
- gravesm
- - akasurde
- - fabianvf
- - tima
- - goneri
- jillr
- alinabuzachis
- abikouo
diff --git a/ansible_collections/community/okd/README.md b/ansible_collections/community/okd/README.md
index f3e1bba67..4f6ba618e 100644
--- a/ansible_collections/community/okd/README.md
+++ b/ansible_collections/community/okd/README.md
@@ -10,10 +10,9 @@ The collection includes a variety of Ansible content to help automate the manage
<!--start requires_ansible-->
## Ansible version compatibility
-This collection has been tested against following Ansible versions: **>=2.9.17**.
+This collection has been tested against following Ansible versions: **>=2.14.0**.
-For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
-fully qualified collection name (for example, `cisco.ios.ios`).
+Please ensure to update the `network_os` to use the fully qualified collection name (for example, `cisco.ios.ios`).
Plugins and modules within a collection may be tested with only specific Ansible versions.
A collection may contain metadata that identifies these versions.
PEP440 is the schema used to describe the versions of Ansible.
@@ -21,11 +20,11 @@ PEP440 is the schema used to describe the versions of Ansible.
## Python Support
-* Collection supports 3.6+
+* Collection supports 3.9+
## Kubernetes Version Support
-This collection supports Kubernetes versions >=1.19.
+This collection supports Kubernetes versions >=1.24.
## Included content
@@ -77,7 +76,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
---
collections:
- name: community.okd
- version: 2.3.0
+ version: 3.0.1
```
### Installing the Kubernetes Python Library
@@ -161,17 +160,17 @@ where the `IMAGE_FORMAT` environment variable is the full reference to your cont
Releases are automatically built and pushed to Ansible Galaxy for any new tag. Before tagging a release, make sure to do the following:
1. Update the version in the following places:
- a. The `version` in `galaxy.yml`
- b. This README's `requirements.yml` example
- c. The `DOWNSTREAM_VERSION` in `ci/downstream.sh`
- d. The `VERSION` in `Makefile`
- e. The version in `requirements.yml`
- 1. Update the CHANGELOG:
- 1. Make sure you have [`antsibull-changelog`](https://pypi.org/project/antsibull-changelog/) installed.
- 1. Make sure there are fragments for all known changes in `changelogs/fragments`.
- 1. Run `antsibull-changelog release`.
- 1. Commit the changes and create a PR with the changes. Wait for tests to pass, then merge it once they have.
- 1. Tag the version in Git and push to GitHub.
+ * a. The `version` in `galaxy.yml`
+ * b. This README's `requirements.yml` example
+ * c. The `DOWNSTREAM_VERSION` in `ci/downstream.sh`
+ * d. The `VERSION` in `Makefile`
+ * e. The version in `requirements.yml`
+ 2. Update the CHANGELOG:
+ * 1. Make sure you have [`antsibull-changelog`](https://pypi.org/project/antsibull-changelog/) installed.
+ * 2. Make sure there are fragments for all known changes in `changelogs/fragments`.
+ * 3. Run `antsibull-changelog release`.
+ 3. Commit the changes and create a PR with the changes. Wait for tests to pass, then merge it once they have.
+ 4. Tag the version in Git and push to GitHub.
After the version is published, verify it exists on the [OKD Collection Galaxy page](https://galaxy.ansible.com/community/okd).
<!--- ENDREMOVE --->
diff --git a/ansible_collections/community/okd/changelogs/.plugin-cache.yaml b/ansible_collections/community/okd/changelogs/.plugin-cache.yaml
deleted file mode 100644
index 223920534..000000000
--- a/ansible_collections/community/okd/changelogs/.plugin-cache.yaml
+++ /dev/null
@@ -1,92 +0,0 @@
-objects: {}
-plugins:
- become: {}
- cache: {}
- callback: {}
- cliconf: {}
- connection:
- oc:
- description: Execute tasks in pods running on OpenShift.
- name: oc
- version_added: null
- httpapi: {}
- inventory:
- openshift:
- description: OpenShift inventory source
- name: openshift
- version_added: null
- lookup: {}
- module:
- k8s:
- description: Manage OpenShift objects
- name: k8s
- namespace: ''
- version_added: null
- openshift_adm_groups_sync:
- description: Sync OpenShift Groups with records from an external provider.
- name: openshift_adm_groups_sync
- namespace: ''
- version_added: 2.1.0
- openshift_adm_migrate_template_instances:
- description: Update TemplateInstances to point to the latest group-version-kinds
- name: openshift_adm_migrate_template_instances
- namespace: ''
- version_added: 2.2.0
- openshift_adm_prune_auth:
- description: Removes references to the specified roles, clusterroles, users,
- and groups
- name: openshift_adm_prune_auth
- namespace: ''
- version_added: 2.2.0
- openshift_adm_prune_builds:
- description: Prune old completed and failed builds
- name: openshift_adm_prune_builds
- namespace: ''
- version_added: 2.3.0
- openshift_adm_prune_deployments:
- description: Remove old completed and failed deployment configs
- name: openshift_adm_prune_deployments
- namespace: ''
- version_added: 2.2.0
- openshift_adm_prune_images:
- description: Remove unreferenced images
- name: openshift_adm_prune_images
- namespace: ''
- version_added: 2.2.0
- openshift_auth:
- description: Authenticate to OpenShift clusters which require an explicit login
- step
- name: openshift_auth
- namespace: ''
- version_added: 0.2.0
- openshift_build:
- description: Start a new build or Cancel running, pending, or new builds.
- name: openshift_build
- namespace: ''
- version_added: 2.3.0
- openshift_import_image:
- description: Import the latest image information from a tag in a container image
- registry.
- name: openshift_import_image
- namespace: ''
- version_added: 2.2.0
- openshift_process:
- description: Process an OpenShift template.openshift.io/v1 Template
- name: openshift_process
- namespace: ''
- version_added: 0.3.0
- openshift_registry_info:
- description: Display information about the integrated registry.
- name: openshift_registry_info
- namespace: ''
- version_added: 2.2.0
- openshift_route:
- description: Expose a Service as an OpenShift Route.
- name: openshift_route
- namespace: ''
- version_added: 0.3.0
- netconf: {}
- shell: {}
- strategy: {}
- vars: {}
-version: 2.3.0
diff --git a/ansible_collections/community/okd/changelogs/changelog.yaml b/ansible_collections/community/okd/changelogs/changelog.yaml
index 12184d712..82cd00add 100644
--- a/ansible_collections/community/okd/changelogs/changelog.yaml
+++ b/ansible_collections/community/okd/changelogs/changelog.yaml
@@ -199,3 +199,28 @@ releases:
name: openshift_build
namespace: ''
release_date: '2023-02-03'
+ 3.0.0:
+ changes:
+ breaking_changes:
+ - Bump minimum Python suupported version to 3.9 (https://github.com/openshift/community.okd/pull/202).
+ - Remove support for ansible-core < 2.14 (https://github.com/openshift/community.okd/pull/202).
+ deprecated_features:
+ - openshift - the ``openshift`` inventory plugin has been deprecated and will
+ be removed in release 4.0.0 (https://github.com/ansible-collections/kubernetes.core/issues/31).
+ release_summary: This major release drops support for ansible-core versions
+ lower than 2.14 and Python versions lower than 3.9. It also deprecates ``openshift``
+ inventory plugin.
+ fragments:
+ - 20230206-deprecate-openshift-inventory.yml
+ - 20231107-move-sanity-and-units-to-gha.yml
+ release_date: '2023-11-20'
+ 3.0.1:
+ changes:
+ release_summary: 'This patch release fixes an issue in building the downstream
+ collection.
+
+ '
+ fragments:
+ - downstream-gitignore.yml
+ - release_summary.yml
+ release_date: '2023-11-30'
diff --git a/ansible_collections/community/okd/changelogs/config.yaml b/ansible_collections/community/okd/changelogs/config.yaml
index 1a31c10ed..4e6bb5e98 100644
--- a/ansible_collections/community/okd/changelogs/config.yaml
+++ b/ansible_collections/community/okd/changelogs/config.yaml
@@ -10,21 +10,21 @@ notesdir: fragments
prelude_section_name: release_summary
prelude_section_title: Release Summary
sections:
-- - major_changes
- - Major Changes
-- - minor_changes
- - Minor Changes
-- - breaking_changes
- - Breaking Changes / Porting Guide
-- - deprecated_features
- - Deprecated Features
-- - removed_features
- - Removed Features (previously deprecated)
-- - security_fixes
- - Security Fixes
-- - bugfixes
- - Bugfixes
-- - known_issues
- - Known Issues
+ - - major_changes
+ - Major Changes
+ - - minor_changes
+ - Minor Changes
+ - - breaking_changes
+ - Breaking Changes / Porting Guide
+ - - deprecated_features
+ - Deprecated Features
+ - - removed_features
+ - Removed Features (previously deprecated)
+ - - security_fixes
+ - Security Fixes
+ - - bugfixes
+ - Bugfixes
+ - - known_issues
+ - Known Issues
title: OKD Collection
trivial_section_name: trivial
diff --git a/ansible_collections/community/okd/ci/Dockerfile b/ansible_collections/community/okd/ci/Dockerfile
index 1a509190d..d57e7a007 100644
--- a/ansible_collections/community/okd/ci/Dockerfile
+++ b/ansible_collections/community/okd/ci/Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.access.redhat.com/ubi8/ubi
+FROM registry.access.redhat.com/ubi9/ubi
ENV OPERATOR=/usr/local/bin/ansible-operator \
USER_UID=1001 \
@@ -11,20 +11,20 @@ RUN yum install -y \
glibc-langpack-en \
git \
make \
- python39 \
- python39-devel \
- python39-pip \
- python39-setuptools \
+ python3 \
+ python3-devel \
+ python3-pip \
+ python3-setuptools \
gcc \
openldap-devel \
- && pip3 install --no-cache-dir --upgrade setuptools pip \
- && pip3 install --no-cache-dir \
+ && python3.9 -m pip install --no-cache-dir --upgrade setuptools pip \
+ && python3.9 -m pip install --no-cache-dir \
kubernetes \
- ansible==2.9.* \
- "molecule<3.3.0" \
+ "ansible-core" \
+ "molecule" \
&& yum clean all \
&& rm -rf $HOME/.cache \
- && curl -L https://github.com/openshift/okd/releases/download/4.5.0-0.okd-2020-08-12-020541/openshift-client-linux-4.5.0-0.okd-2020-08-12-020541.tar.gz | tar -xz -C /usr/local/bin
+ && curl -L https://github.com/openshift/okd/releases/download/4.12.0-0.okd-2023-04-16-041331/openshift-client-linux-4.12.0-0.okd-2023-04-16-041331.tar.gz | tar -xz -C /usr/local/bin
# TODO: Is there a better way to install this client in ubi8?
COPY . /opt/ansible
diff --git a/ansible_collections/community/okd/ci/downstream.sh b/ansible_collections/community/okd/ci/downstream.sh
index 001959c7e..c75398b77 100755
--- a/ansible_collections/community/okd/ci/downstream.sh
+++ b/ansible_collections/community/okd/ci/downstream.sh
@@ -9,7 +9,7 @@
# - All functions are prefixed with f_ so it's obvious where they come
# from when in use throughout the script
-DOWNSTREAM_VERSION="2.3.0"
+DOWNSTREAM_VERSION="3.0.1"
KEEP_DOWNSTREAM_TMPDIR="${KEEP_DOWNSTREAM_TMPDIR:-''}"
INSTALL_DOWNSTREAM_COLLECTION_PATH="${INSTALL_DOWNSTREAM_COLLECTION_PATH:-}"
_build_dir=""
@@ -47,7 +47,7 @@ f_text_sub()
sed -i.bak "s/Kubernetes/OpenShift/g" "${_build_dir}/galaxy.yml"
sed -i.bak "s/^version\:.*$/version: ${DOWNSTREAM_VERSION}/" "${_build_dir}/galaxy.yml"
sed -i.bak "/STARTREMOVE/,/ENDREMOVE/d" "${_build_dir}/README.md"
- sed -i.bak "s/[[:space:]]okd:$/ openshift:/" ${_build_dir}/meta/runtime.yml
+ sed -i.bak "s/[[:space:]]okd:$/ openshift:/" "${_build_dir}/meta/runtime.yml"
find "${_build_dir}" -type f ! -name galaxy.yml -exec sed -i.bak "s/community\.okd/redhat\.openshift/g" {} \;
find "${_build_dir}" -type f -name "*.bak" -delete
@@ -62,12 +62,12 @@ f_prep()
# Files to copy downstream (relative repo root dir path)
_file_manifest=(
+ .gitignore
CHANGELOG.rst
galaxy.yml
LICENSE
README.md
Makefile
- setup.cfg
.yamllint
requirements.txt
requirements.yml
@@ -76,6 +76,7 @@ f_prep()
# Directories to recursively copy downstream (relative repo root dir path)
_dir_manifest=(
+ .config
changelogs
ci
meta
@@ -145,7 +146,7 @@ f_handle_doc_fragments_workaround()
local rendered_fragments="./rendereddocfragments.txt"
# FIXME: Check Python interpreter from environment variable to work with prow
- PYTHON=${DOWNSTREAM_BUILD_PYTHON:-/usr/bin/python3.6}
+ PYTHON=${DOWNSTREAM_BUILD_PYTHON:-/usr/bin/python3}
f_log_info "Using Python interpreter: ${PYTHON}"
# Modules with inherited doc fragments from kubernetes.core that need
@@ -156,7 +157,7 @@ f_handle_doc_fragments_workaround()
# Build the collection, export docs, render them, stitch it all back together
pushd "${_build_dir}" || return
ansible-galaxy collection build
- ansible-galaxy collection install -p "${install_collections_dir}" ./*.tar.gz
+ ansible-galaxy collection install --force-with-deps -p "${install_collections_dir}" ./*.tar.gz
rm ./*.tar.gz
for doc_fragment_mod in "${_doc_fragment_modules[@]}"
do
diff --git a/ansible_collections/community/okd/docs/community.okd.k8s_module.rst b/ansible_collections/community/okd/docs/community.okd.k8s_module.rst
index 8d0e0f9dc..9a14c4417 100644
--- a/ansible_collections/community/okd/docs/community.okd.k8s_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.k8s_module.rst
@@ -354,6 +354,41 @@ Parameters
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kind</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -382,6 +417,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -451,6 +487,25 @@ Parameters
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -603,6 +658,7 @@ Parameters
<td>
<div>Provide a path to a file containing a valid YAML definition of an object or objects to be created or updated. Mutually exclusive with <em>resource_definition</em>. NOTE: <em>kind</em>, <em>api_version</em>, <em>name</em>, and <em>namespace</em> will be overwritten by corresponding values found in the configuration read in from the <em>src</em> file.</div>
<div>Reads from the local file system. To read from the Ansible controller&#x27;s file system, including vaulted files, use the file lookup plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to <em>resource_definition</em>. See Examples below.</div>
+ <div>The URL to manifest files that can be used to create the resource. Added in version 2.4.0.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>kubernetes.core.k8s</span> module.</div>
</td>
</tr>
@@ -938,10 +994,10 @@ Examples
app: galaxy
service: web
ports:
- - protocol: TCP
- targetPort: 8000
- name: port-8000-tcp
- port: 8000
+ - protocol: TCP
+ targetPort: 8000
+ name: port-8000-tcp
+ port: 8000
- name: Remove an existing Service object
community.okd.k8s:
@@ -975,15 +1031,15 @@ Examples
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
validate:
- fail_on_error: yes
+ fail_on_error: true
- name: warn on validation errors, check for unexpected properties
community.okd.k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
validate:
- fail_on_error: no
- strict: yes
+ fail_on_error: false
+ strict: true
@@ -1060,7 +1116,7 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
</td>
<td>error</td>
<td>
- <div>error while trying to create/delete the object.</div>
+ <div>Error while trying to create/delete the object.</div>
<br/>
</td>
</tr>
diff --git a/ansible_collections/community/okd/docs/community.okd.oc_connection.rst b/ansible_collections/community/okd/docs/community.okd.oc_connection.rst
index 14f2477cc..12869df2a 100644
--- a/ansible_collections/community/okd/docs/community.okd.oc_connection.rst
+++ b/ansible_collections/community/okd/docs/community.okd.oc_connection.rst
@@ -308,7 +308,7 @@ Status
Authors
~~~~~~~
-- xuxinkun
+- xuxinkun (@xuxinkun)
.. hint::
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_adm_groups_sync_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_adm_groups_sync_module.rst
index e16aa4d54..7d319a472 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_adm_groups_sync_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_adm_groups_sync_module.rst
@@ -55,6 +55,7 @@ Parameters
</div>
</td>
<td>
+ <b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>Allowed groups, could be openshift group name or LDAP group dn value.</div>
@@ -150,6 +151,7 @@ Parameters
</div>
</td>
<td>
+ <b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>Denied groups, could be openshift group name or LDAP group dn value.</div>
@@ -175,6 +177,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -185,12 +222,32 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -439,31 +496,31 @@ Examples
- name: Sync all groups from an LDAP server
openshift_adm_groups_sync:
src:
- kind: LDAPSyncConfig
- apiVersion: v1
- url: ldap://localhost:1390
- insecure: true
- bindDN: cn=admin,dc=example,dc=org
- bindPassword: adminpassword
- rfc2307:
- groupsQuery:
- baseDN: "cn=admins,ou=groups,dc=example,dc=org"
- scope: sub
- derefAliases: never
- filter: (objectClass=*)
- pageSize: 0
- groupUIDAttribute: dn
- groupNameAttributes: [ cn ]
- groupMembershipAttributes: [ member ]
- usersQuery:
- baseDN: "ou=users,dc=example,dc=org"
- scope: sub
- derefAliases: never
- pageSize: 0
- userUIDAttribute: dn
- userNameAttributes: [ mail ]
- tolerateMemberNotFoundErrors: true
- tolerateMemberOutOfScopeErrors: true
+ kind: LDAPSyncConfig
+ apiVersion: v1
+ url: ldap://localhost:1390
+ insecure: true
+ bindDN: cn=admin,dc=example,dc=org
+ bindPassword: adminpassword
+ rfc2307:
+ groupsQuery:
+ baseDN: "cn=admins,ou=groups,dc=example,dc=org"
+ scope: sub
+ derefAliases: never
+ filter: (objectClass=*)
+ pageSize: 0
+ groupUIDAttribute: dn
+ groupNameAttributes: [cn]
+ groupMembershipAttributes: [member]
+ usersQuery:
+ baseDN: "ou=users,dc=example,dc=org"
+ scope: sub
+ derefAliases: never
+ pageSize: 0
+ userUIDAttribute: dn
+ userNameAttributes: [mail]
+ tolerateMemberNotFoundErrors: true
+ tolerateMemberOutOfScopeErrors: true
# Sync all groups except the ones from the deny_groups from an LDAP server
- name: Sync all groups from an LDAP server using deny_groups
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_adm_migrate_template_instances_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_adm_migrate_template_instances_module.rst
index a7940ca85..c1d54dcfb 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_adm_migrate_template_instances_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_adm_migrate_template_instances_module.rst
@@ -137,6 +137,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -147,6 +182,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -169,6 +205,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -478,13 +533,13 @@ Examples
.. code-block:: yaml
- name: Migrate TemplateInstances in namespace=test
- community.okd.openshift_adm_migrate_template_instances:
- namespace: test
- register: _result
+ community.okd.openshift_adm_migrate_template_instances:
+ namespace: test
+ register: _result
- - name: Migrate TemplateInstances in all namespaces
- community.okd.openshift_adm_migrate_template_instances:
- register: _result
+ - name: Migrate TemplateInstances in all namespaces
+ community.okd.openshift_adm_migrate_template_instances:
+ register: _result
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_auth_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_auth_module.rst
index b4b11c2be..4e8e1dd95 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_auth_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_auth_module.rst
@@ -137,6 +137,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -147,6 +182,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -203,6 +239,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_builds_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_builds_module.rst
index 6fb9443b7..ccffb8d2b 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_builds_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_builds_module.rst
@@ -435,7 +435,7 @@ Examples
# all builds whose associated BuildConfig no longer exists
- name: Run delete orphan Builds
community.okd.openshift_adm_prune_builds:
- orphans: True
+ orphans: true
# Run deleting older completed and failed builds keep younger than 2hours
- name: Run delete builds, keep younger than 2h
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_deployments_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_deployments_module.rst
index 16e0deda9..0c73845b6 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_deployments_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_deployments_module.rst
@@ -137,6 +137,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>keep_younger_than</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -162,6 +197,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -183,6 +219,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>orphans</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -382,7 +437,7 @@ Examples
- name: Prune orphans deployments, keep younger than 2hours
community.okd.openshift_adm_prune_deployments:
- orphans: True
+ orphans: true
keep_younger_than: 120
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_images_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_images_module.rst
index 08fd357a3..9978b967c 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_images_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_adm_prune_images_module.rst
@@ -180,6 +180,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>keep_younger_than</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -205,6 +240,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -226,6 +262,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_auth_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_auth_module.rst
index 3619940ea..a6e77039e 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_auth_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_auth_module.rst
@@ -171,37 +171,40 @@ Examples
.. code-block:: yaml
- - hosts: localhost
+ - name: Example Playbook
+ hosts: localhost
module_defaults:
- group/k8s:
+ group/community.okd.okd:
host: https://k8s.example.com/
ca_cert: ca.pem
tasks:
- - block:
- # It's good practice to store login credentials in a secure vault and not
- # directly in playbooks.
- - include_vars: openshift_passwords.yml
-
- - name: Log in (obtain access token)
- community.okd.openshift_auth:
- username: admin
- password: "{{ openshift_admin_password }}"
- register: openshift_auth_results
-
- # Previous task provides the token/api_key, while all other parameters
- # are taken from module_defaults
- - name: Get a list of all pods from any namespace
- kubernetes.core.k8s_info:
- api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
- kind: Pod
- register: pod_list
-
- always:
- - name: If login succeeded, try to log out (revoke access token)
- when: openshift_auth_results.openshift_auth.api_key is defined
- community.okd.openshift_auth:
- state: absent
- api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
+ - name: Authenticate to OpenShift cluster and gell a list of all pods from any namespace
+ block:
+ # It's good practice to store login credentials in a secure vault and not
+ # directly in playbooks.
+ - name: Include 'openshift_passwords.yml'
+ ansible.builtin.include_vars: openshift_passwords.yml
+
+ - name: Log in (obtain access token)
+ community.okd.openshift_auth:
+ username: admin
+ password: "{{ openshift_admin_password }}"
+ register: openshift_auth_results
+
+ # Previous task provides the token/api_key, while all other parameters
+ # are taken from module_defaults
+ - name: Get a list of all pods from any namespace
+ kubernetes.core.k8s_info:
+ api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
+ kind: Pod
+ register: pod_list
+
+ always:
+ - name: If login succeeded, try to log out (revoke access token)
+ when: openshift_auth_results.openshift_auth.api_key is defined
+ community.okd.openshift_auth:
+ state: absent
+ api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_import_image_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_import_image_module.rst
index 920c8405b..c1bafd173 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_import_image_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_import_image_module.rst
@@ -160,6 +160,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -170,6 +205,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -209,6 +245,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_inventory.rst b/ansible_collections/community/okd/docs/community.okd.openshift_inventory.rst
index 57527f454..9015fb09f 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_inventory.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_inventory.rst
@@ -13,6 +13,15 @@ community.okd.openshift
:local:
:depth: 1
+DEPRECATED
+----------
+:Removed in collection release after
+:Why: As discussed in https://github.com/ansible-collections/kubernetes.core/issues/31, we decided to
+remove the openshift inventory plugin in release 4.0.0.
+
+:Alternative: Use :ref:`kubernetes.core.k8s_info <kubernetes.core.k8s_info_module>` and :ref:`ansible.builtin.add_host <ansible.builtin.add_host_module>` instead.
+
+
Synopsis
--------
@@ -320,24 +329,24 @@ Examples
# File must be named openshift.yaml or openshift.yml
- # Authenticate with token, and return all pods and services for all namespaces
- plugin: community.okd.openshift
- connections:
- - host: https://192.168.64.4:8443
- api_key: xxxxxxxxxxxxxxxx
- verify_ssl: false
+ - name: Authenticate with token, and return all pods and services for all namespaces
+ plugin: community.okd.openshift
+ connections:
+ - host: https://192.168.64.4:8443
+ api_key: xxxxxxxxxxxxxxxx
+ verify_ssl: false
- # Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
- plugin: community.okd.openshift
- connections:
- - namespaces:
- - testing
+ - name: Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
+ plugin: community.okd.openshift
+ connections:
+ - namespaces:
+ - testing
- # Use a custom config file, and a specific context.
- plugin: community.okd.openshift
- connections:
- - kubeconfig: /path/to/config
- context: 'awx/192-168-64-4:8443/developer'
+ - name: Use a custom config file, and a specific context.
+ plugin: community.okd.openshift
+ connections:
+ - kubeconfig: /path/to/config
+ context: 'awx/192-168-64-4:8443/developer'
@@ -346,10 +355,14 @@ Status
------
+- This inventory will be removed in version 4.0.0. *[deprecated]*
+- For more information see `DEPRECATED`_.
+
+
Authors
~~~~~~~
-- Chris Houseknecht <@chouseknecht>
+- Chris Houseknecht (@chouseknecht)
.. hint::
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_process_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_process_module.rst
index 7de7e8c3a..9ccc70221 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_process_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_process_module.rst
@@ -140,6 +140,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -150,6 +185,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -192,7 +228,7 @@ Parameters
<b>namespace_target</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
- <span style="color: purple">-</span>
+ <span style="color: purple">string</span>
</div>
</td>
<td>
@@ -205,6 +241,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>parameter_file</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -389,6 +444,7 @@ Parameters
<td>
<div>Provide a path to a file containing a valid YAML definition of an object or objects to be created or updated. Mutually exclusive with <em>resource_definition</em>. NOTE: <em>kind</em>, <em>api_version</em>, <em>name</em>, and <em>namespace</em> will be overwritten by corresponding values found in the configuration read in from the <em>src</em> file.</div>
<div>Reads from the local file system. To read from the Ansible controller&#x27;s file system, including vaulted files, use the file lookup plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to <em>resource_definition</em>. See Examples below.</div>
+ <div>The URL to manifest files that can be used to create the resource. Added in version 2.4.0.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>kubernetes.core.k8s</span> module.</div>
</td>
</tr>
@@ -616,8 +672,8 @@ Examples
community.okd.k8s:
namespace: default
definition: '{{ item }}'
- wait: yes
- apply: yes
+ wait: true
+ apply: true
loop: '{{ result.resources }}'
- name: Process a template with parameters from an env file and create the resources
@@ -627,7 +683,7 @@ Examples
namespace_target: default
parameter_file: 'files/nginx.env'
state: present
- wait: yes
+ wait: true
- name: Process a local template and create the resources
community.okd.openshift_process:
@@ -642,7 +698,7 @@ Examples
parameter_file: files/example.env
namespace_target: default
state: absent
- wait: yes
+ wait: true
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_registry_info_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_registry_info_module.rst
index f556d0f64..563678590 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_registry_info_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_registry_info_module.rst
@@ -159,6 +159,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -169,12 +204,32 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -356,7 +411,7 @@ Examples
# Read registry integrated information and attempt to contact using local client.
- name: Attempt to contact integrated registry using local client
community.okd.openshift_registry_info:
- check: yes
+ check: true
diff --git a/ansible_collections/community/okd/docs/community.okd.openshift_route_module.rst b/ansible_collections/community/okd/docs/community.okd.openshift_route_module.rst
index fc62623c5..4e939df8d 100644
--- a/ansible_collections/community/okd/docs/community.okd.openshift_route_module.rst
+++ b/ansible_collections/community/okd/docs/community.okd.openshift_route_module.rst
@@ -190,6 +190,41 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_groups</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ / <span style="color: purple">elements=string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Group(s) to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_GROUPS environment. Example: Group1,Group2</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>impersonate_user</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Username to impersonate for the operation.</div>
+ <div>Can also be specified via K8S_AUTH_IMPERSONATE_USER environment.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -200,6 +235,7 @@ Parameters
</td>
<td>
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
+ <div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -255,6 +291,25 @@ Parameters
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>no_proxy</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ <div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
+ <div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
+ <div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
+ <div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
@@ -801,10 +856,10 @@ Examples
app: hello-kubernetes
spec:
containers:
- - name: hello-kubernetes
- image: paulbouwer/hello-kubernetes:1.8
- ports:
- - containerPort: 8080
+ - name: hello-kubernetes
+ image: paulbouwer/hello-kubernetes:1.8
+ ports:
+ - containerPort: 8080
- name: Create Service for the hello-world deployment
community.okd.k8s:
@@ -816,8 +871,8 @@ Examples
namespace: default
spec:
ports:
- - port: 80
- targetPort: 8080
+ - port: 80
+ targetPort: 8080
selector:
app: hello-kubernetes
diff --git a/ansible_collections/community/okd/meta/runtime.yml b/ansible_collections/community/okd/meta/runtime.yml
index e1ab57a85..533a03020 100644
--- a/ansible_collections/community/okd/meta/runtime.yml
+++ b/ansible_collections/community/okd/meta/runtime.yml
@@ -1,5 +1,5 @@
---
-requires_ansible: '>=2.9.17'
+requires_ansible: '>=2.14.0'
action_groups:
okd:
- k8s
@@ -17,6 +17,13 @@ plugin_routing:
modules:
k8s_auth:
redirect: community.okd.openshift_auth
+ inventory:
+ openshift:
+ deprecation:
+ removal_version: 4.0.0
+ warning_text: >-
+ The openshift inventory plugin has been deprecated and
+ will be removed in release 4.0.0.
action:
k8s:
redirect: kubernetes.core.k8s_info
diff --git a/ansible_collections/community/okd/molecule/default/converge.yml b/ansible_collections/community/okd/molecule/default/converge.yml
index 7fe9e8209..fb45006c3 100644
--- a/ansible_collections/community/okd/molecule/default/converge.yml
+++ b/ansible_collections/community/okd/molecule/default/converge.yml
@@ -21,16 +21,13 @@
debug:
var: output
- - name: Create deployment config
+ - name: Create deployment
community.okd.k8s:
state: present
name: hello-world
namespace: testing
definition: '{{ okd_dc_template }}'
wait: yes
- wait_condition:
- type: Available
- status: True
vars:
k8s_pod_name: hello-world
k8s_pod_image: python
@@ -71,19 +68,12 @@
namespace: '{{ namespace }}'
definition: '{{ okd_imagestream_template }}'
- - name: Create DeploymentConfig to reference ImageStream
- community.okd.k8s:
- name: '{{ k8s_pod_name }}'
- namespace: '{{ namespace }}'
- definition: '{{ okd_dc_template }}'
- vars:
- k8s_pod_name: is-idempotent-dc
-
- name: Create Deployment to reference ImageStream
community.okd.k8s:
name: '{{ k8s_pod_name }}'
namespace: '{{ namespace }}'
definition: '{{ k8s_deployment_template | combine(metadata) }}'
+ wait: true
vars:
k8s_pod_annotations:
"alpha.image.policy.openshift.io/resolve-names": "*"
diff --git a/ansible_collections/community/okd/molecule/default/files/pod-template.yaml b/ansible_collections/community/okd/molecule/default/files/pod-template.yaml
index ac388ad67..3a1c8f1b8 100644
--- a/ansible_collections/community/okd/molecule/default/files/pod-template.yaml
+++ b/ansible_collections/community/okd/molecule/default/files/pod-template.yaml
@@ -10,14 +10,14 @@ objects:
name: "Pod-${{ NAME }}"
spec:
containers:
- - args:
- - /bin/sh
- - -c
- - while true; do echo $(date); sleep 15; done
- image: python:3.7-alpine
- imagePullPolicy: Always
- name: python
+ - args:
+ - /bin/sh
+ - -c
+ - while true; do echo $(date); sleep 15; done
+ image: python:3.7-alpine
+ imagePullPolicy: Always
+ name: python
parameters:
- - name: NAME
+ - name: NAME
description: trailing name of the pod
required: true
diff --git a/ansible_collections/community/okd/molecule/default/files/simple-template.yaml b/ansible_collections/community/okd/molecule/default/files/simple-template.yaml
index 29c85b9cd..c8270f776 100644
--- a/ansible_collections/community/okd/molecule/default/files/simple-template.yaml
+++ b/ansible_collections/community/okd/molecule/default/files/simple-template.yaml
@@ -13,22 +13,22 @@ metadata:
tags: quickstart,examples
name: simple-example
objects:
-- apiVersion: v1
- kind: ConfigMap
- metadata:
- annotations:
- description: Big example
- name: ${NAME}
- data:
- content: "${CONTENT}"
+ - apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ annotations:
+ description: Big example
+ name: ${NAME}
+ data:
+ content: "${CONTENT}"
parameters:
-- description: The name assigned to the ConfigMap
- displayName: Name
- name: NAME
- required: true
- value: example
-- description: The value for the content key of the configmap
- displayName: Content
- name: CONTENT
- required: true
- value: ''
+ - description: The name assigned to the ConfigMap
+ displayName: Name
+ name: NAME
+ required: true
+ value: example
+ - description: The value for the content key of the configmap
+ displayName: Content
+ name: CONTENT
+ required: true
+ value: ''
diff --git a/ansible_collections/community/okd/molecule/default/molecule.yml b/ansible_collections/community/okd/molecule/default/molecule.yml
index 43407bd26..7ca7e2c5b 100644
--- a/ansible_collections/community/okd/molecule/default/molecule.yml
+++ b/ansible_collections/community/okd/molecule/default/molecule.yml
@@ -4,7 +4,7 @@ dependency:
options:
requirements-file: requirements.yml
driver:
- name: delegated
+ name: default
platforms:
- name: cluster
groups:
@@ -17,9 +17,6 @@ provisioner:
config_options:
inventory:
enable_plugins: community.okd.openshift
- lint: |
- set -e
- ansible-lint
inventory:
hosts:
plugin: community.okd.openshift
@@ -34,14 +31,10 @@ provisioner:
ANSIBLE_COLLECTIONS_PATHS: ${OVERRIDE_COLLECTION_PATH:-$MOLECULE_PROJECT_DIRECTORY}
verifier:
name: ansible
- lint: |
- set -e
- ansible-lint
scenario:
name: default
test_sequence:
- dependency
- - lint
- syntax
- prepare
- converge
diff --git a/ansible_collections/community/okd/molecule/default/prepare.yml b/ansible_collections/community/okd/molecule/default/prepare.yml
index f155ec1d4..0d0361ab2 100644
--- a/ansible_collections/community/okd/molecule/default/prepare.yml
+++ b/ansible_collections/community/okd/molecule/default/prepare.yml
@@ -37,12 +37,12 @@
name: cluster
spec:
identityProviders:
- - name: htpasswd_provider
- mappingMethod: claim
- type: HTPasswd
- htpasswd:
- fileData:
- name: htpass-secret
+ - name: htpasswd_provider
+ mappingMethod: claim
+ type: HTPasswd
+ htpasswd:
+ fileData:
+ name: htpass-secret
- name: Create ClusterRoleBinding for test user
community.okd.k8s:
diff --git a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py
index ba49f724d..c5bde3e5f 100644
--- a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py
+++ b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/library/openshift_ldap_entry_info.py
@@ -89,6 +89,7 @@ def execute():
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
connection = ldap.initialize(module.params['server_uri'])
+ connection.set_option(ldap.OPT_REFERRALS, 0)
try:
connection.simple_bind_s(module.params['bind_dn'], module.params['bind_pw'])
except ldap.LDAPError as e:
diff --git a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml
index da99f324e..78131a876 100644
--- a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml
+++ b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/activeDirectory.yml
@@ -1,227 +1,227 @@
+---
- block:
- - name: Get LDAP definition
- set_fact:
- ldap_entries: "{{ lookup('template', 'ad/definition.j2') | from_yaml }}"
-
- - name: Delete openshift groups if existing
- community.okd.k8s:
- state: absent
- kind: Group
- version: "user.openshift.io/v1"
- name: "{{ item }}"
- with_items:
- - admins
- - developers
-
- - name: Delete existing LDAP Entries
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- state: absent
- with_items: "{{ ldap_entries.users + ldap_entries.units | reverse | list }}"
-
- - name: Create LDAP Entries
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- attributes: "{{ item.attr }}"
- objectClass: "{{ item.class }}"
- with_items: "{{ ldap_entries.units + ldap_entries.users }}"
-
- - name: Load test configurations
- set_fact:
- sync_config: "{{ lookup('template', 'ad/sync-config.j2') | from_yaml }}"
-
- - name: Synchronize Groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- check_mode: yes
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - admins_group
- - devs_group
- - '"jane.smith@ansible.org" in {{ admins_group.users }}'
- - '"jim.adams@ansible.org" in {{ admins_group.users }}'
- - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- - admins_group.users | length == 2
- - devs_group.users | length == 1
- vars:
- admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'admins') | first }}"
- devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
-
-
- - name: Synchronize Groups (Remove check_mode)
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
-
- - name: Read admins group
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: Validate group was created
- assert:
- that:
- - result.resources | length == 1
- - '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
- - '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Read developers group
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: developers
- register: result
-
- - name: Validate group was created
- assert:
- that:
- - result.resources | length == 1
- - '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Define user dn to delete
- set_fact:
- user_to_delete: "cn=Jane,ou=engineers,ou=activeD,{{ ldap_root }}"
-
- - name: Delete 1 admin user
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ user_to_delete }}"
- state: absent
-
- - name: Synchronize Openshift groups using allow_groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- allow_groups:
- - developers
- type: openshift
- register: openshift_sync
-
- - name: Validate that only developers group was sync
- assert:
- that:
- - openshift_sync is changed
- - openshift_sync.groups | length == 1
- - openshift_sync.groups.0.metadata.name == "developers"
-
- - name: Read admins group
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: Validate admins group content has not changed
- assert:
- that:
- - result.resources | length == 1
- - '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
- - '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Synchronize Openshift groups using deny_groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- deny_groups:
+ - name: Get LDAP definition
+ set_fact:
+ ldap_entries: "{{ lookup('template', 'ad/definition.j2') | from_yaml }}"
+
+ - name: Delete openshift groups if existing
+ community.okd.k8s:
+ state: absent
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: "{{ item }}"
+ with_items:
+ - admins
- developers
- type: openshift
- register: openshift_sync
-
- - name: Validate that only admins group was sync
- assert:
- that:
- - openshift_sync is changed
- - openshift_sync.groups | length == 1
- - openshift_sync.groups.0.metadata.name == "admins"
-
- - name: Read admins group
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: Validate admins group contains only 1 user now
- assert:
- that:
- - result.resources | length == 1
- - result.resources.0.users == ["jim.adams@ansible.org"]
-
- - name: Set users to delete (delete all developers users)
- set_fact:
- user_to_delete: "cn=Jordan,ou=engineers,ou=activeD,{{ ldap_root }}"
-
- - name: Delete 1 admin user
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ user_to_delete }}"
- state: absent
-
- - name: Prune groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- state: absent
- register: result
-
- - name: Validate result is changed (only developers group be deleted)
- assert:
- that:
- - result is changed
- - result.groups | length == 1
-
- - name: Get developers group info
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: developers
- register: result
-
- - name: assert group was deleted
- assert:
- that:
- - result.resources | length == 0
-
- - name: Get admins group info
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: assert group was not deleted
- assert:
- that:
- - result.resources | length == 1
-
- - name: Prune groups once again (idempotency)
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- state: absent
- register: result
-
- - name: Assert nothing was changed
- assert:
- that:
- - result is not changed
+
+ - name: Delete existing LDAP Entries
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ state: absent
+ with_items: "{{ ldap_entries.users + ldap_entries.units | reverse | list }}"
+
+ - name: Create LDAP Entries
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ attributes: "{{ item.attr }}"
+ objectClass: "{{ item.class }}"
+ with_items: "{{ ldap_entries.units + ldap_entries.users }}"
+
+ - name: Load test configurations
+ set_fact:
+ sync_config: "{{ lookup('template', 'ad/sync-config.j2') | from_yaml }}"
+
+ - name: Synchronize Groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ check_mode: yes
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - admins_group
+ - devs_group
+ - '"jane.smith@ansible.org" in {{ admins_group.users }}'
+ - '"jim.adams@ansible.org" in {{ admins_group.users }}'
+ - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
+ - admins_group.users | length == 2
+ - devs_group.users | length == 1
+ vars:
+ admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'admins') | first }}"
+ devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
+
+ - name: Synchronize Groups (Remove check_mode)
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+
+ - name: Read admins group
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: Validate group was created
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
+ - '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Read developers group
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: developers
+ register: result
+
+ - name: Validate group was created
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Define user dn to delete
+ set_fact:
+ user_to_delete: "cn=Jane,ou=engineers,ou=activeD,{{ ldap_root }}"
+
+ - name: Delete 1 admin user
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ user_to_delete }}"
+ state: absent
+
+ - name: Synchronize Openshift groups using allow_groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ allow_groups:
+ - developers
+ type: openshift
+ register: openshift_sync
+
+ - name: Validate that only developers group was sync
+ assert:
+ that:
+ - openshift_sync is changed
+ - openshift_sync.groups | length == 1
+ - openshift_sync.groups.0.metadata.name == "developers"
+
+ - name: Read admins group
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: Validate admins group content has not changed
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
+ - '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Synchronize Openshift groups using deny_groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ deny_groups:
+ - developers
+ type: openshift
+ register: openshift_sync
+
+ - name: Validate that only admins group was sync
+ assert:
+ that:
+ - openshift_sync is changed
+ - openshift_sync.groups | length == 1
+ - openshift_sync.groups.0.metadata.name == "admins"
+
+ - name: Read admins group
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: Validate admins group contains only 1 user now
+ assert:
+ that:
+ - result.resources | length == 1
+ - result.resources.0.users == ["jim.adams@ansible.org"]
+
+ - name: Set users to delete (delete all developers users)
+ set_fact:
+ user_to_delete: "cn=Jordan,ou=engineers,ou=activeD,{{ ldap_root }}"
+
+ - name: Delete 1 admin user
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ user_to_delete }}"
+ state: absent
+
+ - name: Prune groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ state: absent
+ register: result
+
+ - name: Validate result is changed (only developers group be deleted)
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+
+ - name: Get developers group info
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: developers
+ register: result
+
+ - name: assert group was deleted
+ assert:
+ that:
+ - result.resources | length == 0
+
+ - name: Get admins group info
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: assert group was not deleted
+ assert:
+ that:
+ - result.resources | length == 1
+
+ - name: Prune groups once again (idempotency)
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ state: absent
+ register: result
+
+ - name: Assert nothing was changed
+ assert:
+ that:
+ - result is not changed
always:
- name: Delete openshift groups if existing
diff --git a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml
index f70d3bd8e..f089b33ad 100644
--- a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml
+++ b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/augmentedActiveDirectory.yml
@@ -1,166 +1,165 @@
+---
- block:
- - name: Get LDAP definition
- set_fact:
- ldap_entries: "{{ lookup('template', 'augmented-ad/definition.j2') | from_yaml }}"
-
- - name: Delete openshift groups if existing
- community.okd.k8s:
- state: absent
- kind: Group
- version: "user.openshift.io/v1"
- name: "{{ item }}"
- with_items:
- - banking
- - insurance
-
- - name: Delete existing LDAP entries
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- state: absent
- with_items: "{{ ldap_entries.users + ldap_entries.groups + ldap_entries.units | reverse | list }}"
-
- - name: Create LDAP Entries
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- attributes: "{{ item.attr }}"
- objectClass: "{{ item.class }}"
- with_items: "{{ ldap_entries.units + ldap_entries.groups + ldap_entries.users }}"
-
- - name: Load test configurations
- set_fact:
- sync_config: "{{ lookup('template', 'augmented-ad/sync-config.j2') | from_yaml }}"
-
- - name: Synchronize Groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- check_mode: yes
- register: result
-
- - name: Validate that 'banking' and 'insurance' groups were created
- assert:
- that:
- - result is changed
- - banking_group
- - insurance_group
- - '"james-allan@ansible.org" in {{ banking_group.users }}'
- - '"gordon-kane@ansible.org" in {{ banking_group.users }}'
- - '"alice-courtney@ansible.org" in {{ insurance_group.users }}'
- - banking_group.users | length == 2
- - insurance_group.users | length == 1
- vars:
- banking_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'banking') | first }}"
- insurance_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'insurance') | first }}"
-
-
- - name: Synchronize Groups (Remove check_mode)
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
-
- - name: Define facts for group to create
- set_fact:
- ldap_groups:
- - name: banking
- users:
- - "james-allan@ansible.org"
- - "gordon-kane@ansible.org"
- - name: insurance
- users:
- - "alice-courtney@ansible.org"
-
-
- - name: Read 'banking' openshift group
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: banking
- register: result
-
- - name: Validate group info
- assert:
- that:
- - result.resources | length == 1
- - '"james-allan@ansible.org" in {{ result.resources.0.users }}'
- - '"gordon-kane@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Read 'insurance' openshift group
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: insurance
- register: result
-
- - name: Validate group info
- assert:
- that:
- - result.resources | length == 1
- - 'result.resources.0.users == ["alice-courtney@ansible.org"]'
-
- - name: Delete employee from 'insurance' group
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "cn=Alice,ou=employee,ou=augmentedAD,{{ ldap_root }}"
- state: absent
-
- - name: Prune groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- state: absent
- register: result
-
- - name: Validate result is changed (only insurance group be deleted)
- assert:
- that:
- - result is changed
- - result.groups | length == 1
-
- - name: Get 'insurance' openshift group info
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: insurance
- register: result
-
- - name: assert group was deleted
- assert:
- that:
- - result.resources | length == 0
-
- - name: Get 'banking' openshift group info
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: banking
- register: result
-
- - name: assert group was not deleted
- assert:
- that:
- - result.resources | length == 1
-
- - name: Prune groups once again (idempotency)
- community.okd.openshift_adm_groups_sync:
- config: "{{ sync_config }}"
- state: absent
- register: result
-
- - name: Assert no change was made
- assert:
- that:
- - result is not changed
+ - name: Get LDAP definition
+ set_fact:
+ ldap_entries: "{{ lookup('template', 'augmented-ad/definition.j2') | from_yaml }}"
+
+ - name: Delete openshift groups if existing
+ community.okd.k8s:
+ state: absent
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: "{{ item }}"
+ with_items:
+ - banking
+ - insurance
+
+ - name: Delete existing LDAP entries
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ state: absent
+ with_items: "{{ ldap_entries.users + ldap_entries.groups + ldap_entries.units | reverse | list }}"
+
+ - name: Create LDAP Entries
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ attributes: "{{ item.attr }}"
+ objectClass: "{{ item.class }}"
+ with_items: "{{ ldap_entries.units + ldap_entries.groups + ldap_entries.users }}"
+
+ - name: Load test configurations
+ set_fact:
+ sync_config: "{{ lookup('template', 'augmented-ad/sync-config.j2') | from_yaml }}"
+
+ - name: Synchronize Groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ check_mode: yes
+ register: result
+
+ - name: Validate that 'banking' and 'insurance' groups were created
+ assert:
+ that:
+ - result is changed
+ - banking_group
+ - insurance_group
+ - '"james-allan@ansible.org" in {{ banking_group.users }}'
+ - '"gordon-kane@ansible.org" in {{ banking_group.users }}'
+ - '"alice-courtney@ansible.org" in {{ insurance_group.users }}'
+ - banking_group.users | length == 2
+ - insurance_group.users | length == 1
+ vars:
+ banking_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'banking') | first }}"
+ insurance_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'insurance') | first }}"
+
+ - name: Synchronize Groups (Remove check_mode)
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+
+ - name: Define facts for group to create
+ set_fact:
+ ldap_groups:
+ - name: banking
+ users:
+ - "james-allan@ansible.org"
+ - "gordon-kane@ansible.org"
+ - name: insurance
+ users:
+ - "alice-courtney@ansible.org"
+
+ - name: Read 'banking' openshift group
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: banking
+ register: result
+
+ - name: Validate group info
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"james-allan@ansible.org" in {{ result.resources.0.users }}'
+ - '"gordon-kane@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Read 'insurance' openshift group
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: insurance
+ register: result
+
+ - name: Validate group info
+ assert:
+ that:
+ - result.resources | length == 1
+ - 'result.resources.0.users == ["alice-courtney@ansible.org"]'
+
+ - name: Delete employee from 'insurance' group
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "cn=Alice,ou=employee,ou=augmentedAD,{{ ldap_root }}"
+ state: absent
+
+ - name: Prune groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ state: absent
+ register: result
+
+ - name: Validate result is changed (only insurance group be deleted)
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+
+ - name: Get 'insurance' openshift group info
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: insurance
+ register: result
+
+ - name: assert group was deleted
+ assert:
+ that:
+ - result.resources | length == 0
+
+ - name: Get 'banking' openshift group info
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: banking
+ register: result
+
+ - name: assert group was not deleted
+ assert:
+ that:
+ - result.resources | length == 1
+
+ - name: Prune groups once again (idempotency)
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ sync_config }}"
+ state: absent
+ register: result
+
+ - name: Assert no change was made
+ assert:
+ that:
+ - result is not changed
always:
- name: Delete openshift groups if existing
diff --git a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/main.yml b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/main.yml
index 88bfd67f8..5dc79c1f0 100644
--- a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/main.yml
+++ b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/main.yml
@@ -1,5 +1,5 @@
---
-- name: Get cluster information
+- name: Get cluster information
kubernetes.core.k8s_cluster_info:
register: info
@@ -16,30 +16,29 @@
app: ldap
spec:
containers:
- - name: ldap
- image: bitnami/openldap
- env:
- - name: LDAP_ADMIN_USERNAME
- value: "{{ ldap_admin_user }}"
- - name: LDAP_ADMIN_PASSWORD
- value: "{{ ldap_admin_password }}"
- - name: LDAP_USERS
- value: "ansible"
- - name: LDAP_PASSWORDS
- value: "ansible123"
- - name: LDAP_ROOT
- value: "{{ ldap_root }}"
- ports:
- - containerPort: 1389
+ - name: ldap
+ image: bitnami/openldap
+ env:
+ - name: LDAP_ADMIN_USERNAME
+ value: "{{ ldap_admin_user }}"
+ - name: LDAP_ADMIN_PASSWORD
+ value: "{{ ldap_admin_password }}"
+ - name: LDAP_USERS
+ value: "ansible"
+ - name: LDAP_PASSWORDS
+ value: "ansible123"
+ - name: LDAP_ROOT
+ value: "{{ ldap_root }}"
+ ports:
+ - containerPort: 1389
+ name: ldap-server
register: pod_info
-- name: Set Pod Internal IP
- set_fact:
- podIp: "{{ pod_info.result.status.podIP }}"
-
- name: Set LDAP Common facts
set_fact:
- ldap_server_uri: "ldap://{{ podIp }}:1389"
+ # we can use the Pod IP directly because the integration are running inside a Pod in the
+ # same openshift cluster
+ ldap_server_uri: "ldap://{{ pod_info.result.status.podIP }}:1389"
ldap_bind_dn: "cn={{ ldap_admin_user }},{{ ldap_root }}"
ldap_bind_pw: "{{ ldap_admin_password }}"
@@ -53,8 +52,10 @@
bind_pw: "{{ ldap_bind_pw }}"
dn: "ou=users,{{ ldap_root }}"
server_uri: "{{ ldap_server_uri }}"
- # ignore_errors: true
- # register: ping_ldap
+ register: test_ldap
+ retries: 10
+ delay: 5
+ until: test_ldap is not failed
- include_tasks: "tasks/python-ldap-not-installed.yml"
- include_tasks: "tasks/rfc2307.yml"
diff --git a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml
index a79af51c2..857ff4903 100644
--- a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml
+++ b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/python-ldap-not-installed.yml
@@ -1,3 +1,4 @@
+---
- block:
- name: Create temp directory
tempfile:
diff --git a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml
index 7660bf625..749dfdae3 100644
--- a/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml
+++ b/ansible_collections/community/okd/molecule/default/roles/openshift_adm_groups/tasks/rfc2307.yml
@@ -1,459 +1,460 @@
+---
- block:
- - name: Get LDAP definition
- set_fact:
- ldap_resources: "{{ lookup('template', 'rfc2307/definition.j2') | from_yaml }}"
-
- - name: Delete openshift groups if existing
- community.okd.k8s:
- state: absent
- kind: Group
- version: "user.openshift.io/v1"
- name: "{{ item }}"
- with_items:
- - admins
- - engineers
- - developers
-
- - name: Delete existing LDAP entries
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- state: absent
- with_items: "{{ ldap_resources.users + ldap_resources.groups + ldap_resources.units | reverse | list }}"
-
- - name: Create LDAP units
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- attributes: "{{ item.attr }}"
- objectClass: "{{ item.class }}"
- with_items: "{{ ldap_resources.units }}"
-
- - name: Create LDAP Groups
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- attributes: "{{ item.attr }}"
- objectClass: "{{ item.class }}"
- with_items: "{{ ldap_resources.groups }}"
-
- - name: Create LDAP users
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item.dn }}"
- attributes: "{{ item.attr }}"
- objectClass: "{{ item.class }}"
- with_items: "{{ ldap_resources.users }}"
-
- - name: Load test configurations
- set_fact:
- configs: "{{ lookup('template', 'rfc2307/sync-config.j2') | from_yaml }}"
-
- - name: Synchronize Groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.simple }}"
- check_mode: yes
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - admins_group
- - devs_group
- - '"jane.smith@ansible.org" in {{ admins_group.users }}'
- - '"jim.adams@ansible.org" in {{ devs_group.users }}'
- - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- - admins_group.users | length == 1
- - devs_group.users | length == 2
- vars:
- admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'admins') | first }}"
- devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
-
- - name: Synchronize Groups - User defined mapping
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.user_defined }}"
- check_mode: yes
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - admins_group
- - devs_group
- - '"jane.smith@ansible.org" in {{ admins_group.users }}'
- - '"jim.adams@ansible.org" in {{ devs_group.users }}'
- - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- - admins_group.users | length == 1
- - devs_group.users | length == 2
- vars:
- admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-admins') | first }}"
- devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-devs') | first }}"
-
- - name: Synchronize Groups - Using dn for every query
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.dn_everywhere }}"
- check_mode: yes
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - admins_group
- - devs_group
- - '"cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ admins_group.users }}'
- - '"cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ devs_group.users }}'
- - '"cn=Jordan,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ devs_group.users }}'
- - admins_group.users | length == 1
- - devs_group.users | length == 2
- vars:
- admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'cn=admins,ou=groups,ou=rfc2307,' + ldap_root ) | first }}"
- devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'cn=developers,ou=groups,ou=rfc2307,' + ldap_root ) | first }}"
-
- - name: Synchronize Groups - Partially user defined mapping
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.partially_user_defined }}"
- check_mode: yes
- register: result
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - admins_group
- - devs_group
- - '"jane.smith@ansible.org" in {{ admins_group.users }}'
- - '"jim.adams@ansible.org" in {{ devs_group.users }}'
- - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
- - admins_group.users | length == 1
- - devs_group.users | length == 2
- vars:
- admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-admins') | first }}"
- devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
-
- - name: Delete Group 'engineers' if created before
- community.okd.k8s:
- state: absent
- kind: Group
- version: "user.openshift.io/v1"
- name: 'engineers'
- wait: yes
- ignore_errors: yes
-
- - name: Synchronize Groups - Partially user defined mapping
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.out_scope }}"
- check_mode: yes
- register: result
- ignore_errors: yes
-
- - name: Assert group sync failed due to non-existent member
- assert:
- that:
- - result is failed
- - result.msg.startswith("Entry not found for base='cn=Matthew,ou=people,ou=outrfc2307,{{ ldap_root }}'")
-
- - name: Define sync configuration with tolerateMemberNotFoundErrors
- set_fact:
- config_out_of_scope_tolerate_not_found: "{{ configs.out_scope | combine({'rfc2307': merge_rfc2307 })}}"
- vars:
- merge_rfc2307: "{{ configs.out_scope.rfc2307 | combine({'tolerateMemberNotFoundErrors': 'true'}) }}"
-
- - name: Synchronize Groups - Partially user defined mapping (tolerateMemberNotFoundErrors=true)
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_out_of_scope_tolerate_not_found }}"
- check_mode: yes
- register: result
-
- - name: Assert group sync did not fail (tolerateMemberNotFoundErrors=true)
- assert:
- that:
- - result is changed
- - result.groups | length == 1
- - result.groups.0.metadata.name == 'engineers'
- - result.groups.0.users == ['Abraham']
-
- - name: Create Group 'engineers'
- community.okd.k8s:
- state: present
- wait: yes
- definition:
+ - name: Get LDAP definition
+ set_fact:
+ ldap_resources: "{{ lookup('template', 'rfc2307/definition.j2') | from_yaml }}"
+
+ - name: Delete openshift groups if existing
+ community.okd.k8s:
+ state: absent
kind: Group
- apiVersion: "user.openshift.io/v1"
- metadata:
- name: engineers
- users: []
-
- - name: Try to sync LDAP group with Openshift existing group not created using sync should failed
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_out_of_scope_tolerate_not_found }}"
- check_mode: yes
- register: result
- ignore_errors: yes
-
- - name: Validate group sync failed
- assert:
- that:
- - result is failed
- - '"openshift.io/ldap.host label did not match sync host" in result.msg'
-
- - name: Define allow_groups and deny_groups groups
- set_fact:
- allow_groups:
- - "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
- deny_groups:
- - "cn=admins,ou=groups,ou=rfc2307,{{ ldap_root }}"
-
- - name: Synchronize Groups using allow_groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.simple }}"
- allow_groups: "{{ allow_groups }}"
- register: result
- check_mode: yes
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - result.groups | length == 1
- - result.groups.0.metadata.name == "developers"
-
- - name: Synchronize Groups using deny_groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.simple }}"
- deny_groups: "{{ deny_groups }}"
- register: result
- check_mode: yes
-
- - name: Validate Group going to be created
- assert:
- that:
- - result is changed
- - result.groups | length == 1
- - result.groups.0.metadata.name == "developers"
-
- - name: Synchronize groups, remove check_mode
- community.okd.openshift_adm_groups_sync:
- config: "{{ configs.simple }}"
- register: result
-
- - name: Validate result is changed
- assert:
- that:
- - result is changed
-
- - name: Read Groups
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: Validate group was created
- assert:
- that:
- - result.resources | length == 1
- - '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Read Groups
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: developers
- register: result
-
- - name: Validate group was created
- assert:
- that:
- - result.resources | length == 1
- - '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
- - '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Set users to delete (no admins users anymore and only 1 developer kept)
- set_fact:
- users_to_delete:
- - "cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}"
- - "cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}"
-
- - name: Delete users from LDAP servers
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item }}"
- state: absent
- with_items: "{{ users_to_delete }}"
-
- - name: Define sync configuration with tolerateMemberNotFoundErrors
- set_fact:
- config_simple_tolerate_not_found: "{{ configs.simple | combine({'rfc2307': merge_rfc2307 })}}"
- vars:
- merge_rfc2307: "{{ configs.simple.rfc2307 | combine({'tolerateMemberNotFoundErrors': 'true'}) }}"
-
- - name: Synchronize groups once again after users deletion
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_simple_tolerate_not_found }}"
- register: result
-
- - name: Validate result is changed
- assert:
- that:
- - result is changed
-
- - name: Read Groups
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: Validate admins group does not contains users anymore
- assert:
- that:
- - result.resources | length == 1
- - result.resources.0.users == []
-
- - name: Read Groups
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: developers
- register: result
-
- - name: Validate group was created
- assert:
- that:
- - result.resources | length == 1
- - '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
-
- - name: Set group to delete
- set_fact:
- groups_to_delete:
- - "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
-
- - name: Delete Group from LDAP servers
- openshift_ldap_entry:
- bind_dn: "{{ ldap_bind_dn }}"
- bind_pw: "{{ ldap_bind_pw }}"
- server_uri: "{{ ldap_server_uri }}"
- dn: "{{ item }}"
- state: absent
- with_items: "{{ groups_to_delete }}"
-
- - name: Prune groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_simple_tolerate_not_found }}"
- state: absent
- register: result
- check_mode: yes
-
- - name: Validate that only developers group is candidate for Prune
- assert:
- that:
- - result is changed
- - result.groups | length == 1
- - result.groups.0.metadata.name == "developers"
-
- - name: Read Group (validate that check_mode did not performed update in the cluster)
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: developers
- register: result
-
- - name: Assert group was found
- assert:
- that:
- - result.resources | length == 1
-
- - name: Prune using allow_groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_simple_tolerate_not_found }}"
- allow_groups:
- - developers
- state: absent
- register: result
- check_mode: yes
-
- - name: assert developers group was candidate for prune
- assert:
- that:
- - result is changed
- - result.groups | length == 1
- - result.groups.0.metadata.name == "developers"
-
- - name: Prune using deny_groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_simple_tolerate_not_found }}"
- deny_groups:
+ version: "user.openshift.io/v1"
+ name: "{{ item }}"
+ with_items:
+ - admins
+ - engineers
- developers
- state: absent
- register: result
- check_mode: yes
-
- - name: assert nothing found candidate for prune
- assert:
- that:
- - result is not changed
- - result.groups | length == 0
-
- - name: Prune groups
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_simple_tolerate_not_found }}"
- state: absent
- register: result
-
- - name: Validate result is changed
- assert:
- that:
- - result is changed
- - result.groups | length == 1
-
- - name: Get developers group info
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: developers
- register: result
-
- - name: assert group was deleted
- assert:
- that:
- - result.resources | length == 0
-
- - name: Get admins group info
- kubernetes.core.k8s_info:
- kind: Group
- version: "user.openshift.io/v1"
- name: admins
- register: result
-
- - name: assert group was not deleted
- assert:
- that:
- - result.resources | length == 1
-
- - name: Prune groups once again (idempotency)
- community.okd.openshift_adm_groups_sync:
- config: "{{ config_simple_tolerate_not_found }}"
- state: absent
- register: result
-
- - name: Assert nothing changed
- assert:
- that:
- - result is not changed
- - result.groups | length == 0
+
+ - name: Delete existing LDAP entries
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ state: absent
+ with_items: "{{ ldap_resources.users + ldap_resources.groups + ldap_resources.units | reverse | list }}"
+
+ - name: Create LDAP units
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ attributes: "{{ item.attr }}"
+ objectClass: "{{ item.class }}"
+ with_items: "{{ ldap_resources.units }}"
+
+ - name: Create LDAP Groups
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ attributes: "{{ item.attr }}"
+ objectClass: "{{ item.class }}"
+ with_items: "{{ ldap_resources.groups }}"
+
+ - name: Create LDAP users
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item.dn }}"
+ attributes: "{{ item.attr }}"
+ objectClass: "{{ item.class }}"
+ with_items: "{{ ldap_resources.users }}"
+
+ - name: Load test configurations
+ set_fact:
+ configs: "{{ lookup('template', 'rfc2307/sync-config.j2') | from_yaml }}"
+
+ - name: Synchronize Groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.simple }}"
+ check_mode: yes
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - admins_group
+ - devs_group
+ - '"jane.smith@ansible.org" in {{ admins_group.users }}'
+ - '"jim.adams@ansible.org" in {{ devs_group.users }}'
+ - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
+ - admins_group.users | length == 1
+ - devs_group.users | length == 2
+ vars:
+ admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'admins') | first }}"
+ devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
+
+ - name: Synchronize Groups - User defined mapping
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.user_defined }}"
+ check_mode: yes
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - admins_group
+ - devs_group
+ - '"jane.smith@ansible.org" in {{ admins_group.users }}'
+ - '"jim.adams@ansible.org" in {{ devs_group.users }}'
+ - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
+ - admins_group.users | length == 1
+ - devs_group.users | length == 2
+ vars:
+ admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-admins') | first }}"
+ devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-devs') | first }}"
+
+ - name: Synchronize Groups - Using dn for every query
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.dn_everywhere }}"
+ check_mode: yes
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - admins_group
+ - devs_group
+ - '"cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ admins_group.users }}'
+ - '"cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ devs_group.users }}'
+ - '"cn=Jordan,ou=people,ou=rfc2307,{{ ldap_root }}" in {{ devs_group.users }}'
+ - admins_group.users | length == 1
+ - devs_group.users | length == 2
+ vars:
+ admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'cn=admins,ou=groups,ou=rfc2307,' + ldap_root ) | first }}"
+ devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'cn=developers,ou=groups,ou=rfc2307,' + ldap_root ) | first }}"
+
+ - name: Synchronize Groups - Partially user defined mapping
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.partially_user_defined }}"
+ check_mode: yes
+ register: result
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - admins_group
+ - devs_group
+ - '"jane.smith@ansible.org" in {{ admins_group.users }}'
+ - '"jim.adams@ansible.org" in {{ devs_group.users }}'
+ - '"jordanbulls@ansible.org" in {{ devs_group.users }}'
+ - admins_group.users | length == 1
+ - devs_group.users | length == 2
+ vars:
+ admins_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'ansible-admins') | first }}"
+ devs_group: "{{ result.groups | selectattr('metadata.name', 'equalto', 'developers') | first }}"
+
+ - name: Delete Group 'engineers' if created before
+ community.okd.k8s:
+ state: absent
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: 'engineers'
+ wait: yes
+ ignore_errors: yes
+
+ - name: Synchronize Groups - Partially user defined mapping
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.out_scope }}"
+ check_mode: yes
+ register: result
+ ignore_errors: yes
+
+ - name: Assert group sync failed due to non-existent member
+ assert:
+ that:
+ - result is failed
+ - result.msg.startswith("Entry not found for base='cn=Matthew,ou=people,ou=outrfc2307,{{ ldap_root }}'")
+
+ - name: Define sync configuration with tolerateMemberNotFoundErrors
+ set_fact:
+ config_out_of_scope_tolerate_not_found: "{{ configs.out_scope | combine({'rfc2307': merge_rfc2307 })}}"
+ vars:
+ merge_rfc2307: "{{ configs.out_scope.rfc2307 | combine({'tolerateMemberNotFoundErrors': 'true'}) }}"
+
+ - name: Synchronize Groups - Partially user defined mapping (tolerateMemberNotFoundErrors=true)
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_out_of_scope_tolerate_not_found }}"
+ check_mode: yes
+ register: result
+
+ - name: Assert group sync did not fail (tolerateMemberNotFoundErrors=true)
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+ - result.groups.0.metadata.name == 'engineers'
+ - result.groups.0.users == ['Abraham']
+
+ - name: Create Group 'engineers'
+ community.okd.k8s:
+ state: present
+ wait: yes
+ definition:
+ kind: Group
+ apiVersion: "user.openshift.io/v1"
+ metadata:
+ name: engineers
+ users: []
+
+ - name: Try to sync LDAP group with Openshift existing group not created using sync should failed
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_out_of_scope_tolerate_not_found }}"
+ check_mode: yes
+ register: result
+ ignore_errors: yes
+
+ - name: Validate group sync failed
+ assert:
+ that:
+ - result is failed
+ - '"openshift.io/ldap.host label did not match sync host" in result.msg'
+
+ - name: Define allow_groups and deny_groups groups
+ set_fact:
+ allow_groups:
+ - "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
+ deny_groups:
+ - "cn=admins,ou=groups,ou=rfc2307,{{ ldap_root }}"
+
+ - name: Synchronize Groups using allow_groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.simple }}"
+ allow_groups: "{{ allow_groups }}"
+ register: result
+ check_mode: yes
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+ - result.groups.0.metadata.name == "developers"
+
+ - name: Synchronize Groups using deny_groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.simple }}"
+ deny_groups: "{{ deny_groups }}"
+ register: result
+ check_mode: yes
+
+ - name: Validate Group going to be created
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+ - result.groups.0.metadata.name == "developers"
+
+ - name: Synchronize groups, remove check_mode
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ configs.simple }}"
+ register: result
+
+ - name: Validate result is changed
+ assert:
+ that:
+ - result is changed
+
+ - name: Read Groups
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: Validate group was created
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"jane.smith@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Read Groups
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: developers
+ register: result
+
+ - name: Validate group was created
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"jim.adams@ansible.org" in {{ result.resources.0.users }}'
+ - '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Set users to delete (no admins users anymore and only 1 developer kept)
+ set_fact:
+ users_to_delete:
+ - "cn=Jane,ou=people,ou=rfc2307,{{ ldap_root }}"
+ - "cn=Jim,ou=people,ou=rfc2307,{{ ldap_root }}"
+
+ - name: Delete users from LDAP servers
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item }}"
+ state: absent
+ with_items: "{{ users_to_delete }}"
+
+ - name: Define sync configuration with tolerateMemberNotFoundErrors
+ set_fact:
+ config_simple_tolerate_not_found: "{{ configs.simple | combine({'rfc2307': merge_rfc2307 })}}"
+ vars:
+ merge_rfc2307: "{{ configs.simple.rfc2307 | combine({'tolerateMemberNotFoundErrors': 'true'}) }}"
+
+ - name: Synchronize groups once again after users deletion
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_simple_tolerate_not_found }}"
+ register: result
+
+ - name: Validate result is changed
+ assert:
+ that:
+ - result is changed
+
+ - name: Read Groups
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: Validate admins group does not contains users anymore
+ assert:
+ that:
+ - result.resources | length == 1
+ - result.resources.0.users == []
+
+ - name: Read Groups
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: developers
+ register: result
+
+ - name: Validate group was created
+ assert:
+ that:
+ - result.resources | length == 1
+ - '"jordanbulls@ansible.org" in {{ result.resources.0.users }}'
+
+ - name: Set group to delete
+ set_fact:
+ groups_to_delete:
+ - "cn=developers,ou=groups,ou=rfc2307,{{ ldap_root }}"
+
+ - name: Delete Group from LDAP servers
+ openshift_ldap_entry:
+ bind_dn: "{{ ldap_bind_dn }}"
+ bind_pw: "{{ ldap_bind_pw }}"
+ server_uri: "{{ ldap_server_uri }}"
+ dn: "{{ item }}"
+ state: absent
+ with_items: "{{ groups_to_delete }}"
+
+ - name: Prune groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_simple_tolerate_not_found }}"
+ state: absent
+ register: result
+ check_mode: yes
+
+ - name: Validate that only developers group is candidate for Prune
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+ - result.groups.0.metadata.name == "developers"
+
+ - name: Read Group (validate that check_mode did not performed update in the cluster)
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: developers
+ register: result
+
+ - name: Assert group was found
+ assert:
+ that:
+ - result.resources | length == 1
+
+ - name: Prune using allow_groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_simple_tolerate_not_found }}"
+ allow_groups:
+ - developers
+ state: absent
+ register: result
+ check_mode: yes
+
+ - name: assert developers group was candidate for prune
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+ - result.groups.0.metadata.name == "developers"
+
+ - name: Prune using deny_groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_simple_tolerate_not_found }}"
+ deny_groups:
+ - developers
+ state: absent
+ register: result
+ check_mode: yes
+
+ - name: assert nothing found candidate for prune
+ assert:
+ that:
+ - result is not changed
+ - result.groups | length == 0
+
+ - name: Prune groups
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_simple_tolerate_not_found }}"
+ state: absent
+ register: result
+
+ - name: Validate result is changed
+ assert:
+ that:
+ - result is changed
+ - result.groups | length == 1
+
+ - name: Get developers group info
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: developers
+ register: result
+
+ - name: assert group was deleted
+ assert:
+ that:
+ - result.resources | length == 0
+
+ - name: Get admins group info
+ kubernetes.core.k8s_info:
+ kind: Group
+ version: "user.openshift.io/v1"
+ name: admins
+ register: result
+
+ - name: assert group was not deleted
+ assert:
+ that:
+ - result.resources | length == 1
+
+ - name: Prune groups once again (idempotency)
+ community.okd.openshift_adm_groups_sync:
+ config: "{{ config_simple_tolerate_not_found }}"
+ state: absent
+ register: result
+
+ - name: Assert nothing changed
+ assert:
+ that:
+ - result is not changed
+ - result.groups | length == 0
always:
- name: Delete openshift groups if existing
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml
index 4de4894e2..edf0e17c4 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_clusterroles.yml
@@ -1,293 +1,294 @@
+---
- block:
- - set_fact:
- test_sa: "clusterrole-sa"
- test_ns: "clusterrole-ns"
-
- - name: Ensure namespace
- kubernetes.core.k8s:
- kind: Namespace
- name: "{{ test_ns }}"
-
- - name: Get cluster information
- kubernetes.core.k8s_cluster_info:
- register: cluster_info
- no_log: true
-
- - set_fact:
- cluster_host: "{{ cluster_info['connection']['host'] }}"
-
- - name: Create Service account
- kubernetes.core.k8s:
- definition:
- apiVersion: v1
+ - set_fact:
+ test_sa: "clusterrole-sa"
+ test_ns: "clusterrole-ns"
+
+ - name: Ensure namespace
+ kubernetes.core.k8s:
+ kind: Namespace
+ name: "{{ test_ns }}"
+
+ - name: Get cluster information
+ kubernetes.core.k8s_cluster_info:
+ register: cluster_info
+ no_log: true
+
+ - set_fact:
+ cluster_host: "{{ cluster_info['connection']['host'] }}"
+
+ - name: Create Service account
+ kubernetes.core.k8s:
+ definition:
+ apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: "{{ test_sa }}"
+ namespace: "{{ test_ns }}"
+
+ - name: Read Service Account
+ kubernetes.core.k8s_info:
kind: ServiceAccount
- metadata:
- name: "{{ test_sa }}"
- namespace: "{{ test_ns }}"
-
- - name: Read Service Account
- kubernetes.core.k8s_info:
- kind: ServiceAccount
- namespace: "{{ test_ns }}"
- name: "{{ test_sa }}"
- register: result
-
- - set_fact:
- secret_token: "{{ result.resources[0]['secrets'][0]['name'] }}"
-
- - name: Get secret details
- kubernetes.core.k8s_info:
- kind: Secret
- namespace: '{{ test_ns }}'
- name: '{{ secret_token }}'
- register: _secret
- retries: 10
- delay: 10
- until:
- - ("'openshift.io/token-secret.value' in _secret.resources[0]['metadata']['annotations']") or ("'token' in _secret.resources[0]['data']")
-
- - set_fact:
- api_token: "{{ _secret.resources[0]['metadata']['annotations']['openshift.io/token-secret.value'] }}"
- when: "'openshift.io/token-secret.value' in _secret.resources[0]['metadata']['annotations']"
-
- - set_fact:
- api_token: "{{ _secret.resources[0]['data']['token'] | b64decode }}"
- when: "'token' in _secret.resources[0]['data']"
-
- - name: list Node should failed (forbidden user)
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Node
- register: error
- ignore_errors: true
-
- - assert:
- that:
- - '"nodes is forbidden: User" in error.msg'
-
- - name: list Pod for all namespace should failed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- register: error
- ignore_errors: true
-
- - assert:
- that:
- - '"pods is forbidden: User" in error.msg'
-
- - name: list Pod for test namespace should failed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- namespace: "{{ test_ns }}"
- register: error
- ignore_errors: true
-
- - assert:
- that:
- - '"pods is forbidden: User" in error.msg'
-
- - set_fact:
- test_labels:
- phase: dev
- cluster_roles:
- - name: pod-manager
- resources:
- - pods
- verbs:
- - list
- api_version_binding: "authorization.openshift.io/v1"
- - name: node-manager
- resources:
- - nodes
- verbs:
- - list
- api_version_binding: "rbac.authorization.k8s.io/v1"
-
- - name: Create cluster roles
- kubernetes.core.k8s:
- definition:
- kind: ClusterRole
- apiVersion: "rbac.authorization.k8s.io/v1"
- metadata:
- name: "{{ item.name }}"
- labels: "{{ test_labels }}"
- rules:
- - apiGroups: [""]
- resources: "{{ item.resources }}"
- verbs: "{{ item.verbs }}"
- with_items: '{{ cluster_roles }}'
-
- - name: Create Role Binding (namespaced)
- kubernetes.core.k8s:
- definition:
- kind: RoleBinding
- apiVersion: "rbac.authorization.k8s.io/v1"
- metadata:
- name: "{{ cluster_roles[0].name }}-binding"
- namespace: "{{ test_ns }}"
- labels: "{{ test_labels }}"
- subjects:
- - kind: ServiceAccount
- name: "{{ test_sa }}"
- namespace: "{{ test_ns }}"
- apiGroup: ""
- roleRef:
- kind: ClusterRole
- name: "{{ cluster_roles[0].name }}"
- apiGroup: ""
-
- - name: list Pod for all namespace should failed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- register: error
- ignore_errors: true
-
- - assert:
- that:
- - '"pods is forbidden: User" in error.msg'
-
- - name: list Pod for test namespace should succeed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- namespace: "{{ test_ns }}"
- no_log: true
-
- - name: Create Cluster role Binding
- kubernetes.core.k8s:
- definition:
- kind: ClusterRoleBinding
- apiVersion: "{{ item.api_version_binding }}"
- metadata:
- name: "{{ item.name }}-binding"
- labels: "{{ test_labels }}"
- subjects:
- - kind: ServiceAccount
- name: "{{ test_sa }}"
- namespace: "{{ test_ns }}"
- apiGroup: ""
- roleRef:
+ namespace: "{{ test_ns }}"
+ name: "{{ test_sa }}"
+ register: result
+
+ - set_fact:
+ secret_token: "{{ result.resources[0]['secrets'][0]['name'] }}"
+
+ - name: Get secret details
+ kubernetes.core.k8s_info:
+ kind: Secret
+ namespace: '{{ test_ns }}'
+ name: '{{ secret_token }}'
+ register: _secret
+ retries: 10
+ delay: 10
+ until:
+ - ("'openshift.io/token-secret.value' in _secret.resources[0]['metadata']['annotations']") or ("'token' in _secret.resources[0]['data']")
+
+ - set_fact:
+ api_token: "{{ _secret.resources[0]['metadata']['annotations']['openshift.io/token-secret.value'] }}"
+ when: "'openshift.io/token-secret.value' in _secret.resources[0]['metadata']['annotations']"
+
+ - set_fact:
+ api_token: "{{ _secret.resources[0]['data']['token'] | b64decode }}"
+ when: "'token' in _secret.resources[0]['data']"
+
+ - name: list Node should failed (forbidden user)
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Node
+ register: error
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"nodes is forbidden: User" in error.msg'
+
+ - name: list Pod for all namespace should failed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ register: error
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"pods is forbidden: User" in error.msg'
+
+ - name: list Pod for test namespace should failed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ namespace: "{{ test_ns }}"
+ register: error
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"pods is forbidden: User" in error.msg'
+
+ - set_fact:
+ test_labels:
+ phase: dev
+ cluster_roles:
+ - name: pod-manager
+ resources:
+ - pods
+ verbs:
+ - list
+ api_version_binding: "authorization.openshift.io/v1"
+ - name: node-manager
+ resources:
+ - nodes
+ verbs:
+ - list
+ api_version_binding: "rbac.authorization.k8s.io/v1"
+
+ - name: Create cluster roles
+ kubernetes.core.k8s:
+ definition:
kind: ClusterRole
- name: "{{ item.name }}"
- apiGroup: ""
- with_items: "{{ cluster_roles }}"
-
- - name: list Pod for all namespace should succeed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- no_log: true
-
- - name: list Pod for test namespace should succeed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- namespace: "{{ test_ns }}"
- no_log: true
-
- - name: list Node using ServiceAccount
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Node
- namespace: "{{ test_ns }}"
- no_log: true
-
- - name: Prune clusterroles (check mode)
- community.okd.openshift_adm_prune_auth:
- resource: clusterroles
- label_selectors:
- - phase=dev
- register: check
- check_mode: true
-
- - name: validate clusterrole binding candidates for prune
- assert:
- that:
- - '"{{ item.name }}-binding" in check.cluster_role_binding'
- - '"{{ test_ns }}/{{ cluster_roles[0].name }}-binding" in check.role_binding'
- with_items: "{{ cluster_roles }}"
-
- - name: Prune Cluster Role for managing Pod
- community.okd.openshift_adm_prune_auth:
- resource: clusterroles
- name: "{{ cluster_roles[0].name }}"
-
- - name: list Pod for all namespace should failed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- register: error
- no_log: true
- ignore_errors: true
-
- - assert:
- that:
- - '"pods is forbidden: User" in error.msg'
-
- - name: list Pod for test namespace should failed
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Pod
- namespace: "{{ test_ns }}"
- register: error
- no_log: true
- ignore_errors: true
-
- - assert:
- that:
- - '"pods is forbidden: User" in error.msg'
-
- - name: list Node using ServiceAccount
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Node
- namespace: "{{ test_ns }}"
- no_log: true
-
- - name: Prune clusterroles (remaining)
- community.okd.openshift_adm_prune_auth:
- resource: clusterroles
- label_selectors:
- - phase=dev
-
- - name: list Node using ServiceAccount should fail
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- kind: Node
- namespace: "{{ test_ns }}"
- register: error
- ignore_errors: true
-
- - assert:
- that:
- - '"nodes is forbidden: User" in error.msg'
+ apiVersion: "rbac.authorization.k8s.io/v1"
+ metadata:
+ name: "{{ item.name }}"
+ labels: "{{ test_labels }}"
+ rules:
+ - apiGroups: [""]
+ resources: "{{ item.resources }}"
+ verbs: "{{ item.verbs }}"
+ with_items: '{{ cluster_roles }}'
+
+ - name: Create Role Binding (namespaced)
+ kubernetes.core.k8s:
+ definition:
+ kind: RoleBinding
+ apiVersion: "rbac.authorization.k8s.io/v1"
+ metadata:
+ name: "{{ cluster_roles[0].name }}-binding"
+ namespace: "{{ test_ns }}"
+ labels: "{{ test_labels }}"
+ subjects:
+ - kind: ServiceAccount
+ name: "{{ test_sa }}"
+ namespace: "{{ test_ns }}"
+ apiGroup: ""
+ roleRef:
+ kind: ClusterRole
+ name: "{{ cluster_roles[0].name }}"
+ apiGroup: ""
+
+ - name: list Pod for all namespace should failed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ register: error
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"pods is forbidden: User" in error.msg'
+
+ - name: list Pod for test namespace should succeed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ namespace: "{{ test_ns }}"
+ no_log: true
+
+ - name: Create Cluster role Binding
+ kubernetes.core.k8s:
+ definition:
+ kind: ClusterRoleBinding
+ apiVersion: "{{ item.api_version_binding }}"
+ metadata:
+ name: "{{ item.name }}-binding"
+ labels: "{{ test_labels }}"
+ subjects:
+ - kind: ServiceAccount
+ name: "{{ test_sa }}"
+ namespace: "{{ test_ns }}"
+ apiGroup: ""
+ roleRef:
+ kind: ClusterRole
+ name: "{{ item.name }}"
+ apiGroup: ""
+ with_items: "{{ cluster_roles }}"
+
+ - name: list Pod for all namespace should succeed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ no_log: true
+
+ - name: list Pod for test namespace should succeed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ namespace: "{{ test_ns }}"
+ no_log: true
+
+ - name: list Node using ServiceAccount
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Node
+ namespace: "{{ test_ns }}"
+ no_log: true
+
+ - name: Prune clusterroles (check mode)
+ community.okd.openshift_adm_prune_auth:
+ resource: clusterroles
+ label_selectors:
+ - phase=dev
+ register: check
+ check_mode: true
+
+ - name: validate clusterrole binding candidates for prune
+ assert:
+ that:
+ - '"{{ item.name }}-binding" in check.cluster_role_binding'
+ - '"{{ test_ns }}/{{ cluster_roles[0].name }}-binding" in check.role_binding'
+ with_items: "{{ cluster_roles }}"
+
+ - name: Prune Cluster Role for managing Pod
+ community.okd.openshift_adm_prune_auth:
+ resource: clusterroles
+ name: "{{ cluster_roles[0].name }}"
+
+ - name: list Pod for all namespace should failed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ register: error
+ no_log: true
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"pods is forbidden: User" in error.msg'
+
+ - name: list Pod for test namespace should failed
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Pod
+ namespace: "{{ test_ns }}"
+ register: error
+ no_log: true
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"pods is forbidden: User" in error.msg'
+
+ - name: list Node using ServiceAccount
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Node
+ namespace: "{{ test_ns }}"
+ no_log: true
+
+ - name: Prune clusterroles (remaining)
+ community.okd.openshift_adm_prune_auth:
+ resource: clusterroles
+ label_selectors:
+ - phase=dev
+
+ - name: list Node using ServiceAccount should fail
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ kind: Node
+ namespace: "{{ test_ns }}"
+ register: error
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"nodes is forbidden: User" in error.msg'
always:
- name: Ensure namespace is deleted
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_roles.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_roles.yml
index 1724a1938..7b75a0cfe 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_roles.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_auth_roles.yml
@@ -1,335 +1,336 @@
+---
- block:
- - set_fact:
- test_ns: "prune-roles"
- sa_name: "roles-sa"
- pod_name: "pod-prune"
- role_definition:
- - name: pod-list
- labels:
- action: list
- verbs:
- - list
- role_binding:
- api_version: rbac.authorization.k8s.io/v1
- - name: pod-create
- labels:
- action: create
- verbs:
- - create
- - get
- role_binding:
- api_version: authorization.openshift.io/v1
- - name: pod-delete
- labels:
- action: delete
- verbs:
- - delete
- role_binding:
- api_version: rbac.authorization.k8s.io/v1
-
- - name: Ensure namespace
- kubernetes.core.k8s:
- kind: Namespace
- name: '{{ test_ns }}'
-
- - name: Get cluster information
- kubernetes.core.k8s_cluster_info:
- register: cluster_info
- no_log: true
-
- - set_fact:
- cluster_host: "{{ cluster_info['connection']['host'] }}"
-
- - name: Create Service account
- kubernetes.core.k8s:
- definition:
- apiVersion: v1
+ - set_fact:
+ test_ns: "prune-roles"
+ sa_name: "roles-sa"
+ pod_name: "pod-prune"
+ role_definition:
+ - name: pod-list
+ labels:
+ action: list
+ verbs:
+ - list
+ role_binding:
+ api_version: rbac.authorization.k8s.io/v1
+ - name: pod-create
+ labels:
+ action: create
+ verbs:
+ - create
+ - get
+ role_binding:
+ api_version: authorization.openshift.io/v1
+ - name: pod-delete
+ labels:
+ action: delete
+ verbs:
+ - delete
+ role_binding:
+ api_version: rbac.authorization.k8s.io/v1
+
+ - name: Ensure namespace
+ kubernetes.core.k8s:
+ kind: Namespace
+ name: '{{ test_ns }}'
+
+ - name: Get cluster information
+ kubernetes.core.k8s_cluster_info:
+ register: cluster_info
+ no_log: true
+
+ - set_fact:
+ cluster_host: "{{ cluster_info['connection']['host'] }}"
+
+ - name: Create Service account
+ kubernetes.core.k8s:
+ definition:
+ apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: '{{ sa_name }}'
+ namespace: '{{ test_ns }}'
+
+ - name: Read Service Account
+ kubernetes.core.k8s_info:
kind: ServiceAccount
- metadata:
- name: '{{ sa_name }}'
- namespace: '{{ test_ns }}'
-
- - name: Read Service Account
- kubernetes.core.k8s_info:
- kind: ServiceAccount
- namespace: '{{ test_ns }}'
- name: '{{ sa_name }}'
- register: sa_out
-
- - set_fact:
- secret_token: "{{ sa_out.resources[0]['secrets'][0]['name'] }}"
-
- - name: Get secret details
- kubernetes.core.k8s_info:
- kind: Secret
- namespace: '{{ test_ns }}'
- name: '{{ secret_token }}'
- register: r_secret
- retries: 10
- delay: 10
- until:
- - ("'openshift.io/token-secret.value' in r_secret.resources[0]['metadata']['annotations']") or ("'token' in r_secret.resources[0]['data']")
-
- - set_fact:
- api_token: "{{ r_secret.resources[0]['metadata']['annotations']['openshift.io/token-secret.value'] }}"
- when: "'openshift.io/token-secret.value' in r_secret.resources[0]['metadata']['annotations']"
-
- - set_fact:
- api_token: "{{ r_secret.resources[0]['data']['token'] | b64decode }}"
- when: "'token' in r_secret.resources[0]['data']"
-
- - name: list resources using service account
- kubernetes.core.k8s_info:
- api_key: '{{ api_token }}'
- host: '{{ cluster_host }}'
- validate_certs: no
- kind: Pod
- namespace: '{{ test_ns }}'
- register: error
- ignore_errors: true
-
- - assert:
- that:
- - '"pods is forbidden: User" in error.msg'
-
- - name: Create a role to manage Pod from namespace "{{ test_ns }}"
- kubernetes.core.k8s:
- definition:
- kind: Role
- apiVersion: rbac.authorization.k8s.io/v1
- metadata:
- namespace: "{{ test_ns }}"
- name: "{{ item.name }}"
- labels: "{{ item.labels }}"
- rules:
- - apiGroups: [""]
- resources: ["pods"]
- verbs: "{{ item.verbs }}"
- with_items: "{{ role_definition }}"
-
- - name: Create Role Binding
- kubernetes.core.k8s:
- definition:
- kind: RoleBinding
- apiVersion: "{{ item.role_binding.api_version }}"
- metadata:
- name: "{{ item.name }}-bind"
- namespace: "{{ test_ns }}"
- subjects:
- - kind: ServiceAccount
- name: "{{ sa_name }}"
- namespace: "{{ test_ns }}"
- apiGroup: ""
- roleRef:
+ namespace: '{{ test_ns }}'
+ name: '{{ sa_name }}'
+ register: sa_out
+
+ - set_fact:
+ secret_token: "{{ sa_out.resources[0]['secrets'][0]['name'] }}"
+
+ - name: Get secret details
+ kubernetes.core.k8s_info:
+ kind: Secret
+ namespace: '{{ test_ns }}'
+ name: '{{ secret_token }}'
+ register: r_secret
+ retries: 10
+ delay: 10
+ until:
+ - ("'openshift.io/token-secret.value' in r_secret.resources[0]['metadata']['annotations']") or ("'token' in r_secret.resources[0]['data']")
+
+ - set_fact:
+ api_token: "{{ r_secret.resources[0]['metadata']['annotations']['openshift.io/token-secret.value'] }}"
+ when: "'openshift.io/token-secret.value' in r_secret.resources[0]['metadata']['annotations']"
+
+ - set_fact:
+ api_token: "{{ r_secret.resources[0]['data']['token'] | b64decode }}"
+ when: "'token' in r_secret.resources[0]['data']"
+
+ - name: list resources using service account
+ kubernetes.core.k8s_info:
+ api_key: '{{ api_token }}'
+ host: '{{ cluster_host }}'
+ validate_certs: no
+ kind: Pod
+ namespace: '{{ test_ns }}'
+ register: error
+ ignore_errors: true
+
+ - assert:
+ that:
+ - '"pods is forbidden: User" in error.msg'
+
+ - name: Create a role to manage Pod from namespace "{{ test_ns }}"
+ kubernetes.core.k8s:
+ definition:
kind: Role
- name: "{{ item.name }}"
- namespace: "{{ test_ns }}"
- apiGroup: ""
- with_items: "{{ role_definition }}"
-
- - name: Create Pod should succeed
- kubernetes.core.k8s:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- definition:
+ apiVersion: rbac.authorization.k8s.io/v1
+ metadata:
+ namespace: "{{ test_ns }}"
+ name: "{{ item.name }}"
+ labels: "{{ item.labels }}"
+ rules:
+ - apiGroups: [""]
+ resources: ["pods"]
+ verbs: "{{ item.verbs }}"
+ with_items: "{{ role_definition }}"
+
+ - name: Create Role Binding
+ kubernetes.core.k8s:
+ definition:
+ kind: RoleBinding
+ apiVersion: "{{ item.role_binding.api_version }}"
+ metadata:
+ name: "{{ item.name }}-bind"
+ namespace: "{{ test_ns }}"
+ subjects:
+ - kind: ServiceAccount
+ name: "{{ sa_name }}"
+ namespace: "{{ test_ns }}"
+ apiGroup: ""
+ roleRef:
+ kind: Role
+ name: "{{ item.name }}"
+ namespace: "{{ test_ns }}"
+ apiGroup: ""
+ with_items: "{{ role_definition }}"
+
+ - name: Create Pod should succeed
+ kubernetes.core.k8s:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
+ definition:
+ kind: Pod
+ metadata:
+ name: "{{ pod_name }}"
+ spec:
+ containers:
+ - name: python
+ image: python:3.7-alpine
+ command:
+ - /bin/sh
+ - -c
+ - while true; do echo $(date); sleep 15; done
+ imagePullPolicy: IfNotPresent
+ register: result
+
+ - name: assert pod creation succeed
+ assert:
+ that:
+ - result is successful
+
+ - name: List Pod
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
kind: Pod
- metadata:
- name: "{{ pod_name }}"
- spec:
- containers:
- - name: python
- image: python:3.7-alpine
- command:
- - /bin/sh
- - -c
- - while true; do echo $(date); sleep 15; done
- imagePullPolicy: IfNotPresent
- register: result
-
- - name: assert pod creation succeed
- assert:
- that:
- - result is successful
-
- - name: List Pod
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- kind: Pod
- register: result
-
- - name: assert user is still authorize to list pods
- assert:
- that:
- - result is successful
-
- - name: Prune auth roles (check mode)
- community.okd.openshift_adm_prune_auth:
- resource: roles
- namespace: "{{ test_ns }}"
- register: check
- check_mode: true
-
- - name: validate that list role binding are candidates for prune
- assert:
- that: '"{{ test_ns }}/{{ item.name }}-bind" in check.role_binding'
- with_items: "{{ role_definition }}"
-
- - name: Prune resource using label_selectors option
- community.okd.openshift_adm_prune_auth:
- resource: roles
- namespace: "{{ test_ns }}"
- label_selectors:
- - action=delete
- register: prune
-
- - name: assert that role binding 'delete' was pruned
- assert:
- that:
- - prune is changed
- - '"{{ test_ns }}/{{ role_definition[2].name }}-bind" in check.role_binding'
-
- - name: assert that user could not delete pod anymore
- kubernetes.core.k8s:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- state: absent
- namespace: "{{ test_ns }}"
- kind: Pod
- name: "{{ pod_name }}"
- register: result
- ignore_errors: true
-
- - name: assert pod deletion failed due to forbidden user
- assert:
- that:
- - '"forbidden: User" in error.msg'
-
- - name: List Pod
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- kind: Pod
- register: result
-
- - name: assert user is still able to list pods
- assert:
- that:
- - result is successful
-
- - name: Create Pod should succeed
- kubernetes.core.k8s:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- definition:
+ register: result
+
+ - name: assert user is still authorize to list pods
+ assert:
+ that:
+ - result is successful
+
+ - name: Prune auth roles (check mode)
+ community.okd.openshift_adm_prune_auth:
+ resource: roles
+ namespace: "{{ test_ns }}"
+ register: check
+ check_mode: true
+
+ - name: validate that list role binding are candidates for prune
+ assert:
+ that: '"{{ test_ns }}/{{ item.name }}-bind" in check.role_binding'
+ with_items: "{{ role_definition }}"
+
+ - name: Prune resource using label_selectors option
+ community.okd.openshift_adm_prune_auth:
+ resource: roles
+ namespace: "{{ test_ns }}"
+ label_selectors:
+ - action=delete
+ register: prune
+
+ - name: assert that role binding 'delete' was pruned
+ assert:
+ that:
+ - prune is changed
+ - '"{{ test_ns }}/{{ role_definition[2].name }}-bind" in check.role_binding'
+
+ - name: assert that user could not delete pod anymore
+ kubernetes.core.k8s:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ state: absent
+ namespace: "{{ test_ns }}"
kind: Pod
- metadata:
- name: "{{ pod_name }}-1"
- spec:
- containers:
- - name: python
- image: python:3.7-alpine
- command:
- - /bin/sh
- - -c
- - while true; do echo $(date); sleep 15; done
- imagePullPolicy: IfNotPresent
- register: result
-
- - name: assert user is still authorize to create pod
- assert:
- that:
- - result is successful
-
- - name: Prune role using name
- community.okd.openshift_adm_prune_auth:
- resource: roles
- namespace: "{{ test_ns }}"
- name: "{{ role_definition[1].name }}"
- register: prune
-
- - name: assert that role binding 'create' was pruned
- assert:
- that:
- - prune is changed
- - '"{{ test_ns }}/{{ role_definition[1].name }}-bind" in check.role_binding'
-
- - name: Create Pod (should failed)
- kubernetes.core.k8s:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- definition:
+ name: "{{ pod_name }}"
+ register: result
+ ignore_errors: true
+
+ - name: assert pod deletion failed due to forbidden user
+ assert:
+ that:
+ - '"forbidden: User" in error.msg'
+
+ - name: List Pod
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
kind: Pod
- metadata:
- name: "{{ pod_name }}-2"
- spec:
- containers:
- - name: python
- image: python:3.7-alpine
- command:
- - /bin/sh
- - -c
- - while true; do echo $(date); sleep 15; done
- imagePullPolicy: IfNotPresent
- register: result
- ignore_errors: true
-
- - name: assert user is not authorize to create pod anymore
- assert:
- that:
- - '"forbidden: User" in error.msg'
-
- - name: List Pod
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- kind: Pod
- register: result
-
- - name: assert user is still able to list pods
- assert:
- that:
- - result is successful
-
- - name: Prune all role for namespace (neither name nor label_selectors are specified)
- community.okd.openshift_adm_prune_auth:
- resource: roles
- namespace: "{{ test_ns }}"
- register: prune
-
- - name: assert that role binding 'list' was pruned
- assert:
- that:
- - prune is changed
- - '"{{ test_ns }}/{{ role_definition[0].name }}-bind" in check.role_binding'
-
- - name: List Pod
- kubernetes.core.k8s_info:
- api_key: "{{ api_token }}"
- host: "{{ cluster_host }}"
- validate_certs: no
- namespace: "{{ test_ns }}"
- kind: Pod
- register: result
- ignore_errors: true
-
- - name: assert user is not authorize to list pod anymore
- assert:
- that:
- - '"forbidden: User" in error.msg'
+ register: result
+
+ - name: assert user is still able to list pods
+ assert:
+ that:
+ - result is successful
+
+ - name: Create Pod should succeed
+ kubernetes.core.k8s:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
+ definition:
+ kind: Pod
+ metadata:
+ name: "{{ pod_name }}-1"
+ spec:
+ containers:
+ - name: python
+ image: python:3.7-alpine
+ command:
+ - /bin/sh
+ - -c
+ - while true; do echo $(date); sleep 15; done
+ imagePullPolicy: IfNotPresent
+ register: result
+
+ - name: assert user is still authorize to create pod
+ assert:
+ that:
+ - result is successful
+
+ - name: Prune role using name
+ community.okd.openshift_adm_prune_auth:
+ resource: roles
+ namespace: "{{ test_ns }}"
+ name: "{{ role_definition[1].name }}"
+ register: prune
+
+ - name: assert that role binding 'create' was pruned
+ assert:
+ that:
+ - prune is changed
+ - '"{{ test_ns }}/{{ role_definition[1].name }}-bind" in check.role_binding'
+
+ - name: Create Pod (should failed)
+ kubernetes.core.k8s:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
+ definition:
+ kind: Pod
+ metadata:
+ name: "{{ pod_name }}-2"
+ spec:
+ containers:
+ - name: python
+ image: python:3.7-alpine
+ command:
+ - /bin/sh
+ - -c
+ - while true; do echo $(date); sleep 15; done
+ imagePullPolicy: IfNotPresent
+ register: result
+ ignore_errors: true
+
+ - name: assert user is not authorize to create pod anymore
+ assert:
+ that:
+ - '"forbidden: User" in error.msg'
+
+ - name: List Pod
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
+ kind: Pod
+ register: result
+
+ - name: assert user is still able to list pods
+ assert:
+ that:
+ - result is successful
+
+ - name: Prune all role for namespace (neither name nor label_selectors are specified)
+ community.okd.openshift_adm_prune_auth:
+ resource: roles
+ namespace: "{{ test_ns }}"
+ register: prune
+
+ - name: assert that role binding 'list' was pruned
+ assert:
+ that:
+ - prune is changed
+ - '"{{ test_ns }}/{{ role_definition[0].name }}-bind" in check.role_binding'
+
+ - name: List Pod
+ kubernetes.core.k8s_info:
+ api_key: "{{ api_token }}"
+ host: "{{ cluster_host }}"
+ validate_certs: no
+ namespace: "{{ test_ns }}"
+ kind: Pod
+ register: result
+ ignore_errors: true
+
+ - name: assert user is not authorize to list pod anymore
+ assert:
+ that:
+ - '"forbidden: User" in error.msg'
always:
- name: Ensure namespace is deleted
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_deployments.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_deployments.yml
index baa024188..ca48f7327 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_deployments.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_adm_prune_deployments.yml
@@ -1,255 +1,255 @@
+---
- name: Prune deployments
block:
- - set_fact:
- dc_name: "hello"
- deployment_ns: "prune-deployments"
- deployment_ns_2: "prune-deployments-2"
-
+ - set_fact:
+ dc_name: "hello"
+ deployment_ns: "prune-deployments"
+ deployment_ns_2: "prune-deployments-2"
- - name: Ensure namespace
- community.okd.k8s:
- kind: Namespace
- name: '{{ deployment_ns }}'
+ - name: Ensure namespace
+ community.okd.k8s:
+ kind: Namespace
+ name: '{{ deployment_ns }}'
- - name: Create deployment config
- community.okd.k8s:
- namespace: '{{ deployment_ns }}'
- definition:
- kind: DeploymentConfig
- apiVersion: apps.openshift.io/v1
- metadata:
- name: '{{ dc_name }}'
- spec:
- replicas: 1
- selector:
+ - name: Create deployment config
+ community.okd.k8s:
+ namespace: '{{ deployment_ns }}'
+ definition:
+ kind: DeploymentConfig
+ apiVersion: apps.openshift.io/v1
+ metadata:
name: '{{ dc_name }}'
- template:
- metadata:
- labels:
- name: '{{ dc_name }}'
- spec:
- containers:
- - name: hello-openshift
- imagePullPolicy: IfNotPresent
- image: python:3.7-alpine
- command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
- wait: yes
+ spec:
+ replicas: 1
+ selector:
+ name: '{{ dc_name }}'
+ template:
+ metadata:
+ labels:
+ name: '{{ dc_name }}'
+ spec:
+ containers:
+ - name: hello-openshift
+ imagePullPolicy: IfNotPresent
+ image: python:3.7-alpine
+ command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
+ wait: yes
- - name: prune deployments (no candidate DeploymentConfig)
- community.okd.openshift_adm_prune_deployments:
- namespace: "{{ deployment_ns }}"
- register: test_prune
+ - name: prune deployments (no candidate DeploymentConfig)
+ community.okd.openshift_adm_prune_deployments:
+ namespace: "{{ deployment_ns }}"
+ register: test_prune
- - assert:
- that:
- - test_prune is not changed
- - test_prune.replication_controllers | length == 0
+ - assert:
+ that:
+ - test_prune is not changed
+ - test_prune.replication_controllers | length == 0
- - name: Update DeploymentConfig - set replicas to 0
- community.okd.k8s:
- namespace: "{{ deployment_ns }}"
- definition:
- kind: DeploymentConfig
- apiVersion: "apps.openshift.io/v1"
- metadata:
- name: "{{ dc_name }}"
- spec:
- replicas: 0
- selector:
+ - name: Update DeploymentConfig - set replicas to 0
+ community.okd.k8s:
+ namespace: "{{ deployment_ns }}"
+ definition:
+ kind: DeploymentConfig
+ apiVersion: "apps.openshift.io/v1"
+ metadata:
name: "{{ dc_name }}"
- template:
- metadata:
- labels:
- name: "{{ dc_name }}"
- spec:
- containers:
- - name: hello-openshift
- imagePullPolicy: IfNotPresent
- image: python:3.7-alpine
- command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
- wait: yes
+ spec:
+ replicas: 0
+ selector:
+ name: "{{ dc_name }}"
+ template:
+ metadata:
+ labels:
+ name: "{{ dc_name }}"
+ spec:
+ containers:
+ - name: hello-openshift
+ imagePullPolicy: IfNotPresent
+ image: python:3.7-alpine
+ command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
+ wait: yes
- - name: Wait for ReplicationController candidate for pruning
- kubernetes.core.k8s_info:
- kind: ReplicationController
- namespace: "{{ deployment_ns }}"
- register: result
- retries: 10
- delay: 30
- until:
- - result.resources.0.metadata.annotations["openshift.io/deployment.phase"] in ("Failed", "Complete")
+ - name: Wait for ReplicationController candidate for pruning
+ kubernetes.core.k8s_info:
+ kind: ReplicationController
+ namespace: "{{ deployment_ns }}"
+ register: result
+ retries: 10
+ delay: 30
+ until:
+ - result.resources.0.metadata.annotations["openshift.io/deployment.phase"] in ("Failed", "Complete")
- - name: Prune deployments - should delete 1 ReplicationController
- community.okd.openshift_adm_prune_deployments:
- namespace: "{{ deployment_ns }}"
- check_mode: yes
- register: test_prune
+ - name: Prune deployments - should delete 1 ReplicationController
+ community.okd.openshift_adm_prune_deployments:
+ namespace: "{{ deployment_ns }}"
+ check_mode: yes
+ register: test_prune
- - name: Read ReplicationController
- kubernetes.core.k8s_info:
- kind: ReplicationController
- namespace: "{{ deployment_ns }}"
- register: replications
+ - name: Read ReplicationController
+ kubernetes.core.k8s_info:
+ kind: ReplicationController
+ namespace: "{{ deployment_ns }}"
+ register: replications
- - name: Assert that Replication controller was not deleted
- assert:
- that:
- - replications.resources | length == 1
- - 'replications.resources.0.metadata.name is match("{{ dc_name }}-*")'
+ - name: Assert that Replication controller was not deleted
+ assert:
+ that:
+ - replications.resources | length == 1
+ - 'replications.resources.0.metadata.name is match("{{ dc_name }}-*")'
- - name: Assure that candidate ReplicationController was found for pruning
- assert:
- that:
- - test_prune is changed
- - test_prune.replication_controllers | length == 1
- - test_prune.replication_controllers.0.metadata.name == replications.resources.0.metadata.name
- - test_prune.replication_controllers.0.metadata.namespace == replications.resources.0.metadata.namespace
+ - name: Assure that candidate ReplicationController was found for pruning
+ assert:
+ that:
+ - test_prune is changed
+ - test_prune.replication_controllers | length == 1
+ - test_prune.replication_controllers.0.metadata.name == replications.resources.0.metadata.name
+ - test_prune.replication_controllers.0.metadata.namespace == replications.resources.0.metadata.namespace
- - name: Prune deployments - keep younger than 45min (check_mode)
- community.okd.openshift_adm_prune_deployments:
- keep_younger_than: 45
- namespace: "{{ deployment_ns }}"
- check_mode: true
- register: keep_younger
+ - name: Prune deployments - keep younger than 45min (check_mode)
+ community.okd.openshift_adm_prune_deployments:
+ keep_younger_than: 45
+ namespace: "{{ deployment_ns }}"
+ check_mode: true
+ register: keep_younger
- - name: assert no candidate was found
- assert:
- that:
- - keep_younger is not changed
- - keep_younger.replication_controllers == []
+ - name: assert no candidate was found
+ assert:
+ that:
+ - keep_younger is not changed
+ - keep_younger.replication_controllers == []
- - name: Ensure second namespace is created
- community.okd.k8s:
- kind: Namespace
- name: '{{ deployment_ns_2 }}'
+ - name: Ensure second namespace is created
+ community.okd.k8s:
+ kind: Namespace
+ name: '{{ deployment_ns_2 }}'
- - name: Create deployment config from 2nd namespace
- community.okd.k8s:
- namespace: '{{ deployment_ns_2 }}'
- definition:
- kind: DeploymentConfig
- apiVersion: apps.openshift.io/v1
- metadata:
- name: '{{ dc_name }}2'
- spec:
- replicas: 1
- selector:
+ - name: Create deployment config from 2nd namespace
+ community.okd.k8s:
+ namespace: '{{ deployment_ns_2 }}'
+ definition:
+ kind: DeploymentConfig
+ apiVersion: apps.openshift.io/v1
+ metadata:
name: '{{ dc_name }}2'
- template:
- metadata:
- labels:
- name: '{{ dc_name }}2'
- spec:
- containers:
- - name: hello-openshift
- imagePullPolicy: IfNotPresent
- image: python:3.7-alpine
- command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
- wait: yes
+ spec:
+ replicas: 1
+ selector:
+ name: '{{ dc_name }}2'
+ template:
+ metadata:
+ labels:
+ name: '{{ dc_name }}2'
+ spec:
+ containers:
+ - name: hello-openshift
+ imagePullPolicy: IfNotPresent
+ image: python:3.7-alpine
+ command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
+ wait: yes
- - name: Stop deployment config - replicas = 0
- community.okd.k8s:
- namespace: '{{ deployment_ns_2 }}'
- definition:
- kind: DeploymentConfig
- apiVersion: apps.openshift.io/v1
- metadata:
- name: '{{ dc_name }}2'
- spec:
- replicas: 0
- selector:
+ - name: Stop deployment config - replicas = 0
+ community.okd.k8s:
+ namespace: '{{ deployment_ns_2 }}'
+ definition:
+ kind: DeploymentConfig
+ apiVersion: apps.openshift.io/v1
+ metadata:
name: '{{ dc_name }}2'
- template:
- metadata:
- labels:
- name: '{{ dc_name }}2'
- spec:
- containers:
- - name: hello-openshift
- imagePullPolicy: IfNotPresent
- image: python:3.7-alpine
- command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
- wait: yes
+ spec:
+ replicas: 0
+ selector:
+ name: '{{ dc_name }}2'
+ template:
+ metadata:
+ labels:
+ name: '{{ dc_name }}2'
+ spec:
+ containers:
+ - name: hello-openshift
+ imagePullPolicy: IfNotPresent
+ image: python:3.7-alpine
+ command: [ "/bin/sh", "-c", "while true;do date;sleep 2s; done"]
+ wait: yes
+
+ - name: Wait for ReplicationController candidate for pruning
+ kubernetes.core.k8s_info:
+ kind: ReplicationController
+ namespace: "{{ deployment_ns_2 }}"
+ register: result
+ retries: 10
+ delay: 30
+ until:
+ - result.resources.0.metadata.annotations["openshift.io/deployment.phase"] in ("Failed", "Complete")
- - name: Wait for ReplicationController candidate for pruning
- kubernetes.core.k8s_info:
- kind: ReplicationController
- namespace: "{{ deployment_ns_2 }}"
- register: result
- retries: 10
- delay: 30
- until:
- - result.resources.0.metadata.annotations["openshift.io/deployment.phase"] in ("Failed", "Complete")
+ # Prune from one namespace should not have any effect on others namespaces
+ - name: Prune deployments from 2nd namespace
+ community.okd.openshift_adm_prune_deployments:
+ namespace: "{{ deployment_ns_2 }}"
+ check_mode: yes
+ register: test_prune
- # Prune from one namespace should not have any effect on others namespaces
- - name: Prune deployments from 2nd namespace
- community.okd.openshift_adm_prune_deployments:
- namespace: "{{ deployment_ns_2 }}"
- check_mode: yes
- register: test_prune
+ - name: Assure that candidate ReplicationController was found for pruning
+ assert:
+ that:
+ - test_prune is changed
+ - test_prune.replication_controllers | length == 1
+ - "test_prune.replication_controllers.0.metadata.namespace == deployment_ns_2"
- - name: Assure that candidate ReplicationController was found for pruning
- assert:
- that:
- - test_prune is changed
- - test_prune.replication_controllers | length == 1
- - "test_prune.replication_controllers.0.metadata.namespace == deployment_ns_2"
+ # Prune without namespace option
+ - name: Prune from all namespace should update more deployments
+ community.okd.openshift_adm_prune_deployments:
+ check_mode: yes
+ register: no_namespace_prune
- # Prune without namespace option
- - name: Prune from all namespace should update more deployments
- community.okd.openshift_adm_prune_deployments:
- check_mode: yes
- register: no_namespace_prune
+ - name: Assure multiple ReplicationController were found for pruning
+ assert:
+ that:
+ - no_namespace_prune is changed
+ - no_namespace_prune.replication_controllers | length == 2
- - name: Assure multiple ReplicationController were found for pruning
- assert:
- that:
- - no_namespace_prune is changed
- - no_namespace_prune.replication_controllers | length == 2
-
- # Execute Prune from 2nd namespace
- - name: Read ReplicationController before Prune operation
- kubernetes.core.k8s_info:
- kind: ReplicationController
- namespace: "{{ deployment_ns_2 }}"
- register: replications
+ # Execute Prune from 2nd namespace
+ - name: Read ReplicationController before Prune operation
+ kubernetes.core.k8s_info:
+ kind: ReplicationController
+ namespace: "{{ deployment_ns_2 }}"
+ register: replications
- - assert:
- that:
- - replications.resources | length == 1
+ - assert:
+ that:
+ - replications.resources | length == 1
- - name: Prune DeploymentConfig from 2nd namespace
- community.okd.openshift_adm_prune_deployments:
- namespace: "{{ deployment_ns_2 }}"
- register: _prune
+ - name: Prune DeploymentConfig from 2nd namespace
+ community.okd.openshift_adm_prune_deployments:
+ namespace: "{{ deployment_ns_2 }}"
+ register: _prune
- - name: Assert DeploymentConfig was deleted
- assert:
- that:
- - _prune is changed
- - _prune.replication_controllers | length == 1
- - _prune.replication_controllers.0.details.name == replications.resources.0.metadata.name
+ - name: Assert DeploymentConfig was deleted
+ assert:
+ that:
+ - _prune is changed
+ - _prune.replication_controllers | length == 1
+ - _prune.replication_controllers.0.details.name == replications.resources.0.metadata.name
- # Execute Prune without namespace option
- - name: Read ReplicationController before Prune operation
- kubernetes.core.k8s_info:
- kind: ReplicationController
- namespace: "{{ deployment_ns }}"
- register: replications
+ # Execute Prune without namespace option
+ - name: Read ReplicationController before Prune operation
+ kubernetes.core.k8s_info:
+ kind: ReplicationController
+ namespace: "{{ deployment_ns }}"
+ register: replications
- - assert:
- that:
- - replications.resources | length == 1
+ - assert:
+ that:
+ - replications.resources | length == 1
- - name: Prune from all namespace should update more deployments
- community.okd.openshift_adm_prune_deployments:
- register: _prune
+ - name: Prune from all namespace should update more deployments
+ community.okd.openshift_adm_prune_deployments:
+ register: _prune
- - name: Assure multiple ReplicationController were found for pruning
- assert:
- that:
- - _prune is changed
- - _prune.replication_controllers | length > 0
+ - name: Assure multiple ReplicationController were found for pruning
+ assert:
+ that:
+ - _prune is changed
+ - _prune.replication_controllers | length > 0
always:
- name: Delete 1st namespace
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_builds.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_builds.yml
index b564f8bcd..2acbac45e 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_builds.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_builds.yml
@@ -1,240 +1,245 @@
+---
- block:
- - set_fact:
- build_ns: "builds"
- build_config: "start-build"
- is_name: "ruby"
- prune_build: "prune-build"
-
- - name: Ensure namespace
- kubernetes.core.k8s:
- kind: Namespace
- name: "{{ build_ns }}"
-
- - name: Create ImageStream
- community.okd.k8s:
- namespace: "{{ build_ns }}"
- definition:
- apiVersion: image.openshift.io/v1
- kind: ImageStream
- metadata:
- name: "{{ is_name }}"
- spec:
- lookupPolicy:
- local: false
- tags: []
-
- - name: Create build configuration
- community.okd.k8s:
- namespace: "{{ build_ns }}"
- definition:
- kind: BuildConfig
- apiVersion: build.openshift.io/v1
- metadata:
- name: "{{ build_config }}"
- spec:
- source:
- dockerfile: |
- FROM openshift/ruby-22-centos7
- RUN sleep 60s
- USER ansible
- strategy:
- type: Docker
- output:
- to:
- kind: "ImageStreamTag"
- name: "{{ is_name }}:latest"
-
- - name: Start Build from Build configuration
- community.okd.openshift_build:
- namespace: "{{ build_ns }}"
- build_config_name: "{{ build_config }}"
- register: new_build
-
- - name: Assert that a build has been created
- assert:
- that:
- - new_build is changed
- - new_build.builds.0.metadata.name == "{{ build_config }}-1"
-
- - name: Start a new Build from previous Build
- community.okd.openshift_build:
- namespace: "{{ build_ns }}"
- build_name: "{{ new_build.builds.0.metadata.name }}"
- register: rerun_build
-
- - name: Assert that another build has been created
- assert:
- that:
- - rerun_build is changed
- - rerun_build.builds.0.metadata.name == "{{ build_config }}-2"
-
- - name: Cancel first build created
- community.okd.openshift_build:
- namespace: "{{ build_ns }}"
- build_name: "{{ build_config }}-1"
- state: cancelled
- wait: yes
- register: cancel
-
- - name: Assert that the Build was cancelled
- assert:
- that:
- - cancel is changed
- - cancel.builds | length == 1
- - cancel.builds.0.metadata.name == "{{ build_config }}-1"
- - cancel.builds.0.metadata.namespace == "{{ build_ns }}"
- - cancel.builds.0.status.cancelled
-
- - name: Get Build info
- kubernetes.core.k8s_info:
- version: build.openshift.io/v1
- kind: Build
- namespace: "{{ build_ns }}"
- name: "{{ cancel.builds.0.metadata.name }}"
- register: build
-
- - name: Assert that build phase is cancelled
- assert:
- that:
- - build.resources | length == 1
- - build.resources.0.status.cancelled
- - build.resources.0.status.phase == 'Cancelled'
-
- - name: Cancel and restart Build using build config name
- community.okd.openshift_build:
- namespace: "{{ build_ns }}"
- build_config_name: "{{ build_config }}"
- state: restarted
- build_phases:
- - Running
- - New
- register: restart
-
- - name: assert that new build was created
- assert:
- that:
- - restart is changed
- - restart.builds | length == 1
- - 'restart.builds.0.metadata.name == "{{ build_config }}-3"'
-
- - name: Get Build 2 info
- kubernetes.core.k8s_info:
- version: build.openshift.io/v1
- kind: Build
- namespace: "{{ build_ns }}"
- name: "{{ build_config }}-2"
- register: build
-
- - name: Assert that build phase is cancelled
- assert:
- that:
- - build.resources | length == 1
- - build.resources.0.status.cancelled
- - build.resources.0.status.phase == 'Cancelled'
-
- - name: Get Build info
- kubernetes.core.k8s_info:
- version: build.openshift.io/v1
- kind: Build
- namespace: "{{ build_ns }}"
- name: "{{ build_config }}-3"
- register: build
-
- - name: Assert that Build is not cancelled
- assert:
- that:
- - build.resources | length == 1
- - '"cancelled" not in build.resources.0.status'
- - "build.resources.0.status.phase in ('New', 'Pending', 'Running')"
-
- - name: Prune Builds keep younger than 30min
- community.okd.openshift_adm_prune_builds:
- keep_younger_than: 30
- namespace: "{{ build_ns }}"
- register: prune
- check_mode: yes
-
- - name: Assert that no Builds were found
- assert:
- that:
- - not prune.changed
- - prune.builds | length == 0
-
- - name: Prune Builds without namespace
- community.okd.openshift_adm_prune_builds:
- register: prune_without_ns
- check_mode: yes
-
- - name: Assert that completed build are candidate for prune
- assert:
- that:
- - prune_without_ns is changed
- - prune_without_ns.builds | length > 0
- - '"{{ build_config }}-1" in build_names'
- - '"{{ build_config }}-2" in build_names'
- vars:
- build_names: '{{ prune_without_ns.builds | map(attribute="metadata") | flatten | map(attribute="name") | list }}'
-
- - name: Prune Builds using namespace
- community.okd.openshift_adm_prune_builds:
- namespace: "{{ build_ns }}"
- register: prune_with_ns
- check_mode: yes
-
- - name: Assert that prune operation found the completed build
- assert:
- that:
- - prune_with_ns is changed
- - prune_with_ns.builds | length == 2
-
- - name: Check Build before prune
- kubernetes.core.k8s_info:
- kind: Build
- api_version: build.openshift.io/v1
- name: "{{ build_config }}-1"
- namespace: "{{ build_ns }}"
- register: resource
-
- - name: Validate that any previous build operation executed with check_mode did not deleted the build
- assert:
- that:
- - resource.resources | length == 1
-
- - name: Execute prune operation
- community.okd.openshift_adm_prune_builds:
- namespace: "{{ build_ns }}"
- register: prune
-
- - name: assert prune is changed
- assert:
- that:
- - prune is changed
-
- - name: Check Build
- kubernetes.core.k8s_info:
- kind: Build
- api_version: build.openshift.io/v1
- name: "{{ build_config }}-1"
- namespace: "{{ build_ns }}"
- register: resource
-
- - name: Assert that the Build does not exist anymore
- assert:
- that:
- - resource.resources | length == 0
-
- - name: Check Build
- kubernetes.core.k8s_info:
- kind: Build
- api_version: build.openshift.io/v1
- name: "{{ build_config }}-2"
- namespace: "{{ build_ns }}"
- register: resource
-
- - name: Assert that the Build does not exist anymore
- assert:
- that:
- - resource.resources | length == 0
+ - set_fact:
+ build_ns: "builds"
+ build_config: "start-build"
+ is_name: "ruby"
+ prune_build: "prune-build"
+
+ - name: Ensure namespace
+ kubernetes.core.k8s:
+ kind: Namespace
+ name: "{{ build_ns }}"
+
+ - name: Create ImageStream
+ community.okd.k8s:
+ namespace: "{{ build_ns }}"
+ definition:
+ apiVersion: image.openshift.io/v1
+ kind: ImageStream
+ metadata:
+ name: "{{ is_name }}"
+ spec:
+ lookupPolicy:
+ local: false
+ tags: []
+
+ - name: Create build configuration
+ community.okd.k8s:
+ namespace: "{{ build_ns }}"
+ definition:
+ kind: BuildConfig
+ apiVersion: build.openshift.io/v1
+ metadata:
+ name: "{{ build_config }}"
+ spec:
+ source:
+ dockerfile: |
+ FROM openshift/ruby-22-centos7
+ RUN sleep 60s
+ USER ansible
+ strategy:
+ type: Docker
+ output:
+ to:
+ kind: "ImageStreamTag"
+ name: "{{ is_name }}:latest"
+
+ - name: Start Build from Build configuration
+ community.okd.openshift_build:
+ namespace: "{{ build_ns }}"
+ build_config_name: "{{ build_config }}"
+ register: new_build
+
+ - name: Assert that a build has been created
+ assert:
+ that:
+ - new_build is changed
+ - new_build.builds.0.metadata.name == "{{ build_config }}-1"
+
+ - name: Start a new Build from previous Build
+ community.okd.openshift_build:
+ namespace: "{{ build_ns }}"
+ build_name: "{{ new_build.builds.0.metadata.name }}"
+ register: rerun_build
+
+ - name: Assert that another build has been created
+ assert:
+ that:
+ - rerun_build is changed
+ - rerun_build.builds.0.metadata.name == "{{ build_config }}-2"
+
+ - name: Cancel first build created
+ community.okd.openshift_build:
+ namespace: "{{ build_ns }}"
+ build_name: "{{ build_config }}-1"
+ state: cancelled
+ wait: yes
+ register: cancel
+
+ - name: Assert that the Build was cancelled
+ assert:
+ that:
+ - cancel is changed
+ - cancel.builds | length == 1
+ - cancel.builds.0.metadata.name == "{{ build_config }}-1"
+ - cancel.builds.0.metadata.namespace == "{{ build_ns }}"
+ - '"cancelled" in cancel.builds.0.status'
+ - cancel.builds.0.status.cancelled
+
+ - name: Get info for 1st Build
+ kubernetes.core.k8s_info:
+ version: build.openshift.io/v1
+ kind: Build
+ namespace: "{{ build_ns }}"
+ name: "{{ cancel.builds.0.metadata.name }}"
+ register: build
+
+ - name: Assert that build phase is cancelled
+ assert:
+ that:
+ - build.resources | length == 1
+ - '"cancelled" in build.resources.0.status'
+ - build.resources.0.status.cancelled
+ - build.resources.0.status.phase == 'Cancelled'
+
+ - name: Cancel and restart Build using build config name
+ community.okd.openshift_build:
+ namespace: "{{ build_ns }}"
+ build_config_name: "{{ build_config }}"
+ state: restarted
+ build_phases:
+ - Pending
+ - Running
+ - New
+ register: restart
+
+ - name: assert that new build was created
+ assert:
+ that:
+ - restart is changed
+ - restart.builds | length == 1
+ - 'restart.builds.0.metadata.name == "{{ build_config }}-3"'
+
+ - name: Get info for 2nd Build
+ kubernetes.core.k8s_info:
+ version: build.openshift.io/v1
+ kind: Build
+ namespace: "{{ build_ns }}"
+ name: "{{ build_config }}-2"
+ register: build
+
+ - name: Assert that build phase is cancelled
+ assert:
+ that:
+ - build.resources | length == 1
+ - '"cancelled" in build.resources.0.status'
+ - build.resources.0.status.cancelled
+ - build.resources.0.status.phase == 'Cancelled'
+
+ - name: Get info for 3rd build
+ kubernetes.core.k8s_info:
+ version: build.openshift.io/v1
+ kind: Build
+ namespace: "{{ build_ns }}"
+ name: "{{ build_config }}-3"
+ register: build
+
+ - name: Assert that Build is not cancelled
+ assert:
+ that:
+ - build.resources | length == 1
+ - '"cancelled" not in build.resources.0.status'
+ - "build.resources.0.status.phase in ('New', 'Pending', 'Running')"
+
+ - name: Prune Builds keep younger than 30min
+ community.okd.openshift_adm_prune_builds:
+ keep_younger_than: 30
+ namespace: "{{ build_ns }}"
+ register: prune
+ check_mode: yes
+
+ - name: Assert that no Builds were found
+ assert:
+ that:
+ - not prune.changed
+ - prune.builds | length == 0
+
+ - name: Prune Builds without namespace
+ community.okd.openshift_adm_prune_builds:
+ register: prune_without_ns
+ check_mode: yes
+
+ - name: Assert that completed build are candidate for prune
+ assert:
+ that:
+ - prune_without_ns is changed
+ - prune_without_ns.builds | length > 0
+ - '"{{ build_config }}-1" in build_names'
+ - '"{{ build_config }}-2" in build_names'
+ vars:
+ build_names: '{{ prune_without_ns.builds | map(attribute="metadata") | flatten | map(attribute="name") | list }}'
+
+ - name: Prune Builds using namespace
+ community.okd.openshift_adm_prune_builds:
+ namespace: "{{ build_ns }}"
+ register: prune_with_ns
+ check_mode: yes
+
+ - name: Assert that prune operation found the completed build
+ assert:
+ that:
+ - prune_with_ns is changed
+ - prune_with_ns.builds | length == 2
+
+ - name: Check Build before prune
+ kubernetes.core.k8s_info:
+ kind: Build
+ api_version: build.openshift.io/v1
+ name: "{{ build_config }}-1"
+ namespace: "{{ build_ns }}"
+ register: resource
+
+ - name: Validate that any previous build operation executed with check_mode did not deleted the build
+ assert:
+ that:
+ - resource.resources | length == 1
+
+ - name: Execute prune operation
+ community.okd.openshift_adm_prune_builds:
+ namespace: "{{ build_ns }}"
+ register: prune
+
+ - name: assert prune is changed
+ assert:
+ that:
+ - prune is changed
+
+ - name: Check Build
+ kubernetes.core.k8s_info:
+ kind: Build
+ api_version: build.openshift.io/v1
+ name: "{{ build_config }}-1"
+ namespace: "{{ build_ns }}"
+ register: resource
+
+ - name: Assert that the Build does not exist anymore
+ assert:
+ that:
+ - resource.resources | length == 0
+
+ - name: Check Build
+ kubernetes.core.k8s_info:
+ kind: Build
+ api_version: build.openshift.io/v1
+ name: "{{ build_config }}-2"
+ namespace: "{{ build_ns }}"
+ register: resource
+
+ - name: Assert that the Build does not exist anymore
+ assert:
+ that:
+ - resource.resources | length == 0
always:
- name: Ensure namespace is deleted
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_import_images.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_import_images.yml
index 04392bb26..76c49f0a1 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_import_images.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_import_images.yml
@@ -1,174 +1,175 @@
+---
- name: Openshift import image testing
block:
- - set_fact:
- test_ns: "import-images"
-
- - name: Ensure namespace
- community.okd.k8s:
- kind: Namespace
- name: '{{ test_ns }}'
-
- - name: Import image using tag (should import latest tag only)
- community.okd.openshift_import_image:
- namespace: "{{ test_ns }}"
- name: "ansible/awx"
- check_mode: yes
- register: import_tag
-
- - name: Assert only latest was imported
- assert:
- that:
- - import_tag is changed
- - import_tag.result | length == 1
- - import_tag.result.0.spec.import
- - import_tag.result.0.spec.images.0.from.kind == "DockerImage"
- - import_tag.result.0.spec.images.0.from.name == "ansible/awx"
-
- - name: check image stream
- kubernetes.core.k8s_info:
- kind: ImageStream
- namespace: "{{ test_ns }}"
- name: awx
- register: resource
-
- - name: assert that image stream is not created when using check_mode=yes
- assert:
- that:
- - resource.resources == []
-
- - name: Import image using tag (should import latest tag only)
- community.okd.openshift_import_image:
- namespace: "{{ test_ns }}"
- name: "ansible/awx"
- register: import_tag
-
- - name: Assert only latest was imported
- assert:
- that:
- - import_tag is changed
-
- - name: check image stream
- kubernetes.core.k8s_info:
- kind: ImageStream
- namespace: "{{ test_ns }}"
- name: awx
- register: resource
-
- - name: assert that image stream contains only tag latest
- assert:
- that:
- - resource.resources | length == 1
- - resource.resources.0.status.tags.0.tag == 'latest'
-
- - name: Import once again the latest tag
- community.okd.openshift_import_image:
- namespace: "{{ test_ns }}"
- name: "ansible/awx"
- register: import_tag
-
- - name: assert change was performed
- assert:
- that:
- - import_tag is changed
-
- - name: check image stream
- kubernetes.core.k8s_info:
- kind: ImageStream
- version: image.openshift.io/v1
- namespace: "{{ test_ns }}"
- name: awx
- register: resource
-
- - name: assert that image stream still contains unique tag
- assert:
- that:
- - resource.resources | length == 1
- - resource.resources.0.status.tags.0.tag == 'latest'
-
- - name: Import another tags
- community.okd.openshift_import_image:
- namespace: "{{ test_ns }}"
- name: "ansible/awx:17.1.0"
- register: import_another_tag
- ignore_errors: yes
-
- - name: assert that another tag was imported
- assert:
- that:
- - import_another_tag is failed
- - '"the tag 17.1.0 does not exist on the image stream" in import_another_tag.msg'
-
- - name: Create simple ImageStream (without docker external container)
- community.okd.k8s:
- namespace: "{{ test_ns }}"
- name: "local-is"
- definition:
- apiVersion: image.openshift.io/v1
+ - set_fact:
+ test_ns: "import-images"
+
+ - name: Ensure namespace
+ community.okd.k8s:
+ kind: Namespace
+ name: '{{ test_ns }}'
+
+ - name: Import image using tag (should import latest tag only)
+ community.okd.openshift_import_image:
+ namespace: "{{ test_ns }}"
+ name: "ansible/awx"
+ check_mode: yes
+ register: import_tag
+
+ - name: Assert only latest was imported
+ assert:
+ that:
+ - import_tag is changed
+ - import_tag.result | length == 1
+ - import_tag.result.0.spec.import
+ - import_tag.result.0.spec.images.0.from.kind == "DockerImage"
+ - import_tag.result.0.spec.images.0.from.name == "ansible/awx"
+
+ - name: check image stream
+ kubernetes.core.k8s_info:
+ kind: ImageStream
+ namespace: "{{ test_ns }}"
+ name: awx
+ register: resource
+
+ - name: assert that image stream is not created when using check_mode=yes
+ assert:
+ that:
+ - resource.resources == []
+
+ - name: Import image using tag (should import latest tag only)
+ community.okd.openshift_import_image:
+ namespace: "{{ test_ns }}"
+ name: "ansible/awx"
+ register: import_tag
+
+ - name: Assert only latest was imported
+ assert:
+ that:
+ - import_tag is changed
+
+ - name: check image stream
+ kubernetes.core.k8s_info:
+ kind: ImageStream
+ namespace: "{{ test_ns }}"
+ name: awx
+ register: resource
+
+ - name: assert that image stream contains only tag latest
+ assert:
+ that:
+ - resource.resources | length == 1
+ - resource.resources.0.status.tags.0.tag == 'latest'
+
+ - name: Import once again the latest tag
+ community.okd.openshift_import_image:
+ namespace: "{{ test_ns }}"
+ name: "ansible/awx"
+ register: import_tag
+
+ - name: assert change was performed
+ assert:
+ that:
+ - import_tag is changed
+
+ - name: check image stream
+ kubernetes.core.k8s_info:
+ kind: ImageStream
+ version: image.openshift.io/v1
+ namespace: "{{ test_ns }}"
+ name: awx
+ register: resource
+
+ - name: assert that image stream still contains unique tag
+ assert:
+ that:
+ - resource.resources | length == 1
+ - resource.resources.0.status.tags.0.tag == 'latest'
+
+ - name: Import another tags
+ community.okd.openshift_import_image:
+ namespace: "{{ test_ns }}"
+ name: "ansible/awx:17.1.0"
+ register: import_another_tag
+ ignore_errors: yes
+
+ - name: assert that another tag was imported
+ assert:
+ that:
+ - import_another_tag is failed
+ - '"the tag 17.1.0 does not exist on the image stream" in import_another_tag.msg'
+
+ - name: Create simple ImageStream (without docker external container)
+ community.okd.k8s:
+ namespace: "{{ test_ns }}"
+ name: "local-is"
+ definition:
+ apiVersion: image.openshift.io/v1
+ kind: ImageStream
+ spec:
+ lookupPolicy:
+ local: false
+ tags: []
+
+ - name: Import all tag for image stream not pointing on external container image should failed
+ community.okd.openshift_import_image:
+ namespace: "{{ test_ns }}"
+ name: "local-is"
+ all: true
+ register: error_tag
+ ignore_errors: true
+ check_mode: yes
+
+ - name: Assert module cannot import from non-existing tag from ImageStream
+ assert:
+ that:
+ - error_tag is failed
+ - 'error_tag.msg == "image stream {{ test_ns }}/local-is does not have tags pointing to external container images"'
+
+ - name: import all tags for container image ibmcom/pause and specific tag for redhat/ubi8-micro
+ community.okd.openshift_import_image:
+ namespace: "{{ test_ns }}"
+ name:
+ - "ibmcom/pause"
+ - "redhat/ubi8-micro:8.5-437"
+ all: true
+ register: multiple_import
+
+ - name: Assert that import succeed
+ assert:
+ that:
+ - multiple_import is changed
+ - multiple_import.result | length == 2
+
+ - name: Read ibmcom/pause ImageStream
+ kubernetes.core.k8s_info:
+ version: image.openshift.io/v1
+ kind: ImageStream
+ namespace: "{{ test_ns }}"
+ name: pause
+ register: pause
+
+ - name: assert that ibmcom/pause has multiple tags
+ assert:
+ that:
+ - pause.resources | length == 1
+ - pause.resources.0.status.tags | length > 1
+
+ - name: Read redhat/ubi8-micro ImageStream
+ kubernetes.core.k8s_info:
+ version: image.openshift.io/v1
kind: ImageStream
- spec:
- lookupPolicy:
- local: false
- tags: []
-
- - name: Import all tag for image stream not pointing on external container image should failed
- community.okd.openshift_import_image:
- namespace: "{{ test_ns }}"
- name: "local-is"
- all: true
- register: error_tag
- ignore_errors: true
- check_mode: yes
-
- - name: Assert module cannot import from non-existing tag from ImageStream
- assert:
- that:
- - error_tag is failed
- - 'error_tag.msg == "image stream {{ test_ns }}/local-is does not have tags pointing to external container images"'
-
- - name: import all tags for container image ibmcom/pause and specific tag for redhat/ubi8-micro
- community.okd.openshift_import_image:
- namespace: "{{ test_ns }}"
- name:
- - "ibmcom/pause"
- - "redhat/ubi8-micro:8.5-437"
- all: true
- register: multiple_import
-
- - name: Assert that import succeed
- assert:
- that:
- - multiple_import is changed
- - multiple_import.result | length == 2
-
- - name: Read ibmcom/pause ImageStream
- kubernetes.core.k8s_info:
- version: image.openshift.io/v1
- kind: ImageStream
- namespace: "{{ test_ns }}"
- name: pause
- register: pause
-
- - name: assert that ibmcom/pause has multiple tags
- assert:
- that:
- - pause.resources | length == 1
- - pause.resources.0.status.tags | length > 1
-
- - name: Read redhat/ubi8-micro ImageStream
- kubernetes.core.k8s_info:
- version: image.openshift.io/v1
- kind: ImageStream
- namespace: "{{ test_ns }}"
- name: ubi8-micro
- register: resource
-
- - name: assert that redhat/ubi8-micro has only one tag
- assert:
- that:
- - resource.resources | length == 1
- - resource.resources.0.status.tags | length == 1
- - 'resource.resources.0.status.tags.0.tag == "8.5-437"'
+ namespace: "{{ test_ns }}"
+ name: ubi8-micro
+ register: resource
+
+ - name: assert that redhat/ubi8-micro has only one tag
+ assert:
+ that:
+ - resource.resources | length == 1
+ - resource.resources.0.status.tags | length == 1
+ - 'resource.resources.0.status.tags.0.tag == "8.5-437"'
always:
- name: Delete testing namespace
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_prune_images.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_prune_images.yml
index 86630da69..1748522ec 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_prune_images.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_prune_images.yml
@@ -38,12 +38,12 @@
name: "{{ pod_name }}"
spec:
containers:
- - name: test-container
- image: "{{ prune_registry }}/{{ prune_ns }}/{{ container.name }}:latest"
- command:
- - /bin/sh
- - -c
- - while true;do date;sleep 5; done
+ - name: test-container
+ image: "{{ prune_registry }}/{{ prune_ns }}/{{ container.name }}:latest"
+ command:
+ - /bin/sh
+ - -c
+ - while true;do date;sleep 5; done
- name: Create limit range for images size
community.okd.k8s:
@@ -57,7 +57,7 @@
- type: openshift.io/Image
max:
storage: 1Gi
-
+
- name: Prune images from namespace
community.okd.openshift_adm_prune_images:
registry_url: "{{ prune_registry }}"
diff --git a/ansible_collections/community/okd/molecule/default/tasks/openshift_route.yml b/ansible_collections/community/okd/molecule/default/tasks/openshift_route.yml
index 50056b7e4..b3043cb7e 100644
--- a/ansible_collections/community/okd/molecule/default/tasks/openshift_route.yml
+++ b/ansible_collections/community/okd/molecule/default/tasks/openshift_route.yml
@@ -19,10 +19,10 @@
app: hello-kubernetes
spec:
containers:
- - name: hello-kubernetes
- image: docker.io/openshift/hello-openshift
- ports:
- - containerPort: 8080
+ - name: hello-kubernetes
+ image: docker.io/openshift/hello-openshift
+ ports:
+ - containerPort: 8080
- name: Create Service
community.okd.k8s:
@@ -35,8 +35,8 @@
namespace: default
spec:
ports:
- - port: 80
- targetPort: 8080
+ - port: 80
+ targetPort: 8080
selector:
app: hello-kubernetes
diff --git a/ansible_collections/community/okd/molecule/default/vars/main.yml b/ansible_collections/community/okd/molecule/default/vars/main.yml
index 66fb0d33c..22e227c1f 100644
--- a/ansible_collections/community/okd/molecule/default/vars/main.yml
+++ b/ansible_collections/community/okd/molecule/default/vars/main.yml
@@ -64,14 +64,16 @@ okd_dc_triggers:
okd_dc_spec:
template: '{{ k8s_pod_template }}'
- triggers: '{{ okd_dc_triggers }}'
+ selector:
+ matchLabels:
+ app: "{{ k8s_pod_name }}"
replicas: 1
strategy:
type: Recreate
okd_dc_template:
- apiVersion: v1
- kind: DeploymentConfig
+ apiVersion: apps/v1
+ kind: Deployment
spec: '{{ okd_dc_spec }}'
okd_imagestream_template:
@@ -83,12 +85,12 @@ okd_imagestream_template:
lookupPolicy:
local: true
tags:
- - annotations: null
- from:
- kind: DockerImage
- name: '{{ image }}'
- name: '{{ image_tag }}'
- referencePolicy:
- type: Source
+ - annotations: null
+ from:
+ kind: DockerImage
+ name: '{{ image }}'
+ name: '{{ image_tag }}'
+ referencePolicy:
+ type: Source
image_tag: latest
diff --git a/ansible_collections/community/okd/plugins/connection/oc.py b/ansible_collections/community/okd/plugins/connection/oc.py
index 44236a11a..ae399e66b 100644
--- a/ansible_collections/community/okd/plugins/connection/oc.py
+++ b/ansible_collections/community/okd/plugins/connection/oc.py
@@ -17,10 +17,11 @@
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-DOCUMENTATION = '''
+DOCUMENTATION = """
author:
- xuxinkun (@xuxinkun)
@@ -145,29 +146,32 @@ DOCUMENTATION = '''
env:
- name: K8S_AUTH_VERIFY_SSL
aliases: [ oc_verify_ssl ]
-'''
+"""
-from ansible_collections.kubernetes.core.plugins.connection.kubectl import Connection as KubectlConnection
+from ansible_collections.kubernetes.core.plugins.connection.kubectl import (
+ Connection as KubectlConnection,
+)
-CONNECTION_TRANSPORT = 'oc'
+CONNECTION_TRANSPORT = "oc"
CONNECTION_OPTIONS = {
- 'oc_container': '-c',
- 'oc_namespace': '-n',
- 'oc_kubeconfig': '--kubeconfig',
- 'oc_context': '--context',
- 'oc_host': '--server',
- 'client_cert': '--client-certificate',
- 'client_key': '--client-key',
- 'ca_cert': '--certificate-authority',
- 'validate_certs': '--insecure-skip-tls-verify',
- 'oc_token': '--token'
+ "oc_container": "-c",
+ "oc_namespace": "-n",
+ "oc_kubeconfig": "--kubeconfig",
+ "oc_context": "--context",
+ "oc_host": "--server",
+ "client_cert": "--client-certificate",
+ "client_key": "--client-key",
+ "ca_cert": "--certificate-authority",
+ "validate_certs": "--insecure-skip-tls-verify",
+ "oc_token": "--token",
}
class Connection(KubectlConnection):
- ''' Local oc based connections '''
+ """Local oc based connections"""
+
transport = CONNECTION_TRANSPORT
connection_options = CONNECTION_OPTIONS
documentation = DOCUMENTATION
diff --git a/ansible_collections/community/okd/plugins/inventory/openshift.py b/ansible_collections/community/okd/plugins/inventory/openshift.py
index f69c652fc..4ec788408 100644
--- a/ansible_collections/community/okd/plugins/inventory/openshift.py
+++ b/ansible_collections/community/okd/plugins/inventory/openshift.py
@@ -1,11 +1,11 @@
# Copyright (c) 2018 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
__metaclass__ = type
-DOCUMENTATION = '''
+DOCUMENTATION = """
name: openshift
author:
- Chris Houseknecht (@chouseknecht)
@@ -17,6 +17,13 @@ DOCUMENTATION = '''
- Groups by cluster name, namespace, namespace_services, namespace_pods, namespace_routes, and labels
- Uses openshift.(yml|yaml) YAML configuration file to set parameter values.
+ deprecated:
+ removed_in: 4.0.0
+ why: |
+ As discussed in U(https://github.com/ansible-collections/kubernetes.core/issues/31), we decided to
+ remove the openshift inventory plugin in release 4.0.0.
+ alternative: "Use M(kubernetes.core.k8s_info) and M(ansible.builtin.add_host) instead."
+
options:
plugin:
description: token that ensures this is a source file for the 'openshift' plugin.
@@ -87,34 +94,41 @@ DOCUMENTATION = '''
- "python >= 3.6"
- "kubernetes >= 12.0.0"
- "PyYAML >= 3.11"
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
# File must be named openshift.yaml or openshift.yml
-# Authenticate with token, and return all pods and services for all namespaces
-plugin: community.okd.openshift
-connections:
- - host: https://192.168.64.4:8443
- api_key: xxxxxxxxxxxxxxxx
- verify_ssl: false
-
-# Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
-plugin: community.okd.openshift
-connections:
- - namespaces:
- - testing
-
-# Use a custom config file, and a specific context.
-plugin: community.okd.openshift
-connections:
- - kubeconfig: /path/to/config
- context: 'awx/192-168-64-4:8443/developer'
-'''
+- name: Authenticate with token, and return all pods and services for all namespaces
+ plugin: community.okd.openshift
+ connections:
+ - host: https://192.168.64.4:8443
+ api_key: xxxxxxxxxxxxxxxx
+ verify_ssl: false
+
+- name: Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
+ plugin: community.okd.openshift
+ connections:
+ - namespaces:
+ - testing
+
+- name: Use a custom config file, and a specific context.
+ plugin: community.okd.openshift
+ connections:
+ - kubeconfig: /path/to/config
+ context: 'awx/192-168-64-4:8443/developer'
+"""
try:
- from ansible_collections.kubernetes.core.plugins.inventory.k8s import K8sInventoryException, InventoryModule as K8sInventoryModule, format_dynamic_api_exc
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import get_api_client
+ from ansible_collections.kubernetes.core.plugins.inventory.k8s import (
+ K8sInventoryException,
+ InventoryModule as K8sInventoryModule,
+ format_dynamic_api_exc,
+ )
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
+ get_api_client,
+ )
+
HAS_KUBERNETES_COLLECTION = True
except ImportError as e:
HAS_KUBERNETES_COLLECTION = False
@@ -127,29 +141,38 @@ except ImportError:
class InventoryModule(K8sInventoryModule):
- NAME = 'community.okd.openshift'
+ NAME = "community.okd.openshift"
- connection_plugin = 'community.okd.oc'
- transport = 'oc'
+ connection_plugin = "community.okd.oc"
+ transport = "oc"
def check_kubernetes_collection(self):
-
if not HAS_KUBERNETES_COLLECTION:
- K8sInventoryException("The kubernetes.core collection must be installed")
+ raise K8sInventoryException(
+ "The kubernetes.core collection must be installed"
+ )
def fetch_objects(self, connections):
self.check_kubernetes_collection()
super(InventoryModule, self).fetch_objects(connections)
+ self.display.deprecated(
+ "The 'openshift' inventory plugin has been deprecated and will be removed in release 4.0.0",
+ version="4.0.0",
+ collection_name="community.okd",
+ )
+
if connections:
if not isinstance(connections, list):
raise K8sInventoryException("Expecting connections to be a list.")
for connection in connections:
client = get_api_client(**connection)
- name = connection.get('name', self.get_default_host_name(client.configuration.host))
- if connection.get('namespaces'):
- namespaces = connection['namespaces']
+ name = connection.get(
+ "name", self.get_default_host_name(client.configuration.host)
+ )
+ if connection.get("namespaces"):
+ namespaces = connection["namespaces"]
else:
namespaces = self.get_available_namespaces(client)
for namespace in namespaces:
@@ -163,15 +186,19 @@ class InventoryModule(K8sInventoryModule):
def get_routes_for_namespace(self, client, name, namespace):
self.check_kubernetes_collection()
- v1_route = client.resources.get(api_version='route.openshift.io/v1', kind='Route')
+ v1_route = client.resources.get(
+ api_version="route.openshift.io/v1", kind="Route"
+ )
try:
obj = v1_route.get(namespace=namespace)
except DynamicApiError as exc:
self.display.debug(exc)
- raise K8sInventoryException('Error fetching Routes list: %s' % format_dynamic_api_exc(exc))
+ raise K8sInventoryException(
+ "Error fetching Routes list: %s" % format_dynamic_api_exc(exc)
+ )
- namespace_group = 'namespace_{0}'.format(namespace)
- namespace_routes_group = '{0}_routes'.format(namespace_group)
+ namespace_group = "namespace_{0}".format(namespace)
+ namespace_routes_group = "{0}_routes".format(namespace_group)
self.inventory.add_group(name)
self.inventory.add_group(namespace_group)
@@ -180,14 +207,18 @@ class InventoryModule(K8sInventoryModule):
self.inventory.add_child(namespace_group, namespace_routes_group)
for route in obj.items:
route_name = route.metadata.name
- route_annotations = {} if not route.metadata.annotations else dict(route.metadata.annotations)
+ route_annotations = (
+ {}
+ if not route.metadata.annotations
+ else dict(route.metadata.annotations)
+ )
self.inventory.add_host(route_name)
if route.metadata.labels:
# create a group for each label_value
for key, value in route.metadata.labels:
- group_name = 'label_{0}_{1}'.format(key, value)
+ group_name = "label_{0}_{1}".format(key, value)
self.inventory.add_group(group_name)
self.inventory.add_child(group_name, route_name)
route_labels = dict(route.metadata.labels)
@@ -197,19 +228,25 @@ class InventoryModule(K8sInventoryModule):
self.inventory.add_child(namespace_routes_group, route_name)
# add hostvars
- self.inventory.set_variable(route_name, 'labels', route_labels)
- self.inventory.set_variable(route_name, 'annotations', route_annotations)
- self.inventory.set_variable(route_name, 'cluster_name', route.metadata.clusterName)
- self.inventory.set_variable(route_name, 'object_type', 'route')
- self.inventory.set_variable(route_name, 'self_link', route.metadata.selfLink)
- self.inventory.set_variable(route_name, 'resource_version', route.metadata.resourceVersion)
- self.inventory.set_variable(route_name, 'uid', route.metadata.uid)
+ self.inventory.set_variable(route_name, "labels", route_labels)
+ self.inventory.set_variable(route_name, "annotations", route_annotations)
+ self.inventory.set_variable(
+ route_name, "cluster_name", route.metadata.clusterName
+ )
+ self.inventory.set_variable(route_name, "object_type", "route")
+ self.inventory.set_variable(
+ route_name, "self_link", route.metadata.selfLink
+ )
+ self.inventory.set_variable(
+ route_name, "resource_version", route.metadata.resourceVersion
+ )
+ self.inventory.set_variable(route_name, "uid", route.metadata.uid)
if route.spec.host:
- self.inventory.set_variable(route_name, 'host', route.spec.host)
+ self.inventory.set_variable(route_name, "host", route.spec.host)
if route.spec.path:
- self.inventory.set_variable(route_name, 'path', route.spec.path)
+ self.inventory.set_variable(route_name, "path", route.spec.path)
- if hasattr(route.spec.port, 'targetPort') and route.spec.port.targetPort:
- self.inventory.set_variable(route_name, 'port', dict(route.spec.port))
+ if hasattr(route.spec.port, "targetPort") and route.spec.port.targetPort:
+ self.inventory.set_variable(route_name, "port", dict(route.spec.port))
diff --git a/ansible_collections/community/okd/plugins/module_utils/k8s.py b/ansible_collections/community/okd/plugins/module_utils/k8s.py
index 87ec70d90..9c8f47fd2 100644
--- a/ansible_collections/community/okd/plugins/module_utils/k8s.py
+++ b/ansible_collections/community/okd/plugins/module_utils/k8s.py
@@ -1,35 +1,46 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
import re
import operator
from functools import reduce
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.resource import create_definitions
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import CoreException
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.resource import (
+ create_definitions,
+ )
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import (
+ CoreException,
+ )
except ImportError:
pass
from ansible.module_utils._text import to_native
try:
- from kubernetes.dynamic.exceptions import DynamicApiError, NotFoundError, ForbiddenError
+ from kubernetes.dynamic.exceptions import (
+ DynamicApiError,
+ NotFoundError,
+ ForbiddenError,
+ )
except ImportError as e:
pass
-TRIGGER_ANNOTATION = 'image.openshift.io/triggers'
-TRIGGER_CONTAINER = re.compile(r"(?P<path>.*)\[((?P<index>[0-9]+)|\?\(@\.name==[\"'\\]*(?P<name>[a-z0-9]([-a-z0-9]*[a-z0-9])?))")
+TRIGGER_ANNOTATION = "image.openshift.io/triggers"
+TRIGGER_CONTAINER = re.compile(
+ r"(?P<path>.*)\[((?P<index>[0-9]+)|\?\(@\.name==[\"'\\]*(?P<name>[a-z0-9]([-a-z0-9]*[a-z0-9])?))"
+)
class OKDRawModule(AnsibleOpenshiftModule):
-
def __init__(self, **kwargs):
-
super(OKDRawModule, self).__init__(**kwargs)
@property
@@ -50,36 +61,60 @@ class OKDRawModule(AnsibleOpenshiftModule):
result = {"changed": False, "result": {}}
warnings = []
- if self.params.get("state") != 'absent':
+ if self.params.get("state") != "absent":
existing = None
name = definition.get("metadata", {}).get("name")
namespace = definition.get("metadata", {}).get("namespace")
- if definition.get("kind") in ['Project', 'ProjectRequest']:
+ if definition.get("kind") in ["Project", "ProjectRequest"]:
try:
- resource = self.svc.find_resource(kind=definition.get("kind"), api_version=definition.get("apiVersion", "v1"))
- existing = resource.get(name=name, namespace=namespace).to_dict()
+ resource = self.svc.find_resource(
+ kind=definition.get("kind"),
+ api_version=definition.get("apiVersion", "v1"),
+ )
+ existing = resource.get(
+ name=name, namespace=namespace
+ ).to_dict()
except (NotFoundError, ForbiddenError):
result = self.create_project_request(definition)
changed |= result["changed"]
results.append(result)
continue
except DynamicApiError as exc:
- self.fail_json(msg='Failed to retrieve requested object: {0}'.format(exc.body),
- error=exc.status, status=exc.status, reason=exc.reason)
-
- if definition.get("kind") not in ['Project', 'ProjectRequest']:
+ self.fail_json(
+ msg="Failed to retrieve requested object: {0}".format(
+ exc.body
+ ),
+ error=exc.status,
+ status=exc.status,
+ reason=exc.reason,
+ )
+
+ if definition.get("kind") not in ["Project", "ProjectRequest"]:
try:
- resource = self.svc.find_resource(kind=definition.get("kind"), api_version=definition.get("apiVersion", "v1"))
- existing = resource.get(name=name, namespace=namespace).to_dict()
+ resource = self.svc.find_resource(
+ kind=definition.get("kind"),
+ api_version=definition.get("apiVersion", "v1"),
+ )
+ existing = resource.get(
+ name=name, namespace=namespace
+ ).to_dict()
except Exception:
existing = None
if existing:
- if resource.kind == 'DeploymentConfig':
- if definition.get('spec', {}).get('triggers'):
- definition = self.resolve_imagestream_triggers(existing, definition)
- elif existing['metadata'].get('annotations', {}).get(TRIGGER_ANNOTATION):
- definition = self.resolve_imagestream_trigger_annotation(existing, definition)
+ if resource.kind == "DeploymentConfig":
+ if definition.get("spec", {}).get("triggers"):
+ definition = self.resolve_imagestream_triggers(
+ existing, definition
+ )
+ elif (
+ existing["metadata"]
+ .get("annotations", {})
+ .get(TRIGGER_ANNOTATION)
+ ):
+ definition = self.resolve_imagestream_trigger_annotation(
+ existing, definition
+ )
if self.params.get("validate") is not None:
warnings = self.validate(definition)
@@ -116,13 +151,15 @@ class OKDRawModule(AnsibleOpenshiftModule):
@staticmethod
def get_index(desired, objects, keys):
- """ Iterates over keys, returns the first object from objects where the value of the key
- matches the value in desired
+ """Iterates over keys, returns the first object from objects where the value of the key
+ matches the value in desired
"""
# pylint: disable=use-a-generator
# Use a generator instead 'all(desired.get(key, True) == item.get(key, False) for key in keys)'
for i, item in enumerate(objects):
- if item and all([desired.get(key, True) == item.get(key, False) for key in keys]):
+ if item and all(
+ [desired.get(key, True) == item.get(key, False) for key in keys]
+ ):
return i
def resolve_imagestream_trigger_annotation(self, existing, definition):
@@ -137,84 +174,148 @@ class OKDRawModule(AnsibleOpenshiftModule):
def set_from_fields(d, fields, value):
get_from_fields(d, fields[:-1])[fields[-1]] = value
- if TRIGGER_ANNOTATION in definition['metadata'].get('annotations', {}).keys():
- triggers = yaml.safe_load(definition['metadata']['annotations'][TRIGGER_ANNOTATION] or '[]')
+ if TRIGGER_ANNOTATION in definition["metadata"].get("annotations", {}).keys():
+ triggers = yaml.safe_load(
+ definition["metadata"]["annotations"][TRIGGER_ANNOTATION] or "[]"
+ )
else:
- triggers = yaml.safe_load(existing['metadata'].get('annotations', '{}').get(TRIGGER_ANNOTATION, '[]'))
+ triggers = yaml.safe_load(
+ existing["metadata"]
+ .get("annotations", "{}")
+ .get(TRIGGER_ANNOTATION, "[]")
+ )
if not isinstance(triggers, list):
return definition
for trigger in triggers:
- if trigger.get('fieldPath'):
- parsed = self.parse_trigger_fieldpath(trigger['fieldPath'])
- path = parsed.get('path', '').split('.')
+ if trigger.get("fieldPath"):
+ parsed = self.parse_trigger_fieldpath(trigger["fieldPath"])
+ path = parsed.get("path", "").split(".")
if path:
existing_containers = get_from_fields(existing, path)
new_containers = get_from_fields(definition, path)
- if parsed.get('name'):
- existing_index = self.get_index({'name': parsed['name']}, existing_containers, ['name'])
- new_index = self.get_index({'name': parsed['name']}, new_containers, ['name'])
- elif parsed.get('index') is not None:
- existing_index = new_index = int(parsed['index'])
+ if parsed.get("name"):
+ existing_index = self.get_index(
+ {"name": parsed["name"]}, existing_containers, ["name"]
+ )
+ new_index = self.get_index(
+ {"name": parsed["name"]}, new_containers, ["name"]
+ )
+ elif parsed.get("index") is not None:
+ existing_index = new_index = int(parsed["index"])
else:
existing_index = new_index = None
if existing_index is not None and new_index is not None:
- if existing_index < len(existing_containers) and new_index < len(new_containers):
- set_from_fields(definition, path + [new_index, 'image'], get_from_fields(existing, path + [existing_index, 'image']))
+ if existing_index < len(
+ existing_containers
+ ) and new_index < len(new_containers):
+ set_from_fields(
+ definition,
+ path + [new_index, "image"],
+ get_from_fields(
+ existing, path + [existing_index, "image"]
+ ),
+ )
return definition
def resolve_imagestream_triggers(self, existing, definition):
-
- existing_triggers = existing.get('spec', {}).get('triggers')
- new_triggers = definition['spec']['triggers']
- existing_containers = existing.get('spec', {}).get('template', {}).get('spec', {}).get('containers', [])
- new_containers = definition.get('spec', {}).get('template', {}).get('spec', {}).get('containers', [])
+ existing_triggers = existing.get("spec", {}).get("triggers")
+ new_triggers = definition["spec"]["triggers"]
+ existing_containers = (
+ existing.get("spec", {})
+ .get("template", {})
+ .get("spec", {})
+ .get("containers", [])
+ )
+ new_containers = (
+ definition.get("spec", {})
+ .get("template", {})
+ .get("spec", {})
+ .get("containers", [])
+ )
for i, trigger in enumerate(new_triggers):
- if trigger.get('type') == 'ImageChange' and trigger.get('imageChangeParams'):
- names = trigger['imageChangeParams'].get('containerNames', [])
+ if trigger.get("type") == "ImageChange" and trigger.get(
+ "imageChangeParams"
+ ):
+ names = trigger["imageChangeParams"].get("containerNames", [])
for name in names:
- old_container_index = self.get_index({'name': name}, existing_containers, ['name'])
- new_container_index = self.get_index({'name': name}, new_containers, ['name'])
- if old_container_index is not None and new_container_index is not None:
- image = existing['spec']['template']['spec']['containers'][old_container_index]['image']
- definition['spec']['template']['spec']['containers'][new_container_index]['image'] = image
-
- existing_index = self.get_index(trigger['imageChangeParams'],
- [x.get('imageChangeParams') for x in existing_triggers],
- ['containerNames'])
+ old_container_index = self.get_index(
+ {"name": name}, existing_containers, ["name"]
+ )
+ new_container_index = self.get_index(
+ {"name": name}, new_containers, ["name"]
+ )
+ if (
+ old_container_index is not None
+ and new_container_index is not None
+ ):
+ image = existing["spec"]["template"]["spec"]["containers"][
+ old_container_index
+ ]["image"]
+ definition["spec"]["template"]["spec"]["containers"][
+ new_container_index
+ ]["image"] = image
+
+ existing_index = self.get_index(
+ trigger["imageChangeParams"],
+ [x.get("imageChangeParams") for x in existing_triggers],
+ ["containerNames"],
+ )
if existing_index is not None:
- existing_image = existing_triggers[existing_index].get('imageChangeParams', {}).get('lastTriggeredImage')
+ existing_image = (
+ existing_triggers[existing_index]
+ .get("imageChangeParams", {})
+ .get("lastTriggeredImage")
+ )
if existing_image:
- definition['spec']['triggers'][i]['imageChangeParams']['lastTriggeredImage'] = existing_image
- existing_from = existing_triggers[existing_index].get('imageChangeParams', {}).get('from', {})
- new_from = trigger['imageChangeParams'].get('from', {})
- existing_namespace = existing_from.get('namespace')
- existing_name = existing_from.get('name', False)
- new_name = new_from.get('name', True)
- add_namespace = existing_namespace and 'namespace' not in new_from.keys() and existing_name == new_name
+ definition["spec"]["triggers"][i]["imageChangeParams"][
+ "lastTriggeredImage"
+ ] = existing_image
+ existing_from = (
+ existing_triggers[existing_index]
+ .get("imageChangeParams", {})
+ .get("from", {})
+ )
+ new_from = trigger["imageChangeParams"].get("from", {})
+ existing_namespace = existing_from.get("namespace")
+ existing_name = existing_from.get("name", False)
+ new_name = new_from.get("name", True)
+ add_namespace = (
+ existing_namespace
+ and "namespace" not in new_from.keys()
+ and existing_name == new_name
+ )
if add_namespace:
- definition['spec']['triggers'][i]['imageChangeParams']['from']['namespace'] = existing_from['namespace']
+ definition["spec"]["triggers"][i]["imageChangeParams"][
+ "from"
+ ]["namespace"] = existing_from["namespace"]
return definition
def parse_trigger_fieldpath(self, expression):
parsed = TRIGGER_CONTAINER.search(expression).groupdict()
- if parsed.get('index'):
- parsed['index'] = int(parsed['index'])
+ if parsed.get("index"):
+ parsed["index"] = int(parsed["index"])
return parsed
def create_project_request(self, definition):
- definition['kind'] = 'ProjectRequest'
- result = {'changed': False, 'result': {}}
- resource = self.svc.find_resource(kind='ProjectRequest', api_version=definition['apiVersion'], fail=True)
+ definition["kind"] = "ProjectRequest"
+ result = {"changed": False, "result": {}}
+ resource = self.svc.find_resource(
+ kind="ProjectRequest", api_version=definition["apiVersion"], fail=True
+ )
if not self.check_mode:
try:
k8s_obj = resource.create(definition)
- result['result'] = k8s_obj.to_dict()
+ result["result"] = k8s_obj.to_dict()
except DynamicApiError as exc:
- self.fail_json(msg="Failed to create object: {0}".format(exc.body),
- error=exc.status, status=exc.status, reason=exc.reason)
- result['changed'] = True
- result['method'] = 'create'
+ self.fail_json(
+ msg="Failed to create object: {0}".format(exc.body),
+ error=exc.status,
+ status=exc.status,
+ reason=exc.reason,
+ )
+ result["changed"] = True
+ result["method"] = "create"
return result
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_auth.py b/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_auth.py
index e5143ae4e..f28640551 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_auth.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_auth.py
@@ -1,11 +1,14 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
from ansible.module_utils._text import to_native
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes import client
@@ -18,31 +21,36 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
def __init__(self, **kwargs):
super(OpenShiftAdmPruneAuth, self).__init__(**kwargs)
- def prune_resource_binding(self, kind, api_version, ref_kind, ref_namespace_names, propagation_policy=None):
-
+ def prune_resource_binding(
+ self, kind, api_version, ref_kind, ref_namespace_names, propagation_policy=None
+ ):
resource = self.find_resource(kind=kind, api_version=api_version, fail=True)
candidates = []
for ref_namespace, ref_name in ref_namespace_names:
try:
result = resource.get(name=None, namespace=ref_namespace)
result = result.to_dict()
- result = result.get('items') if 'items' in result else [result]
+ result = result.get("items") if "items" in result else [result]
for obj in result:
- namespace = obj['metadata'].get('namespace', None)
- name = obj['metadata'].get('name')
- if ref_kind and obj['roleRef']['kind'] != ref_kind:
+ namespace = obj["metadata"].get("namespace", None)
+ name = obj["metadata"].get("name")
+ if ref_kind and obj["roleRef"]["kind"] != ref_kind:
# skip this binding as the roleRef.kind does not match
continue
- if obj['roleRef']['name'] == ref_name:
+ if obj["roleRef"]["name"] == ref_name:
# select this binding as the roleRef.name match
candidates.append((namespace, name))
except NotFoundError:
continue
except DynamicApiError as exc:
- msg = "Failed to get {kind} resource due to: {msg}".format(kind=kind, msg=exc.body)
+ msg = "Failed to get {kind} resource due to: {msg}".format(
+ kind=kind, msg=exc.body
+ )
self.fail_json(msg=msg)
except Exception as e:
- msg = "Failed to get {kind} due to: {msg}".format(kind=kind, msg=to_native(e))
+ msg = "Failed to get {kind} due to: {msg}".format(
+ kind=kind, msg=to_native(e)
+ )
self.fail_json(msg=msg)
if len(candidates) == 0 or self.check_mode:
@@ -54,24 +62,29 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
for namespace, name in candidates:
try:
- result = resource.delete(name=name, namespace=namespace, body=delete_options)
+ result = resource.delete(
+ name=name, namespace=namespace, body=delete_options
+ )
except DynamicApiError as exc:
- msg = "Failed to delete {kind} {namespace}/{name} due to: {msg}".format(kind=kind, namespace=namespace, name=name, msg=exc.body)
+ msg = "Failed to delete {kind} {namespace}/{name} due to: {msg}".format(
+ kind=kind, namespace=namespace, name=name, msg=exc.body
+ )
self.fail_json(msg=msg)
except Exception as e:
- msg = "Failed to delete {kind} {namespace}/{name} due to: {msg}".format(kind=kind, namespace=namespace, name=name, msg=to_native(e))
+ msg = "Failed to delete {kind} {namespace}/{name} due to: {msg}".format(
+ kind=kind, namespace=namespace, name=name, msg=to_native(e)
+ )
self.fail_json(msg=msg)
return [y if x is None else x + "/" + y for x, y in candidates]
def update_resource_binding(self, ref_kind, ref_names, namespaced=False):
-
- kind = 'ClusterRoleBinding'
- api_version = "rbac.authorization.k8s.io/v1",
+ kind = "ClusterRoleBinding"
+ api_version = "rbac.authorization.k8s.io/v1"
if namespaced:
kind = "RoleBinding"
resource = self.find_resource(kind=kind, api_version=api_version, fail=True)
result = resource.get(name=None, namespace=None).to_dict()
- result = result.get('items') if 'items' in result else [result]
+ result = result.get("items") if "items" in result else [result]
if len(result) == 0:
return [], False
@@ -79,29 +92,40 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
def _update_user_group(binding_namespace, subjects):
users, groups = [], []
for x in subjects:
- if x['kind'] == 'User':
- users.append(x['name'])
- elif x['kind'] == 'Group':
- groups.append(x['name'])
- elif x['kind'] == 'ServiceAccount':
+ if x["kind"] == "User":
+ users.append(x["name"])
+ elif x["kind"] == "Group":
+ groups.append(x["name"])
+ elif x["kind"] == "ServiceAccount":
namespace = binding_namespace
- if x.get('namespace') is not None:
- namespace = x.get('namespace')
+ if x.get("namespace") is not None:
+ namespace = x.get("namespace")
if namespace is not None:
- users.append("system:serviceaccount:%s:%s" % (namespace, x['name']))
+ users.append(
+ "system:serviceaccount:%s:%s" % (namespace, x["name"])
+ )
return users, groups
candidates = []
changed = False
for item in result:
- subjects = item.get('subjects', [])
- retainedSubjects = [x for x in subjects if x['kind'] == ref_kind and x['name'] in ref_names]
+ subjects = item.get("subjects", [])
+ retainedSubjects = [
+ x for x in subjects if x["kind"] == ref_kind and x["name"] in ref_names
+ ]
if len(subjects) != len(retainedSubjects):
updated_binding = item
- updated_binding['subjects'] = retainedSubjects
- binding_namespace = item['metadata'].get('namespace', None)
- updated_binding['userNames'], updated_binding['groupNames'] = _update_user_group(binding_namespace, retainedSubjects)
- candidates.append(binding_namespace + "/" + item['metadata']['name'] if binding_namespace else item['metadata']['name'])
+ updated_binding["subjects"] = retainedSubjects
+ binding_namespace = item["metadata"].get("namespace", None)
+ (
+ updated_binding["userNames"],
+ updated_binding["groupNames"],
+ ) = _update_user_group(binding_namespace, retainedSubjects)
+ candidates.append(
+ binding_namespace + "/" + item["metadata"]["name"]
+ if binding_namespace
+ else item["metadata"]["name"]
+ )
changed = True
if not self.check_mode:
try:
@@ -112,20 +136,25 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
return candidates, changed
def update_security_context(self, ref_names, key):
- params = {'kind': 'SecurityContextConstraints', 'api_version': 'security.openshift.io/v1'}
+ params = {
+ "kind": "SecurityContextConstraints",
+ "api_version": "security.openshift.io/v1",
+ }
sccs = self.kubernetes_facts(**params)
- if not sccs['api_found']:
- self.fail_json(msg=sccs['msg'])
- sccs = sccs.get('resources')
+ if not sccs["api_found"]:
+ self.fail_json(msg=sccs["msg"])
+ sccs = sccs.get("resources")
candidates = []
changed = False
- resource = self.find_resource(kind="SecurityContextConstraints", api_version="security.openshift.io/v1")
+ resource = self.find_resource(
+ kind="SecurityContextConstraints", api_version="security.openshift.io/v1"
+ )
for item in sccs:
subjects = item.get(key, [])
retainedSubjects = [x for x in subjects if x not in ref_names]
if len(subjects) != len(retainedSubjects):
- candidates.append(item['metadata']['name'])
+ candidates.append(item["metadata"]["name"])
changed = True
if not self.check_mode:
upd_sec_ctx = item
@@ -138,94 +167,116 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
return candidates, changed
def auth_prune_roles(self):
- params = {'kind': 'Role', 'api_version': 'rbac.authorization.k8s.io/v1', 'namespace': self.params.get('namespace')}
- for attr in ('name', 'label_selectors'):
+ params = {
+ "kind": "Role",
+ "api_version": "rbac.authorization.k8s.io/v1",
+ "namespace": self.params.get("namespace"),
+ }
+ for attr in ("name", "label_selectors"):
if self.params.get(attr):
params[attr] = self.params.get(attr)
result = self.kubernetes_facts(**params)
- if not result['api_found']:
- self.fail_json(msg=result['msg'])
+ if not result["api_found"]:
+ self.fail_json(msg=result["msg"])
- roles = result.get('resources')
+ roles = result.get("resources")
if len(roles) == 0:
- self.exit_json(changed=False, msg="No candidate rolebinding to prune from namespace %s." % self.params.get('namespace'))
-
- ref_roles = [(x['metadata']['namespace'], x['metadata']['name']) for x in roles]
- candidates = self.prune_resource_binding(kind="RoleBinding",
- api_version="rbac.authorization.k8s.io/v1",
- ref_kind="Role",
- ref_namespace_names=ref_roles,
- propagation_policy='Foreground')
+ self.exit_json(
+ changed=False,
+ msg="No candidate rolebinding to prune from namespace %s."
+ % self.params.get("namespace"),
+ )
+
+ ref_roles = [(x["metadata"]["namespace"], x["metadata"]["name"]) for x in roles]
+ candidates = self.prune_resource_binding(
+ kind="RoleBinding",
+ api_version="rbac.authorization.k8s.io/v1",
+ ref_kind="Role",
+ ref_namespace_names=ref_roles,
+ propagation_policy="Foreground",
+ )
if len(candidates) == 0:
self.exit_json(changed=False, role_binding=candidates)
self.exit_json(changed=True, role_binding=candidates)
def auth_prune_clusterroles(self):
- params = {'kind': 'ClusterRole', 'api_version': 'rbac.authorization.k8s.io/v1'}
- for attr in ('name', 'label_selectors'):
+ params = {"kind": "ClusterRole", "api_version": "rbac.authorization.k8s.io/v1"}
+ for attr in ("name", "label_selectors"):
if self.params.get(attr):
params[attr] = self.params.get(attr)
result = self.kubernetes_facts(**params)
- if not result['api_found']:
- self.fail_json(msg=result['msg'])
+ if not result["api_found"]:
+ self.fail_json(msg=result["msg"])
- clusterroles = result.get('resources')
+ clusterroles = result.get("resources")
if len(clusterroles) == 0:
- self.exit_json(changed=False, msg="No clusterroles found matching input criteria.")
+ self.exit_json(
+ changed=False, msg="No clusterroles found matching input criteria."
+ )
- ref_clusterroles = [(None, x['metadata']['name']) for x in clusterroles]
+ ref_clusterroles = [(None, x["metadata"]["name"]) for x in clusterroles]
# Prune ClusterRoleBinding
- candidates_cluster_binding = self.prune_resource_binding(kind="ClusterRoleBinding",
- api_version="rbac.authorization.k8s.io/v1",
- ref_kind=None,
- ref_namespace_names=ref_clusterroles)
+ candidates_cluster_binding = self.prune_resource_binding(
+ kind="ClusterRoleBinding",
+ api_version="rbac.authorization.k8s.io/v1",
+ ref_kind=None,
+ ref_namespace_names=ref_clusterroles,
+ )
# Prune Role Binding
- candidates_namespaced_binding = self.prune_resource_binding(kind="RoleBinding",
- api_version="rbac.authorization.k8s.io/v1",
- ref_kind='ClusterRole',
- ref_namespace_names=ref_clusterroles)
-
- self.exit_json(changed=True,
- cluster_role_binding=candidates_cluster_binding,
- role_binding=candidates_namespaced_binding)
+ candidates_namespaced_binding = self.prune_resource_binding(
+ kind="RoleBinding",
+ api_version="rbac.authorization.k8s.io/v1",
+ ref_kind="ClusterRole",
+ ref_namespace_names=ref_clusterroles,
+ )
+
+ self.exit_json(
+ changed=True,
+ cluster_role_binding=candidates_cluster_binding,
+ role_binding=candidates_namespaced_binding,
+ )
def list_groups(self, params=None):
- options = {'kind': 'Group', 'api_version': 'user.openshift.io/v1'}
+ options = {"kind": "Group", "api_version": "user.openshift.io/v1"}
if params:
- for attr in ('name', 'label_selectors'):
+ for attr in ("name", "label_selectors"):
if params.get(attr):
options[attr] = params.get(attr)
return self.kubernetes_facts(**options)
def auth_prune_users(self):
- params = {'kind': 'User', 'api_version': 'user.openshift.io/v1'}
- for attr in ('name', 'label_selectors'):
+ params = {"kind": "User", "api_version": "user.openshift.io/v1"}
+ for attr in ("name", "label_selectors"):
if self.params.get(attr):
params[attr] = self.params.get(attr)
users = self.kubernetes_facts(**params)
if len(users) == 0:
- self.exit_json(changed=False, msg="No resource type 'User' found matching input criteria.")
+ self.exit_json(
+ changed=False,
+ msg="No resource type 'User' found matching input criteria.",
+ )
- names = [x['metadata']['name'] for x in users]
+ names = [x["metadata"]["name"] for x in users]
changed = False
# Remove the user role binding
- rolebinding, changed_role = self.update_resource_binding(ref_kind="User",
- ref_names=names,
- namespaced=True)
+ rolebinding, changed_role = self.update_resource_binding(
+ ref_kind="User", ref_names=names, namespaced=True
+ )
changed = changed or changed_role
# Remove the user cluster role binding
- clusterrolesbinding, changed_cr = self.update_resource_binding(ref_kind="User",
- ref_names=names)
+ clusterrolesbinding, changed_cr = self.update_resource_binding(
+ ref_kind="User", ref_names=names
+ )
changed = changed or changed_cr
# Remove the user from security context constraints
- sccs, changed_sccs = self.update_security_context(names, 'users')
+ sccs, changed_sccs = self.update_security_context(names, "users")
changed = changed or changed_sccs
# Remove the user from groups
@@ -233,14 +284,14 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
deleted_groups = []
resource = self.find_resource(kind="Group", api_version="user.openshift.io/v1")
for grp in groups:
- subjects = grp.get('users', [])
+ subjects = grp.get("users", [])
retainedSubjects = [x for x in subjects if x not in names]
if len(subjects) != len(retainedSubjects):
- deleted_groups.append(grp['metadata']['name'])
+ deleted_groups.append(grp["metadata"]["name"])
changed = True
if not self.check_mode:
upd_group = grp
- upd_group.update({'users': retainedSubjects})
+ upd_group.update({"users": retainedSubjects})
try:
resource.apply(upd_group, namespace=None)
except DynamicApiError as exc:
@@ -248,62 +299,82 @@ class OpenShiftAdmPruneAuth(AnsibleOpenshiftModule):
self.fail_json(msg=msg)
# Remove the user's OAuthClientAuthorizations
- oauth = self.kubernetes_facts(kind='OAuthClientAuthorization', api_version='oauth.openshift.io/v1')
+ oauth = self.kubernetes_facts(
+ kind="OAuthClientAuthorization", api_version="oauth.openshift.io/v1"
+ )
deleted_auths = []
- resource = self.find_resource(kind="OAuthClientAuthorization", api_version="oauth.openshift.io/v1")
+ resource = self.find_resource(
+ kind="OAuthClientAuthorization", api_version="oauth.openshift.io/v1"
+ )
for authorization in oauth:
- if authorization.get('userName', None) in names:
- auth_name = authorization['metadata']['name']
+ if authorization.get("userName", None) in names:
+ auth_name = authorization["metadata"]["name"]
deleted_auths.append(auth_name)
changed = True
if not self.check_mode:
try:
- resource.delete(name=auth_name, namespace=None, body=client.V1DeleteOptions())
+ resource.delete(
+ name=auth_name,
+ namespace=None,
+ body=client.V1DeleteOptions(),
+ )
except DynamicApiError as exc:
- msg = "Failed to delete OAuthClientAuthorization {name} due to: {msg}".format(name=auth_name, msg=exc.body)
+ msg = "Failed to delete OAuthClientAuthorization {name} due to: {msg}".format(
+ name=auth_name, msg=exc.body
+ )
self.fail_json(msg=msg)
except Exception as e:
- msg = "Failed to delete OAuthClientAuthorization {name} due to: {msg}".format(name=auth_name, msg=to_native(e))
+ msg = "Failed to delete OAuthClientAuthorization {name} due to: {msg}".format(
+ name=auth_name, msg=to_native(e)
+ )
self.fail_json(msg=msg)
- self.exit_json(changed=changed,
- cluster_role_binding=clusterrolesbinding,
- role_binding=rolebinding,
- security_context_constraints=sccs,
- authorization=deleted_auths,
- group=deleted_groups)
+ self.exit_json(
+ changed=changed,
+ cluster_role_binding=clusterrolesbinding,
+ role_binding=rolebinding,
+ security_context_constraints=sccs,
+ authorization=deleted_auths,
+ group=deleted_groups,
+ )
def auth_prune_groups(self):
groups = self.list_groups(params=self.params)
if len(groups) == 0:
- self.exit_json(changed=False, result="No resource type 'Group' found matching input criteria.")
+ self.exit_json(
+ changed=False,
+ result="No resource type 'Group' found matching input criteria.",
+ )
- names = [x['metadata']['name'] for x in groups]
+ names = [x["metadata"]["name"] for x in groups]
changed = False
# Remove the groups role binding
- rolebinding, changed_role = self.update_resource_binding(ref_kind="Group",
- ref_names=names,
- namespaced=True)
+ rolebinding, changed_role = self.update_resource_binding(
+ ref_kind="Group", ref_names=names, namespaced=True
+ )
changed = changed or changed_role
# Remove the groups cluster role binding
- clusterrolesbinding, changed_cr = self.update_resource_binding(ref_kind="Group",
- ref_names=names)
+ clusterrolesbinding, changed_cr = self.update_resource_binding(
+ ref_kind="Group", ref_names=names
+ )
changed = changed or changed_cr
# Remove the groups security context constraints
- sccs, changed_sccs = self.update_security_context(names, 'groups')
+ sccs, changed_sccs = self.update_security_context(names, "groups")
changed = changed or changed_sccs
- self.exit_json(changed=changed,
- cluster_role_binding=clusterrolesbinding,
- role_binding=rolebinding,
- security_context_constraints=sccs)
+ self.exit_json(
+ changed=changed,
+ cluster_role_binding=clusterrolesbinding,
+ role_binding=rolebinding,
+ security_context_constraints=sccs,
+ )
def execute_module(self):
auth_prune = {
- 'roles': self.auth_prune_roles,
- 'clusterroles': self.auth_prune_clusterroles,
- 'users': self.auth_prune_users,
- 'groups': self.auth_prune_groups,
+ "roles": self.auth_prune_roles,
+ "clusterroles": self.auth_prune_clusterroles,
+ "users": self.auth_prune_users,
+ "groups": self.auth_prune_groups,
}
- auth_prune[self.params.get('resource')]()
+ auth_prune[self.params.get("resource")]()
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_deployments.py b/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_deployments.py
index 418922d52..315de4b10 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_deployments.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_deployments.py
@@ -1,14 +1,16 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
from datetime import datetime, timezone
-import traceback
from ansible.module_utils._text import to_native
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes import client
@@ -23,7 +25,9 @@ def get_deploymentconfig_for_replicationcontroller(replica_controller):
# This is set on replication controller pod template by deployer controller.
DeploymentConfigAnnotation = "openshift.io/deployment-config.name"
try:
- deploymentconfig_name = replica_controller['metadata']['annotations'].get(DeploymentConfigAnnotation)
+ deploymentconfig_name = replica_controller["metadata"]["annotations"].get(
+ DeploymentConfigAnnotation
+ )
if deploymentconfig_name is None or deploymentconfig_name == "":
return None
return deploymentconfig_name
@@ -32,7 +36,6 @@ def get_deploymentconfig_for_replicationcontroller(replica_controller):
class OpenShiftAdmPruneDeployment(AnsibleOpenshiftModule):
-
def __init__(self, **kwargs):
super(OpenShiftAdmPruneDeployment, self).__init__(**kwargs)
@@ -41,27 +44,33 @@ class OpenShiftAdmPruneDeployment(AnsibleOpenshiftModule):
return get_deploymentconfig_for_replicationcontroller(obj) is not None
def _zeroReplicaSize(obj):
- return obj['spec']['replicas'] == 0 and obj['status']['replicas'] == 0
+ return obj["spec"]["replicas"] == 0 and obj["status"]["replicas"] == 0
def _complete_failed(obj):
DeploymentStatusAnnotation = "openshift.io/deployment.phase"
try:
# validate that replication controller status is either 'Complete' or 'Failed'
- deployment_phase = obj['metadata']['annotations'].get(DeploymentStatusAnnotation)
- return deployment_phase in ('Failed', 'Complete')
+ deployment_phase = obj["metadata"]["annotations"].get(
+ DeploymentStatusAnnotation
+ )
+ return deployment_phase in ("Failed", "Complete")
except Exception:
return False
def _younger(obj):
- creation_timestamp = datetime.strptime(obj['metadata']['creationTimestamp'], '%Y-%m-%dT%H:%M:%SZ')
+ creation_timestamp = datetime.strptime(
+ obj["metadata"]["creationTimestamp"], "%Y-%m-%dT%H:%M:%SZ"
+ )
now = datetime.now(timezone.utc).replace(tzinfo=None)
age = (now - creation_timestamp).seconds / 60
- return age > self.params['keep_younger_than']
+ return age > self.params["keep_younger_than"]
def _orphan(obj):
try:
# verify if the deploymentconfig associated to the replication controller is still existing
- deploymentconfig_name = get_deploymentconfig_for_replicationcontroller(obj)
+ deploymentconfig_name = get_deploymentconfig_for_replicationcontroller(
+ obj
+ )
params = dict(
kind="DeploymentConfig",
api_version="apps.openshift.io/v1",
@@ -69,14 +78,14 @@ class OpenShiftAdmPruneDeployment(AnsibleOpenshiftModule):
namespace=obj["metadata"]["name"],
)
exists = self.kubernetes_facts(**params)
- return not (exists.get['api_found'] and len(exists['resources']) > 0)
+ return not (exists.get["api_found"] and len(exists["resources"]) > 0)
except Exception:
return False
predicates = [_deployment, _zeroReplicaSize, _complete_failed]
- if self.params['orphans']:
+ if self.params["orphans"]:
predicates.append(_orphan)
- if self.params['keep_younger_than']:
+ if self.params["keep_younger_than"]:
predicates.append(_younger)
results = replicacontrollers.copy()
@@ -86,8 +95,8 @@ class OpenShiftAdmPruneDeployment(AnsibleOpenshiftModule):
def execute_module(self):
# list replicationcontroller candidate for pruning
- kind = 'ReplicationController'
- api_version = 'v1'
+ kind = "ReplicationController"
+ api_version = "v1"
resource = self.find_resource(kind=kind, api_version=api_version, fail=True)
# Get ReplicationController
@@ -103,7 +112,7 @@ class OpenShiftAdmPruneDeployment(AnsibleOpenshiftModule):
self.exit_json(changed=False, replication_controllers=[])
changed = True
- delete_options = client.V1DeleteOptions(propagation_policy='Background')
+ delete_options = client.V1DeleteOptions(propagation_policy="Background")
replication_controllers = []
for replica in candidates:
try:
@@ -111,12 +120,18 @@ class OpenShiftAdmPruneDeployment(AnsibleOpenshiftModule):
if not self.check_mode:
name = replica["metadata"]["name"]
namespace = replica["metadata"]["namespace"]
- result = resource.delete(name=name, namespace=namespace, body=delete_options).to_dict()
+ result = resource.delete(
+ name=name, namespace=namespace, body=delete_options
+ ).to_dict()
replication_controllers.append(result)
except DynamicApiError as exc:
- msg = "Failed to delete ReplicationController {namespace}/{name} due to: {msg}".format(namespace=namespace, name=name, msg=exc.body)
+ msg = "Failed to delete ReplicationController {namespace}/{name} due to: {msg}".format(
+ namespace=namespace, name=name, msg=exc.body
+ )
self.fail_json(msg=msg)
except Exception as e:
- msg = "Failed to delete ReplicationController {namespace}/{name} due to: {msg}".format(namespace=namespace, name=name, msg=to_native(e))
+ msg = "Failed to delete ReplicationController {namespace}/{name} due to: {msg}".format(
+ namespace=namespace, name=name, msg=to_native(e)
+ )
self.fail_json(msg=msg)
self.exit_json(changed=changed, replication_controllers=replication_controllers)
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_images.py b/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_images.py
index 442cf9010..768c359b6 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_images.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_adm_prune_images.py
@@ -1,17 +1,19 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
from datetime import datetime, timezone, timedelta
-import traceback
import copy
from ansible.module_utils._text import to_native
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.module_utils.six import iteritems
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
from ansible_collections.community.okd.plugins.module_utils.openshift_images_common import (
OpenShiftAnalyzeImageStream,
@@ -30,7 +32,7 @@ try:
from kubernetes.dynamic.exceptions import (
DynamicApiError,
NotFoundError,
- ApiException
+ ApiException,
)
except ImportError:
pass
@@ -67,18 +69,20 @@ def determine_host_registry(module, images, image_streams):
managed_images = list(filter(_f_managed_images, images))
# Be sure to pick up the newest managed image which should have an up to date information
- sorted_images = sorted(managed_images,
- key=lambda x: x["metadata"]["creationTimestamp"],
- reverse=True)
+ sorted_images = sorted(
+ managed_images, key=lambda x: x["metadata"]["creationTimestamp"], reverse=True
+ )
docker_image_ref = ""
if len(sorted_images) > 0:
docker_image_ref = sorted_images[0].get("dockerImageReference", "")
else:
# 2nd try to get the pull spec from any image stream
# Sorting by creation timestamp may not get us up to date info. Modification time would be much
- sorted_image_streams = sorted(image_streams,
- key=lambda x: x["metadata"]["creationTimestamp"],
- reverse=True)
+ sorted_image_streams = sorted(
+ image_streams,
+ key=lambda x: x["metadata"]["creationTimestamp"],
+ reverse=True,
+ )
for i_stream in sorted_image_streams:
docker_image_ref = i_stream["status"].get("dockerImageRepository", "")
if len(docker_image_ref) > 0:
@@ -88,7 +92,7 @@ def determine_host_registry(module, images, image_streams):
module.exit_json(changed=False, result="no managed image found")
result, error = parse_docker_image_ref(docker_image_ref, module)
- return result['hostname']
+ return result["hostname"]
class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
@@ -97,7 +101,7 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
self.max_creation_timestamp = self.get_max_creation_timestamp()
self._rest_client = None
- self.registryhost = self.params.get('registry_url')
+ self.registryhost = self.params.get("registry_url")
self.changed = False
def list_objects(self):
@@ -107,9 +111,9 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
if self.params.get("namespace") and kind.lower() == "imagestream":
namespace = self.params.get("namespace")
try:
- result[kind] = self.kubernetes_facts(kind=kind,
- api_version=version,
- namespace=namespace).get('resources')
+ result[kind] = self.kubernetes_facts(
+ kind=kind, api_version=version, namespace=namespace
+ ).get("resources")
except DynamicApiError as e:
self.fail_json(
msg="An error occurred while trying to list objects.",
@@ -119,7 +123,7 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
except Exception as e:
self.fail_json(
msg="An error occurred while trying to list objects.",
- error=to_native(e)
+ error=to_native(e),
)
return result
@@ -134,8 +138,8 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
def rest_client(self):
if not self._rest_client:
configuration = copy.deepcopy(self.client.configuration)
- validate_certs = self.params.get('registry_validate_certs')
- ssl_ca_cert = self.params.get('registry_ca_cert')
+ validate_certs = self.params.get("registry_validate_certs")
+ ssl_ca_cert = self.params.get("registry_ca_cert")
if validate_certs is not None:
configuration.verify_ssl = validate_certs
if ssl_ca_cert is not None:
@@ -146,7 +150,9 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
def delete_from_registry(self, url):
try:
- response = self.rest_client.DELETE(url=url, headers=self.client.configuration.api_key)
+ response = self.rest_client.DELETE(
+ url=url, headers=self.client.configuration.api_key
+ )
if response.status == 404:
# Unable to delete layer
return None
@@ -156,8 +162,9 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
if response.status != 202 and response.status != 204:
self.fail_json(
msg="Delete URL {0}: Unexpected status code in response: {1}".format(
- response.status, url),
- reason=response.reason
+ response.status, url
+ ),
+ reason=response.reason,
)
return None
except ApiException as e:
@@ -204,9 +211,7 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
result = self.request(
"PUT",
"/apis/{api_version}/namespaces/{namespace}/imagestreams/{name}/status".format(
- api_version=api_version,
- namespace=namespace,
- name=name
+ api_version=api_version, namespace=namespace, name=name
),
body=definition,
content_type="application/json",
@@ -237,11 +242,10 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
pass
except DynamicApiError as exc:
self.fail_json(
- msg="Failed to delete object %s/%s due to: %s" % (
- kind, name, exc.body
- ),
+ msg="Failed to delete object %s/%s due to: %s"
+ % (kind, name, exc.body),
reason=exc.reason,
- status=exc.status
+ status=exc.status,
)
else:
existing = resource.get(name=name)
@@ -285,9 +289,11 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
continue
if idx == 0:
- istag = "%s/%s:%s" % (stream_namespace,
- stream_name,
- tag_event_list["tag"])
+ istag = "%s/%s:%s" % (
+ stream_namespace,
+ stream_name,
+ tag_event_list["tag"],
+ )
if istag in self.used_tags:
# keeping because tag is used
filtered_items.append(item)
@@ -302,20 +308,20 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
image = self.image_mapping[item["image"]]
# check prune over limit size
- if prune_over_size_limit and not self.exceeds_limits(stream_namespace, image):
+ if prune_over_size_limit and not self.exceeds_limits(
+ stream_namespace, image
+ ):
filtered_items.append(item)
continue
- image_ref = "%s/%s@%s" % (stream_namespace,
- stream_name,
- item["image"])
+ image_ref = "%s/%s@%s" % (stream_namespace, stream_name, item["image"])
if image_ref in self.used_images:
# keeping because tag is used
filtered_items.append(item)
continue
images_to_delete.append(item["image"])
- if self.params.get('prune_registry'):
+ if self.params.get("prune_registry"):
manifests_to_delete.append(image["metadata"]["name"])
path = stream_namespace + "/" + stream_name
image_blobs, err = get_image_blobs(image)
@@ -325,21 +331,25 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
return filtered_items, manifests_to_delete, images_to_delete
def prune_image_streams(self, stream):
- name = stream['metadata']['namespace'] + "/" + stream['metadata']['name']
+ name = stream["metadata"]["namespace"] + "/" + stream["metadata"]["name"]
if is_too_young_object(stream, self.max_creation_timestamp):
# keeping all images because of image stream too young
return None, []
- facts = self.kubernetes_facts(kind="ImageStream",
- api_version=ApiConfiguration.get("ImageStream"),
- name=stream["metadata"]["name"],
- namespace=stream["metadata"]["namespace"])
- image_stream = facts.get('resources')
+ facts = self.kubernetes_facts(
+ kind="ImageStream",
+ api_version=ApiConfiguration.get("ImageStream"),
+ name=stream["metadata"]["name"],
+ namespace=stream["metadata"]["namespace"],
+ )
+ image_stream = facts.get("resources")
if len(image_stream) != 1:
# skipping because it does not exist anymore
return None, []
stream = image_stream[0]
namespace = self.params.get("namespace")
- stream_to_update = not namespace or (stream["metadata"]["namespace"] == namespace)
+ stream_to_update = not namespace or (
+ stream["metadata"]["namespace"] == namespace
+ )
manifests_to_delete, images_to_delete = [], []
deleted_items = False
@@ -351,9 +361,9 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
(
filtered_tag_event,
tag_manifests_to_delete,
- tag_images_to_delete
+ tag_images_to_delete,
) = self.prune_image_stream_tag(stream, tag_event_list)
- stream['status']['tags'][idx]['items'] = filtered_tag_event
+ stream["status"]["tags"][idx]["items"] = filtered_tag_event
manifests_to_delete += tag_manifests_to_delete
images_to_delete += tag_images_to_delete
deleted_items = deleted_items or (len(tag_images_to_delete) > 0)
@@ -361,11 +371,11 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
# Deleting tags without items
tags = []
for tag in stream["status"].get("tags", []):
- if tag['items'] is None or len(tag['items']) == 0:
+ if tag["items"] is None or len(tag["items"]) == 0:
continue
tags.append(tag)
- stream['status']['tags'] = tags
+ stream["status"]["tags"] = tags
result = None
# Update ImageStream
if stream_to_update:
@@ -402,19 +412,23 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
def execute_module(self):
resources = self.list_objects()
- if not self.check_mode and self.params.get('prune_registry'):
+ if not self.check_mode and self.params.get("prune_registry"):
if not self.registryhost:
- self.registryhost = determine_host_registry(self.module, resources['Image'], resources['ImageStream'])
+ self.registryhost = determine_host_registry(
+ self.module, resources["Image"], resources["ImageStream"]
+ )
# validate that host has a scheme
if "://" not in self.registryhost:
self.registryhost = "https://" + self.registryhost
# Analyze Image Streams
analyze_ref = OpenShiftAnalyzeImageStream(
- ignore_invalid_refs=self.params.get('ignore_invalid_refs'),
+ ignore_invalid_refs=self.params.get("ignore_invalid_refs"),
max_creation_timestamp=self.max_creation_timestamp,
- module=self.module
+ module=self.module,
+ )
+ self.used_tags, self.used_images, error = analyze_ref.analyze_image_stream(
+ resources
)
- self.used_tags, self.used_images, error = analyze_ref.analyze_image_stream(resources)
if error:
self.fail_json(msg=error)
@@ -435,16 +449,20 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
updated_image_streams = []
deleted_tags_images = []
updated_is_mapping = {}
- for stream in resources['ImageStream']:
+ for stream in resources["ImageStream"]:
result, images_to_delete = self.prune_image_streams(stream)
if result:
- updated_is_mapping[result["metadata"]["namespace"] + "/" + result["metadata"]["name"]] = result
+ updated_is_mapping[
+ result["metadata"]["namespace"] + "/" + result["metadata"]["name"]
+ ] = result
updated_image_streams.append(result)
deleted_tags_images += images_to_delete
# Create a list with images referenced on image stream
self.referenced_images = []
- for item in self.kubernetes_facts(kind="ImageStream", api_version="image.openshift.io/v1")["resources"]:
+ for item in self.kubernetes_facts(
+ kind="ImageStream", api_version="image.openshift.io/v1"
+ )["resources"]:
name = "%s/%s" % (item["metadata"]["namespace"], item["metadata"]["name"])
if name in updated_is_mapping:
item = updated_is_mapping[name]
@@ -453,7 +471,7 @@ class OpenShiftAdmPruneImages(AnsibleOpenshiftModule):
# Stage 2: delete images
images = []
- images_to_delete = [x["metadata"]["name"] for x in resources['Image']]
+ images_to_delete = [x["metadata"]["name"] for x in resources["Image"]]
if self.params.get("namespace") is not None:
# When namespace is defined, prune only images that were referenced by ImageStream
# from the corresponding namespace
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_builds.py b/ansible_collections/community/okd/plugins/module_utils/openshift_builds.py
index 02e60fd2a..51ebfc281 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_builds.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_builds.py
@@ -1,15 +1,17 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
from datetime import datetime, timezone, timedelta
-import traceback
import time
from ansible.module_utils._text import to_native
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes.dynamic.exceptions import DynamicApiError
@@ -36,8 +38,7 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
result = self.request(
method="POST",
path="/apis/build.openshift.io/v1/namespaces/{namespace}/builds/{name}/clone".format(
- namespace=namespace,
- name=name
+ namespace=namespace, name=name
),
body=request,
content_type="application/json",
@@ -47,7 +48,11 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
msg = "Failed to clone Build %s/%s due to: %s" % (namespace, name, exc.body)
self.fail_json(msg=msg, status=exc.status, reason=exc.reason)
except Exception as e:
- msg = "Failed to clone Build %s/%s due to: %s" % (namespace, name, to_native(e))
+ msg = "Failed to clone Build %s/%s due to: %s" % (
+ namespace,
+ name,
+ to_native(e),
+ )
self.fail_json(msg=msg, error=to_native(e), exception=e)
def instantiate_build_config(self, name, namespace, request):
@@ -55,22 +60,28 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
result = self.request(
method="POST",
path="/apis/build.openshift.io/v1/namespaces/{namespace}/buildconfigs/{name}/instantiate".format(
- namespace=namespace,
- name=name
+ namespace=namespace, name=name
),
body=request,
content_type="application/json",
)
return result.to_dict()
except DynamicApiError as exc:
- msg = "Failed to instantiate BuildConfig %s/%s due to: %s" % (namespace, name, exc.body)
+ msg = "Failed to instantiate BuildConfig %s/%s due to: %s" % (
+ namespace,
+ name,
+ exc.body,
+ )
self.fail_json(msg=msg, status=exc.status, reason=exc.reason)
except Exception as e:
- msg = "Failed to instantiate BuildConfig %s/%s due to: %s" % (namespace, name, to_native(e))
+ msg = "Failed to instantiate BuildConfig %s/%s due to: %s" % (
+ namespace,
+ name,
+ to_native(e),
+ )
self.fail_json(msg=msg, error=to_native(e), exception=e)
def start_build(self):
-
result = None
name = self.params.get("build_config_name")
if not name:
@@ -79,32 +90,20 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
build_request = {
"kind": "BuildRequest",
"apiVersion": "build.openshift.io/v1",
- "metadata": {
- "name": name
- },
- "triggeredBy": [
- {"message": "Manually triggered"}
- ],
+ "metadata": {"name": name},
+ "triggeredBy": [{"message": "Manually triggered"}],
}
# Overrides incremental
incremental = self.params.get("incremental")
if incremental is not None:
build_request.update(
- {
- "sourceStrategyOptions": {
- "incremental": incremental
- }
- }
+ {"sourceStrategyOptions": {"incremental": incremental}}
)
# Environment variable
if self.params.get("env_vars"):
- build_request.update(
- {
- "env": self.params.get("env_vars")
- }
- )
+ build_request.update({"env": self.params.get("env_vars")})
# Docker strategy option
if self.params.get("build_args"):
@@ -121,22 +120,14 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
if no_cache is not None:
build_request.update(
{
- "dockerStrategyOptions": {
- "noCache": no_cache
- },
+ "dockerStrategyOptions": {"noCache": no_cache},
}
)
# commit
if self.params.get("commit"):
build_request.update(
- {
- "revision": {
- "git": {
- "commit": self.params.get("commit")
- }
- }
- }
+ {"revision": {"git": {"commit": self.params.get("commit")}}}
)
if self.params.get("build_config_name"):
@@ -144,7 +135,7 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
result = self.instantiate_build_config(
name=self.params.get("build_config_name"),
namespace=self.params.get("namespace"),
- request=build_request
+ request=build_request,
)
else:
@@ -152,7 +143,7 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
result = self.clone_build(
name=self.params.get("build_name"),
namespace=self.params.get("namespace"),
- request=build_request
+ request=build_request,
)
if result and self.params.get("wait"):
@@ -179,10 +170,11 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
break
elif last_status_phase in ("Cancelled", "Error", "Failed"):
self.fail_json(
- msg="Unexpected status for Build %s/%s: %s" % (
+ msg="Unexpected status for Build %s/%s: %s"
+ % (
result["metadata"]["name"],
result["metadata"]["namespace"],
- last_status_phase
+ last_status_phase,
)
)
time.sleep(wait_sleep)
@@ -190,8 +182,11 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
if last_status_phase != "Complete":
name = result["metadata"]["name"]
namespace = result["metadata"]["namespace"]
- msg = "Build %s/%s has not complete after %d second(s)," \
- "current status is %s" % (namespace, name, wait_timeout, last_status_phase)
+ msg = (
+ "Build %s/%s has not complete after %d second(s),"
+ "current status is %s"
+ % (namespace, name, wait_timeout, last_status_phase)
+ )
self.fail_json(msg=msg)
@@ -199,9 +194,8 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
self.exit_json(changed=True, builds=result)
def cancel_build(self, restart):
-
- kind = 'Build'
- api_version = 'build.openshift.io/v1'
+ kind = "Build"
+ api_version = "build.openshift.io/v1"
namespace = self.params.get("namespace")
phases = ["new", "pending", "running"]
@@ -215,16 +209,18 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
else:
build_config = self.params.get("build_config_name")
# list all builds from namespace
- params = dict(
- kind=kind,
- api_version=api_version,
- namespace=namespace
- )
+ params = dict(kind=kind, api_version=api_version, namespace=namespace)
resources = self.kubernetes_facts(**params).get("resources", [])
def _filter_builds(build):
- config = build["metadata"].get("labels", {}).get("openshift.io/build-config.name")
- return build_config is None or (build_config is not None and config in build_config)
+ config = (
+ build["metadata"]
+ .get("labels", {})
+ .get("openshift.io/build-config.name")
+ )
+ return build_config is None or (
+ build_config is not None and config in build_config
+ )
for item in list(filter(_filter_builds, resources)):
name = item["metadata"]["name"]
@@ -232,16 +228,15 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
names.append(name)
if len(names) == 0:
- self.exit_json(changed=False, msg="No Build found from namespace %s" % namespace)
+ self.exit_json(
+ changed=False, msg="No Build found from namespace %s" % namespace
+ )
warning = []
builds_to_cancel = []
for name in names:
params = dict(
- kind=kind,
- api_version=api_version,
- name=name,
- namespace=namespace
+ kind=kind, api_version=api_version, name=name, namespace=namespace
)
resource = self.kubernetes_facts(**params).get("resources", [])
@@ -256,7 +251,10 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
if phase in phases:
builds_to_cancel.append(resource)
else:
- warning.append("build %s/%s is not in expected phase, found %s" % (namespace, name, phase))
+ warning.append(
+ "build %s/%s is not in expected phase, found %s"
+ % (namespace, name, phase)
+ )
changed = False
result = []
@@ -278,9 +276,10 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
result.append(cancelled_build)
except DynamicApiError as exc:
self.fail_json(
- msg="Failed to cancel Build %s/%s due to: %s" % (namespace, name, exc),
+ msg="Failed to cancel Build %s/%s due to: %s"
+ % (namespace, name, exc),
reason=exc.reason,
- status=exc.status
+ status=exc.status,
)
except Exception as e:
self.fail_json(
@@ -294,10 +293,7 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
name = build["metadata"]["name"]
while (datetime.now() - start).seconds < wait_timeout:
params = dict(
- kind=kind,
- api_version=api_version,
- name=name,
- namespace=namespace
+ kind=kind, api_version=api_version, name=name, namespace=namespace
)
resource = self.kubernetes_facts(**params).get("resources", [])
if len(resource) == 0:
@@ -307,7 +303,11 @@ class OpenShiftBuilds(AnsibleOpenshiftModule):
if last_phase == "Cancelled":
return resource, None
time.sleep(wait_sleep)
- return None, "Build %s/%s is not cancelled as expected, current state is %s" % (namespace, name, last_phase)
+ return (
+ None,
+ "Build %s/%s is not cancelled as expected, current state is %s"
+ % (namespace, name, last_phase),
+ )
if result and self.params.get("wait"):
wait_timeout = self.params.get("wait_timeout")
@@ -341,8 +341,8 @@ class OpenShiftPruneBuilds(OpenShiftBuilds):
def execute_module(self):
# list replicationcontroller candidate for pruning
- kind = 'Build'
- api_version = 'build.openshift.io/v1'
+ kind = "Build"
+ api_version = "build.openshift.io/v1"
resource = self.find_resource(kind=kind, api_version=api_version, fail=True)
self.max_creation_timestamp = None
@@ -352,7 +352,12 @@ class OpenShiftPruneBuilds(OpenShiftBuilds):
self.max_creation_timestamp = now - timedelta(minutes=keep_younger_than)
def _prunable_build(build):
- return build["status"]["phase"] in ("Complete", "Failed", "Error", "Cancelled")
+ return build["status"]["phase"] in (
+ "Complete",
+ "Failed",
+ "Error",
+ "Cancelled",
+ )
def _orphan_build(build):
if not _prunable_build(build):
@@ -367,7 +372,9 @@ class OpenShiftPruneBuilds(OpenShiftBuilds):
def _younger_build(build):
if not self.max_creation_timestamp:
return False
- creation_timestamp = datetime.strptime(build['metadata']['creationTimestamp'], '%Y-%m-%dT%H:%M:%SZ')
+ creation_timestamp = datetime.strptime(
+ build["metadata"]["creationTimestamp"], "%Y-%m-%dT%H:%M:%SZ"
+ )
return creation_timestamp < self.max_creation_timestamp
predicates = [
@@ -401,9 +408,17 @@ class OpenShiftPruneBuilds(OpenShiftBuilds):
namespace = build["metadata"]["namespace"]
resource.delete(name=name, namespace=namespace, body={})
except DynamicApiError as exc:
- msg = "Failed to delete Build %s/%s due to: %s" % (namespace, name, exc.body)
+ msg = "Failed to delete Build %s/%s due to: %s" % (
+ namespace,
+ name,
+ exc.body,
+ )
self.fail_json(msg=msg, status=exc.status, reason=exc.reason)
except Exception as e:
- msg = "Failed to delete Build %s/%s due to: %s" % (namespace, name, to_native(e))
+ msg = "Failed to delete Build %s/%s due to: %s" % (
+ namespace,
+ name,
+ to_native(e),
+ )
self.fail_json(msg=msg, error=to_native(e), exception=e)
self.exit_json(changed=changed, builds=candidates)
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_common.py b/ansible_collections/community/okd/plugins/module_utils/openshift_common.py
index a1318f9a5..b818b7a7b 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_common.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_common.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
import traceback
@@ -9,8 +10,12 @@ from abc import abstractmethod
from ansible.module_utils._text import to_native
try:
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import get_api_client
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.core import AnsibleK8SModule
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
+ get_api_client,
+ )
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.core import (
+ AnsibleK8SModule,
+ )
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
K8sService,
diff_objects,
@@ -24,7 +29,10 @@ try:
merge_params,
flatten_list_kind,
)
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import CoreException
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import (
+ CoreException,
+ )
+
HAS_KUBERNETES_COLLECTION = True
k8s_collection_import_exception = None
K8S_COLLECTION_ERROR = None
@@ -35,7 +43,6 @@ except ImportError as e:
class AnsibleOpenshiftModule(AnsibleK8SModule):
-
def __init__(self, **kwargs):
super(AnsibleOpenshiftModule, self).__init__(**kwargs)
@@ -86,7 +93,6 @@ class AnsibleOpenshiftModule(AnsibleK8SModule):
return diff_objects(existing, new)
def run_module(self):
-
try:
self.execute_module()
except CoreException as e:
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_docker_image.py b/ansible_collections/community/okd/plugins/module_utils/openshift_docker_image.py
index 27dbe6cc7..160c5b50b 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_docker_image.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_docker_image.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
import re
@@ -23,62 +24,68 @@ def convert_storage_to_bytes(value):
def is_valid_digest(digest):
-
digest_algorithm_size = dict(
- sha256=64, sha384=96, sha512=128,
+ sha256=64,
+ sha384=96,
+ sha512=128,
)
- m = re.match(r'[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+', digest)
+ m = re.match(r"[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+", digest)
if not m:
return "Docker digest does not match expected format %s" % digest
- idx = digest.find(':')
+ idx = digest.find(":")
# case: "sha256:" with no hex.
if idx < 0 or idx == (len(digest) - 1):
return "Invalid docker digest %s, no hex value define" % digest
algorithm = digest[:idx]
if algorithm not in digest_algorithm_size:
- return "Unsupported digest algorithm value %s for digest %s" % (algorithm, digest)
+ return "Unsupported digest algorithm value %s for digest %s" % (
+ algorithm,
+ digest,
+ )
- hex_value = digest[idx + 1:]
+ hex_value = digest[idx + 1:] # fmt: skip
if len(hex_value) != digest_algorithm_size.get(algorithm):
return "Invalid length for digest hex expected %d found %d (digest is %s)" % (
- digest_algorithm_size.get(algorithm), len(hex_value), digest
+ digest_algorithm_size.get(algorithm),
+ len(hex_value),
+ digest,
)
def parse_docker_image_ref(image_ref, module=None):
"""
- Docker Grammar Reference
- Reference => name [ ":" tag ] [ "@" digest ]
- name => [hostname '/'] component ['/' component]*
- hostname => hostcomponent ['.' hostcomponent]* [':' port-number]
- hostcomponent => /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
- port-number => /[0-9]+/
- component => alpha-numeric [separator alpha-numeric]*
- alpha-numeric => /[a-z0-9]+/
- separator => /[_.]|__|[-]*/
+ Docker Grammar Reference
+ Reference => name [ ":" tag ] [ "@" digest ]
+ name => [hostname '/'] component ['/' component]*
+ hostname => hostcomponent ['.' hostcomponent]* [':' port-number]
+ hostcomponent => /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
+ port-number => /[0-9]+/
+ component => alpha-numeric [separator alpha-numeric]*
+ alpha-numeric => /[a-z0-9]+/
+ separator => /[_.]|__|[-]*/
"""
idx = image_ref.find("/")
def _contains_any(src, values):
return any(x in src for x in values)
- result = {
- "tag": None, "digest": None
- }
+ result = {"tag": None, "digest": None}
default_domain = "docker.io"
- if idx < 0 or (not _contains_any(image_ref[:idx], ":.") and image_ref[:idx] != "localhost"):
+ if idx < 0 or (
+ not _contains_any(image_ref[:idx], ":.") and image_ref[:idx] != "localhost"
+ ):
result["hostname"], remainder = default_domain, image_ref
else:
- result["hostname"], remainder = image_ref[:idx], image_ref[idx + 1:]
+ result["hostname"], remainder = image_ref[:idx], image_ref[idx + 1:] # fmt: skip
# Parse remainder information
idx = remainder.find("@")
if idx > 0 and len(remainder) > (idx + 1):
# docker image reference with digest
- component, result["digest"] = remainder[:idx], remainder[idx + 1:]
+ component, result["digest"] = remainder[:idx], remainder[idx + 1:] # fmt: skip
err = is_valid_digest(result["digest"])
if err:
if module:
@@ -88,7 +95,7 @@ def parse_docker_image_ref(image_ref, module=None):
idx = remainder.find(":")
if idx > 0 and len(remainder) > (idx + 1):
# docker image reference with tag
- component, result["tag"] = remainder[:idx], remainder[idx + 1:]
+ component, result["tag"] = remainder[:idx], remainder[idx + 1:] # fmt: skip
else:
# name only
component = remainder
@@ -96,8 +103,6 @@ def parse_docker_image_ref(image_ref, module=None):
namespace = None
if len(v) > 1:
namespace = v[0]
- result.update({
- "namespace": namespace, "name": v[-1]
- })
+ result.update({"namespace": namespace, "name": v[-1]})
return result, None
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_groups.py b/ansible_collections/community/okd/plugins/module_utils/openshift_groups.py
index 5d1aaadc1..473a14f7e 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_groups.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_groups.py
@@ -3,11 +3,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-import traceback
from datetime import datetime
from ansible.module_utils.parsing.convert_bool import boolean
@@ -19,18 +19,21 @@ from ansible_collections.community.okd.plugins.module_utils.openshift_ldap impor
ldap_split_host_port,
OpenshiftLDAPRFC2307,
OpenshiftLDAPActiveDirectory,
- OpenshiftLDAPAugmentedActiveDirectory
+ OpenshiftLDAPAugmentedActiveDirectory,
)
try:
import ldap
+
HAS_PYTHON_LDAP = True
PYTHON_LDAP_ERROR = None
except ImportError as e:
HAS_PYTHON_LDAP = False
PYTHON_LDAP_ERROR = e
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes.dynamic.exceptions import DynamicApiError
@@ -44,7 +47,9 @@ LDAP_OPENSHIFT_UID_ANNOTATION = "openshift.io/ldap.uid"
LDAP_OPENSHIFT_SYNCTIME_ANNOTATION = "openshift.io/ldap.sync-time"
-def connect_to_ldap(module, server_uri, bind_dn=None, bind_pw=None, insecure=True, ca_file=None):
+def connect_to_ldap(
+ module, server_uri, bind_dn=None, bind_pw=None, insecure=True, ca_file=None
+):
if insecure:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
elif ca_file:
@@ -56,27 +61,36 @@ def connect_to_ldap(module, server_uri, bind_dn=None, bind_pw=None, insecure=Tru
connection.simple_bind_s(bind_dn, bind_pw)
return connection
except ldap.LDAPError as e:
- module.fail_json(msg="Cannot bind to the LDAP server '{0}' due to: {1}".format(server_uri, e))
+ module.fail_json(
+ msg="Cannot bind to the LDAP server '{0}' due to: {1}".format(server_uri, e)
+ )
def validate_group_annotation(definition, host_ip):
- name = definition['metadata']['name']
+ name = definition["metadata"]["name"]
# Validate LDAP URL Annotation
- annotate_url = definition['metadata'].get('annotations', {}).get(LDAP_OPENSHIFT_URL_ANNOTATION)
+ annotate_url = (
+ definition["metadata"].get("annotations", {}).get(LDAP_OPENSHIFT_URL_ANNOTATION)
+ )
if host_ip:
if not annotate_url:
- return "group '{0}' marked as having been synced did not have an '{1}' annotation".format(name, LDAP_OPENSHIFT_URL_ANNOTATION)
+ return "group '{0}' marked as having been synced did not have an '{1}' annotation".format(
+ name, LDAP_OPENSHIFT_URL_ANNOTATION
+ )
elif annotate_url != host_ip:
return "group '{0}' was not synchronized from: '{1}'".format(name, host_ip)
# Validate LDAP UID Annotation
- annotate_uid = definition['metadata']['annotations'].get(LDAP_OPENSHIFT_UID_ANNOTATION)
+ annotate_uid = definition["metadata"]["annotations"].get(
+ LDAP_OPENSHIFT_UID_ANNOTATION
+ )
if not annotate_uid:
- return "group '{0}' marked as having been synced did not have an '{1}' annotation".format(name, LDAP_OPENSHIFT_UID_ANNOTATION)
+ return "group '{0}' marked as having been synced did not have an '{1}' annotation".format(
+ name, LDAP_OPENSHIFT_UID_ANNOTATION
+ )
return None
class OpenshiftLDAPGroups(object):
-
kind = "Group"
version = "user.openshift.io/v1"
@@ -88,11 +102,7 @@ class OpenshiftLDAPGroups(object):
@property
def k8s_group_api(self):
if not self.__group_api:
- params = dict(
- kind=self.kind,
- api_version=self.version,
- fail=True
- )
+ params = dict(kind=self.kind, api_version=self.version, fail=True)
self.__group_api = self.module.find_resource(**params)
return self.__group_api
@@ -139,16 +149,26 @@ class OpenshiftLDAPGroups(object):
if missing:
self.module.fail_json(
- msg="The following groups were not found: %s" % ''.join(missing)
+ msg="The following groups were not found: %s" % "".join(missing)
)
else:
label_selector = "%s=%s" % (LDAP_OPENSHIFT_HOST_LABEL, host)
- resources = self.get_group_info(label_selectors=[label_selector], return_list=True)
+ resources = self.get_group_info(
+ label_selectors=[label_selector], return_list=True
+ )
if not resources:
- return None, "Unable to find Group matching label selector '%s'" % label_selector
+ return (
+ None,
+ "Unable to find Group matching label selector '%s'"
+ % label_selector,
+ )
groups = resources
if deny_groups:
- groups = [item for item in groups if item["metadata"]["name"] not in deny_groups]
+ groups = [
+ item
+ for item in groups
+ if item["metadata"]["name"] not in deny_groups
+ ]
uids = []
for grp in groups:
@@ -156,7 +176,9 @@ class OpenshiftLDAPGroups(object):
if err and allow_groups:
# We raise an error for group part of the allow_group not matching LDAP sync criteria
return None, err
- group_uid = grp['metadata']['annotations'].get(LDAP_OPENSHIFT_UID_ANNOTATION)
+ group_uid = grp["metadata"]["annotations"].get(
+ LDAP_OPENSHIFT_UID_ANNOTATION
+ )
self.cache[group_uid] = grp
uids.append(group_uid)
return uids, None
@@ -174,38 +196,65 @@ class OpenshiftLDAPGroups(object):
"kind": "Group",
"metadata": {
"name": group_name,
- "labels": {
- LDAP_OPENSHIFT_HOST_LABEL: self.module.host
- },
+ "labels": {LDAP_OPENSHIFT_HOST_LABEL: self.module.host},
"annotations": {
LDAP_OPENSHIFT_URL_ANNOTATION: self.module.netlocation,
LDAP_OPENSHIFT_UID_ANNOTATION: group_uid,
- }
- }
+ },
+ },
}
# Make sure we aren't taking over an OpenShift group that is already related to a different LDAP group
- ldaphost_label = group["metadata"].get("labels", {}).get(LDAP_OPENSHIFT_HOST_LABEL)
+ ldaphost_label = (
+ group["metadata"].get("labels", {}).get(LDAP_OPENSHIFT_HOST_LABEL)
+ )
if not ldaphost_label or ldaphost_label != self.module.host:
- return None, "Group %s: %s label did not match sync host: wanted %s, got %s" % (
- group_name, LDAP_OPENSHIFT_HOST_LABEL, self.module.host, ldaphost_label
+ return (
+ None,
+ "Group %s: %s label did not match sync host: wanted %s, got %s"
+ % (
+ group_name,
+ LDAP_OPENSHIFT_HOST_LABEL,
+ self.module.host,
+ ldaphost_label,
+ ),
)
- ldapurl_annotation = group["metadata"].get("annotations", {}).get(LDAP_OPENSHIFT_URL_ANNOTATION)
+ ldapurl_annotation = (
+ group["metadata"].get("annotations", {}).get(LDAP_OPENSHIFT_URL_ANNOTATION)
+ )
if not ldapurl_annotation or ldapurl_annotation != self.module.netlocation:
- return None, "Group %s: %s annotation did not match sync host: wanted %s, got %s" % (
- group_name, LDAP_OPENSHIFT_URL_ANNOTATION, self.module.netlocation, ldapurl_annotation
+ return (
+ None,
+ "Group %s: %s annotation did not match sync host: wanted %s, got %s"
+ % (
+ group_name,
+ LDAP_OPENSHIFT_URL_ANNOTATION,
+ self.module.netlocation,
+ ldapurl_annotation,
+ ),
)
- ldapuid_annotation = group["metadata"].get("annotations", {}).get(LDAP_OPENSHIFT_UID_ANNOTATION)
+ ldapuid_annotation = (
+ group["metadata"].get("annotations", {}).get(LDAP_OPENSHIFT_UID_ANNOTATION)
+ )
if not ldapuid_annotation or ldapuid_annotation != group_uid:
- return None, "Group %s: %s annotation did not match LDAP UID: wanted %s, got %s" % (
- group_name, LDAP_OPENSHIFT_UID_ANNOTATION, group_uid, ldapuid_annotation
+ return (
+ None,
+ "Group %s: %s annotation did not match LDAP UID: wanted %s, got %s"
+ % (
+ group_name,
+ LDAP_OPENSHIFT_UID_ANNOTATION,
+ group_uid,
+ ldapuid_annotation,
+ ),
)
# Overwrite Group Users data
group["users"] = usernames
- group["metadata"]["annotations"][LDAP_OPENSHIFT_SYNCTIME_ANNOTATION] = datetime.now().isoformat()
+ group["metadata"]["annotations"][
+ LDAP_OPENSHIFT_SYNCTIME_ANNOTATION
+ ] = datetime.now().isoformat()
return group, None
def create_openshift_groups(self, groups: list):
@@ -223,9 +272,15 @@ class OpenshiftLDAPGroups(object):
else:
definition = self.k8s_group_api.create(definition).to_dict()
except DynamicApiError as exc:
- self.module.fail_json(msg="Failed to %s Group '%s' due to: %s" % (method, name, exc.body))
+ self.module.fail_json(
+ msg="Failed to %s Group '%s' due to: %s"
+ % (method, name, exc.body)
+ )
except Exception as exc:
- self.module.fail_json(msg="Failed to %s Group '%s' due to: %s" % (method, name, to_native(exc)))
+ self.module.fail_json(
+ msg="Failed to %s Group '%s' due to: %s"
+ % (method, name, to_native(exc))
+ )
equals = False
if existing:
equals, diff = self.module.diff_objects(existing, definition)
@@ -235,27 +290,27 @@ class OpenshiftLDAPGroups(object):
return results, diffs, changed
def delete_openshift_group(self, name: str):
- result = dict(
- kind=self.kind,
- apiVersion=self.version,
- metadata=dict(
- name=name
- )
- )
+ result = dict(kind=self.kind, apiVersion=self.version, metadata=dict(name=name))
if not self.module.check_mode:
try:
result = self.k8s_group_api.delete(name=name).to_dict()
except DynamicApiError as exc:
- self.module.fail_json(msg="Failed to delete Group '{0}' due to: {1}".format(name, exc.body))
+ self.module.fail_json(
+ msg="Failed to delete Group '{0}' due to: {1}".format(
+ name, exc.body
+ )
+ )
except Exception as exc:
- self.module.fail_json(msg="Failed to delete Group '{0}' due to: {1}".format(name, to_native(exc)))
+ self.module.fail_json(
+ msg="Failed to delete Group '{0}' due to: {1}".format(
+ name, to_native(exc)
+ )
+ )
return result
class OpenshiftGroupsSync(AnsibleOpenshiftModule):
-
def __init__(self, **kwargs):
-
super(OpenshiftGroupsSync, self).__init__(**kwargs)
self.__k8s_group_api = None
self.__ldap_connection = None
@@ -267,17 +322,14 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
if not HAS_PYTHON_LDAP:
self.fail_json(
- msg=missing_required_lib('python-ldap'), error=to_native(PYTHON_LDAP_ERROR)
+ msg=missing_required_lib("python-ldap"),
+ error=to_native(PYTHON_LDAP_ERROR),
)
@property
def k8s_group_api(self):
if not self.__k8s_group_api:
- params = dict(
- kind="Group",
- api_version="user.openshift.io/v1",
- fail=True
- )
+ params = dict(kind="Group", api_version="user.openshift.io/v1", fail=True)
self.__k8s_group_api = self.find_resource(**params)
return self.__k8s_group_api
@@ -291,11 +343,11 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
# Create connection object
params = dict(
module=self,
- server_uri=self.config.get('url'),
- bind_dn=self.config.get('bindDN'),
- bind_pw=self.config.get('bindPassword'),
- insecure=boolean(self.config.get('insecure')),
- ca_file=self.config.get('ca')
+ server_uri=self.config.get("url"),
+ bind_dn=self.config.get("bindDN"),
+ bind_pw=self.config.get("bindPassword"),
+ insecure=boolean(self.config.get("insecure")),
+ ca_file=self.config.get("ca"),
)
self.__ldap_connection = connect_to_ldap(**params)
return self.__ldap_connection
@@ -327,7 +379,6 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
return syncer
def synchronize(self):
-
sync_group_type = self.module.params.get("type")
groups_uids = []
@@ -365,7 +416,8 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
name, err = syncer.get_username_for_entry(entry)
if err:
self.exit_json(
- msg="Unable to determine username for entry %s: %s" % (entry, err)
+ msg="Unable to determine username for entry %s: %s"
+ % (entry, err)
)
if isinstance(name, list):
usernames.extend(name)
@@ -380,13 +432,17 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
self.exit_json(msg=err)
# Make Openshift group
- group, err = ldap_openshift_group.make_openshift_group(uid, group_name, usernames)
+ group, err = ldap_openshift_group.make_openshift_group(
+ uid, group_name, usernames
+ )
if err:
self.fail_json(msg=err)
openshift_groups.append(group)
# Create Openshift Groups
- results, diffs, changed = ldap_openshift_group.create_openshift_groups(openshift_groups)
+ results, diffs, changed = ldap_openshift_group.create_openshift_groups(
+ openshift_groups
+ )
self.module.exit_json(changed=True, groups=results)
def prune(self):
@@ -404,7 +460,10 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
# Check if LDAP group exist
exists, err = syncer.is_ldapgroup_exists(uid)
if err:
- msg = "Error determining LDAP group existence for group %s: %s" % (uid, err)
+ msg = "Error determining LDAP group existence for group %s: %s" % (
+ uid,
+ err,
+ )
self.module.fail_json(msg=msg)
if exists:
@@ -429,14 +488,22 @@ class OpenshiftGroupsSync(AnsibleOpenshiftModule):
self.fail_json(msg="Invalid LDAP Sync config: %s" % error)
# Split host/port
- if self.config.get('url'):
- result, error = ldap_split_host_port(self.config.get('url'))
+ if self.config.get("url"):
+ result, error = ldap_split_host_port(self.config.get("url"))
if error:
- self.fail_json(msg="Failed to parse url='{0}': {1}".format(self.config.get('url'), error))
- self.netlocation, self.host, self.port = result["netlocation"], result["host"], result["port"]
+ self.fail_json(
+ msg="Failed to parse url='{0}': {1}".format(
+ self.config.get("url"), error
+ )
+ )
+ self.netlocation, self.host, self.port = (
+ result["netlocation"],
+ result["host"],
+ result["port"],
+ )
self.scheme = result["scheme"]
- if self.params.get('state') == 'present':
+ if self.params.get("state") == "present":
self.synchronize()
else:
self.prune()
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_images_common.py b/ansible_collections/community/okd/plugins/module_utils/openshift_images_common.py
index 67d7123e8..8978a93b0 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_images_common.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_images_common.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
from datetime import datetime
@@ -17,9 +18,9 @@ def get_image_blobs(image):
return blobs, "failed to read metadata for image %s" % image["metadata"]["name"]
media_type_manifest = (
"application/vnd.docker.distribution.manifest.v2+json",
- "application/vnd.oci.image.manifest.v1+json"
+ "application/vnd.oci.image.manifest.v1+json",
)
- media_type_has_config = image['dockerImageManifestMediaType'] in media_type_manifest
+ media_type_has_config = image["dockerImageManifestMediaType"] in media_type_manifest
docker_image_id = docker_image_metadata.get("Id")
if media_type_has_config and docker_image_id and len(docker_image_id) > 0:
blobs.append(docker_image_id)
@@ -29,19 +30,18 @@ def get_image_blobs(image):
def is_created_after(creation_timestamp, max_creation_timestamp):
if not max_creation_timestamp:
return False
- creationTimestamp = datetime.strptime(creation_timestamp, '%Y-%m-%dT%H:%M:%SZ')
+ creationTimestamp = datetime.strptime(creation_timestamp, "%Y-%m-%dT%H:%M:%SZ")
return creationTimestamp > max_creation_timestamp
def is_too_young_object(obj, max_creation_timestamp):
- return is_created_after(obj['metadata']['creationTimestamp'],
- max_creation_timestamp)
+ return is_created_after(
+ obj["metadata"]["creationTimestamp"], max_creation_timestamp
+ )
class OpenShiftAnalyzeImageStream(object):
-
def __init__(self, ignore_invalid_refs, max_creation_timestamp, module):
-
self.max_creationTimestamp = max_creation_timestamp
self.used_tags = {}
self.used_images = {}
@@ -53,32 +53,34 @@ class OpenShiftAnalyzeImageStream(object):
if error:
return error
- if not result['hostname'] or not result['namespace']:
+ if not result["hostname"] or not result["namespace"]:
# image reference does not match hostname/namespace/name pattern - skipping
return None
- if not result['digest']:
+ if not result["digest"]:
# Attempt to dereference istag. Since we cannot be sure whether the reference refers to the
# integrated registry or not, we ignore the host part completely. As a consequence, we may keep
# image otherwise sentenced for a removal just because its pull spec accidentally matches one of
# our imagestreamtags.
# set the tag if empty
- if result['tag'] == "":
- result['tag'] = 'latest'
- key = "%s/%s:%s" % (result['namespace'], result['name'], result['tag'])
+ if result["tag"] == "":
+ result["tag"] = "latest"
+ key = "%s/%s:%s" % (result["namespace"], result["name"], result["tag"])
if key not in self.used_tags:
self.used_tags[key] = []
self.used_tags[key].append(referrer)
else:
- key = "%s/%s@%s" % (result['namespace'], result['name'], result['digest'])
+ key = "%s/%s@%s" % (result["namespace"], result["name"], result["digest"])
if key not in self.used_images:
self.used_images[key] = []
self.used_images[key].append(referrer)
def analyze_refs_from_pod_spec(self, podSpec, referrer):
- for container in podSpec.get('initContainers', []) + podSpec.get('containers', []):
- image = container.get('image')
+ for container in podSpec.get("initContainers", []) + podSpec.get(
+ "containers", []
+ ):
+ image = container.get("image")
if len(image.strip()) == 0:
# Ignoring container because it has no reference to image
continue
@@ -93,29 +95,35 @@ class OpenShiftAnalyzeImageStream(object):
# pending or running. Additionally, it has to be at least as old as the minimum
# age threshold defined by the algorithm.
too_young = is_too_young_object(pod, self.max_creationTimestamp)
- if pod['status']['phase'] not in ("Running", "Pending") and too_young:
+ if pod["status"]["phase"] not in ("Running", "Pending") and too_young:
continue
referrer = {
"kind": pod["kind"],
"namespace": pod["metadata"]["namespace"],
"name": pod["metadata"]["name"],
}
- err = self.analyze_refs_from_pod_spec(pod['spec'], referrer)
+ err = self.analyze_refs_from_pod_spec(pod["spec"], referrer)
if err:
return err
return None
def analyze_refs_pod_creators(self, resources):
keys = (
- "ReplicationController", "DeploymentConfig", "DaemonSet",
- "Deployment", "ReplicaSet", "StatefulSet", "Job", "CronJob"
+ "ReplicationController",
+ "DeploymentConfig",
+ "DaemonSet",
+ "Deployment",
+ "ReplicaSet",
+ "StatefulSet",
+ "Job",
+ "CronJob",
)
for k, objects in iteritems(resources):
if k not in keys:
continue
for obj in objects:
- if k == 'CronJob':
+ if k == "CronJob":
spec = obj["spec"]["jobTemplate"]["spec"]["template"]["spec"]
else:
spec = obj["spec"]["template"]["spec"]
@@ -132,64 +140,84 @@ class OpenShiftAnalyzeImageStream(object):
def analyze_refs_from_strategy(self, build_strategy, namespace, referrer):
# Determine 'from' reference
def _determine_source_strategy():
- for src in ('sourceStrategy', 'dockerStrategy', 'customStrategy'):
+ for src in ("sourceStrategy", "dockerStrategy", "customStrategy"):
strategy = build_strategy.get(src)
if strategy:
- return strategy.get('from')
+ return strategy.get("from")
return None
def _parse_image_stream_image_name(name):
- v = name.split('@')
+ v = name.split("@")
if len(v) != 2:
- return None, None, "expected exactly one @ in the isimage name %s" % name
+ return (
+ None,
+ None,
+ "expected exactly one @ in the isimage name %s" % name,
+ )
name = v[0]
tag = v[1]
if len(name) == 0 or len(tag) == 0:
- return None, None, "image stream image name %s must have a name and ID" % name
+ return (
+ None,
+ None,
+ "image stream image name %s must have a name and ID" % name,
+ )
return name, tag, None
def _parse_image_stream_tag_name(name):
if "@" in name:
- return None, None, "%s is an image stream image, not an image stream tag" % name
+ return (
+ None,
+ None,
+ "%s is an image stream image, not an image stream tag" % name,
+ )
v = name.split(":")
if len(v) != 2:
- return None, None, "expected exactly one : delimiter in the istag %s" % name
+ return (
+ None,
+ None,
+ "expected exactly one : delimiter in the istag %s" % name,
+ )
name = v[0]
tag = v[1]
if len(name) == 0 or len(tag) == 0:
- return None, None, "image stream tag name %s must have a name and a tag" % name
+ return (
+ None,
+ None,
+ "image stream tag name %s must have a name and a tag" % name,
+ )
return name, tag, None
from_strategy = _determine_source_strategy()
if from_strategy:
- if from_strategy.get('kind') == "DockerImage":
- docker_image_ref = from_strategy.get('name').strip()
+ if from_strategy.get("kind") == "DockerImage":
+ docker_image_ref = from_strategy.get("name").strip()
if len(docker_image_ref) > 0:
err = self.analyze_reference_image(docker_image_ref, referrer)
- elif from_strategy.get('kind') == "ImageStreamImage":
- name, tag, error = _parse_image_stream_image_name(from_strategy.get('name'))
+ elif from_strategy.get("kind") == "ImageStreamImage":
+ name, tag, error = _parse_image_stream_image_name(
+ from_strategy.get("name")
+ )
if error:
if not self.ignore_invalid_refs:
return error
else:
- namespace = from_strategy.get('namespace') or namespace
- self.used_images.append({
- 'namespace': namespace,
- 'name': name,
- 'tag': tag
- })
- elif from_strategy.get('kind') == "ImageStreamTag":
- name, tag, error = _parse_image_stream_tag_name(from_strategy.get('name'))
+ namespace = from_strategy.get("namespace") or namespace
+ self.used_images.append(
+ {"namespace": namespace, "name": name, "tag": tag}
+ )
+ elif from_strategy.get("kind") == "ImageStreamTag":
+ name, tag, error = _parse_image_stream_tag_name(
+ from_strategy.get("name")
+ )
if error:
if not self.ignore_invalid_refs:
return error
else:
- namespace = from_strategy.get('namespace') or namespace
- self.used_tags.append({
- 'namespace': namespace,
- 'name': name,
- 'tag': tag
- })
+ namespace = from_strategy.get("namespace") or namespace
+ self.used_tags.append(
+ {"namespace": namespace, "name": name, "tag": tag}
+ )
def analyze_refs_from_build_strategy(self, resources):
# Json Path is always spec.strategy
@@ -203,16 +231,20 @@ class OpenShiftAnalyzeImageStream(object):
"namespace": obj["metadata"]["namespace"],
"name": obj["metadata"]["name"],
}
- error = self.analyze_refs_from_strategy(obj['spec']['strategy'],
- obj['metadata']['namespace'],
- referrer)
+ error = self.analyze_refs_from_strategy(
+ obj["spec"]["strategy"], obj["metadata"]["namespace"], referrer
+ )
if error is not None:
- return "%s/%s/%s: %s" % (referrer["kind"], referrer["namespace"], referrer["name"], error)
+ return "%s/%s/%s: %s" % (
+ referrer["kind"],
+ referrer["namespace"],
+ referrer["name"],
+ error,
+ )
def analyze_image_stream(self, resources):
-
# Analyze image reference from Pods
- error = self.analyze_refs_from_pods(resources['Pod'])
+ error = self.analyze_refs_from_pods(resources["Pod"])
if error:
return None, None, error
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_import_image.py b/ansible_collections/community/okd/plugins/module_utils/openshift_import_image.py
index 01bba82af..c9953d761 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_import_image.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_import_image.py
@@ -1,16 +1,17 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-import traceback
import copy
-from ansible.module_utils._text import to_native
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.module_utils.six import string_types
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes.dynamic.exceptions import DynamicApiError
@@ -44,10 +45,17 @@ def follow_imagestream_tag_reference(stream, tag):
return name, tag, len(parts) == 2
content = []
- err_cross_stream_ref = "tag %s points to an imagestreamtag from another ImageStream" % tag
+ err_cross_stream_ref = (
+ "tag %s points to an imagestreamtag from another ImageStream" % tag
+ )
while True:
if tag in content:
- return tag, None, multiple, "tag %s on the image stream is a reference to same tag" % tag
+ return (
+ tag,
+ None,
+ multiple,
+ "tag %s on the image stream is a reference to same tag" % tag,
+ )
content.append(tag)
tag_ref = _imagestream_has_tag()
if not tag_ref:
@@ -56,7 +64,10 @@ def follow_imagestream_tag_reference(stream, tag):
if not tag_ref.get("from") or tag_ref["from"]["kind"] != "ImageStreamTag":
return tag, tag_ref, multiple, None
- if tag_ref["from"]["namespace"] != "" and tag_ref["from"]["namespace"] != stream["metadata"]["namespace"]:
+ if (
+ tag_ref["from"]["namespace"] != ""
+ and tag_ref["from"]["namespace"] != stream["metadata"]["namespace"]
+ ):
return tag, None, multiple, err_cross_stream_ref
# The reference needs to be followed with two format patterns:
@@ -64,7 +75,12 @@ def follow_imagestream_tag_reference(stream, tag):
if ":" in tag_ref["from"]["name"]:
name, tagref, result = _imagestream_split_tag(tag_ref["from"]["name"])
if not result:
- return tag, None, multiple, "tag %s points to an invalid imagestreamtag" % tag
+ return (
+ tag,
+ None,
+ multiple,
+ "tag %s points to an invalid imagestreamtag" % tag,
+ )
if name != stream["metadata"]["namespace"]:
# anotheris:sometag - this should not happen.
return tag, None, multiple, err_cross_stream_ref
@@ -80,7 +96,7 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
super(OpenShiftImportImage, self).__init__(**kwargs)
self._rest_client = None
- self.registryhost = self.params.get('registry_url')
+ self.registryhost = self.params.get("registry_url")
self.changed = False
ref_policy = self.params.get("reference_policy")
@@ -90,9 +106,7 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
elif ref_policy == "local":
ref_policy_type = "Local"
- self.ref_policy = {
- "type": ref_policy_type
- }
+ self.ref_policy = {"type": ref_policy_type}
self.validate_certs = self.params.get("validate_registry_certs")
self.cluster_resources = {}
@@ -104,15 +118,15 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
"metadata": {
"name": stream["metadata"]["name"],
"namespace": stream["metadata"]["namespace"],
- "resourceVersion": stream["metadata"].get("resourceVersion")
+ "resourceVersion": stream["metadata"].get("resourceVersion"),
},
- "spec": {
- "import": True
- }
+ "spec": {"import": True},
}
annotations = stream.get("annotations", {})
- insecure = boolean(annotations.get("openshift.io/image.insecureRepository", True))
+ insecure = boolean(
+ annotations.get("openshift.io/image.insecureRepository", True)
+ )
if self.validate_certs is not None:
insecure = not self.validate_certs
return isi, insecure
@@ -126,7 +140,7 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
},
"importPolicy": {
"insecure": insecure,
- "scheduled": self.params.get("scheduled")
+ "scheduled": self.params.get("scheduled"),
},
"referencePolicy": self.ref_policy,
}
@@ -149,26 +163,23 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
scheduled = scheduled or old_tag["importPolicy"].get("scheduled")
images = isi["spec"].get("images", [])
- images.append({
- "from": {
- "kind": "DockerImage",
- "name": tags.get(k),
- },
- "to": {
- "name": k
- },
- "importPolicy": {
- "insecure": insecure,
- "scheduled": scheduled
- },
- "referencePolicy": self.ref_policy,
- })
+ images.append(
+ {
+ "from": {
+ "kind": "DockerImage",
+ "name": tags.get(k),
+ },
+ "to": {"name": k},
+ "importPolicy": {"insecure": insecure, "scheduled": scheduled},
+ "referencePolicy": self.ref_policy,
+ }
+ )
isi["spec"]["images"] = images
return isi
def create_image_stream(self, ref):
"""
- Create new ImageStream and accompanying ImageStreamImport
+ Create new ImageStream and accompanying ImageStreamImport
"""
source = self.params.get("source")
if not source:
@@ -183,27 +194,20 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
),
)
if self.params.get("all") and not ref["tag"]:
- spec = dict(
- dockerImageRepository=source
- )
+ spec = dict(dockerImageRepository=source)
isi = self.create_image_stream_import_all(stream, source)
else:
spec = dict(
tags=[
{
- "from": {
- "kind": "DockerImage",
- "name": source
- },
- "referencePolicy": self.ref_policy
+ "from": {"kind": "DockerImage", "name": source},
+ "referencePolicy": self.ref_policy,
}
]
)
tags = {ref["tag"]: source}
isi = self.create_image_stream_import_tags(stream, tags)
- stream.update(
- dict(spec=spec)
- )
+ stream.update(dict(spec=spec))
return stream, isi
def import_all(self, istream):
@@ -220,8 +224,9 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
if t.get("from") and t["from"].get("kind") == "DockerImage":
tags[t.get("name")] = t["from"].get("name")
if tags == {}:
- msg = "image stream %s/%s does not have tags pointing to external container images" % (
- stream["metadata"]["namespace"], stream["metadata"]["name"]
+ msg = (
+ "image stream %s/%s does not have tags pointing to external container images"
+ % (stream["metadata"]["namespace"], stream["metadata"]["name"])
)
self.fail_json(msg=msg)
isi = self.create_image_stream_import_tags(stream, tags)
@@ -236,7 +241,9 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
source = self.params.get("source")
# Follow any referential tags to the destination
- final_tag, existing, multiple, err = follow_imagestream_tag_reference(stream, tag)
+ final_tag, existing, multiple, err = follow_imagestream_tag_reference(
+ stream, tag
+ )
if err:
if err == err_stream_not_found_ref:
# Create a new tag
@@ -245,7 +252,10 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
# if the from is still empty this means there's no such tag defined
# nor we can't create any from .spec.dockerImageRepository
if not source:
- msg = "the tag %s does not exist on the image stream - choose an existing tag to import" % tag
+ msg = (
+ "the tag %s does not exist on the image stream - choose an existing tag to import"
+ % tag
+ )
self.fail_json(msg=msg)
existing = {
"from": {
@@ -257,13 +267,21 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
self.fail_json(msg=err)
else:
# Disallow re-importing anything other than DockerImage
- if existing.get("from", {}) and existing["from"].get("kind") != "DockerImage":
+ if (
+ existing.get("from", {})
+ and existing["from"].get("kind") != "DockerImage"
+ ):
msg = "tag {tag} points to existing {kind}/={name}, it cannot be re-imported.".format(
- tag=tag, kind=existing["from"]["kind"], name=existing["from"]["name"]
+ tag=tag,
+ kind=existing["from"]["kind"],
+ name=existing["from"]["name"],
)
# disallow changing an existing tag
if not existing.get("from", {}):
- msg = "tag %s already exists - you cannot change the source using this module." % tag
+ msg = (
+ "tag %s already exists - you cannot change the source using this module."
+ % tag
+ )
self.fail_json(msg=msg)
if source and source != existing["from"]["name"]:
if multiple:
@@ -271,7 +289,10 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
tag, final_tag, existing["from"]["name"]
)
else:
- msg = "the tag %s points to %s you cannot change the source using this module." % (tag, final_tag)
+ msg = (
+ "the tag %s points to %s you cannot change the source using this module."
+ % (tag, final_tag)
+ )
self.fail_json(msg=msg)
# Set the target item to import
@@ -309,13 +330,13 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
kind=kind,
api_version=api_version,
name=ref.get("name"),
- namespace=self.params.get("namespace")
+ namespace=self.params.get("namespace"),
)
result = self.kubernetes_facts(**params)
if not result["api_found"]:
msg = 'Failed to find API for resource with apiVersion "{0}" and kind "{1}"'.format(
api_version, kind
- ),
+ )
self.fail_json(msg=msg)
imagestream = None
if len(result["resources"]) > 0:
@@ -335,7 +356,9 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
def parse_image_reference(self, image_ref):
result, err = parse_docker_image_ref(image_ref, self.module)
if result.get("digest"):
- self.fail_json(msg="Cannot import by ID, error with definition: %s" % image_ref)
+ self.fail_json(
+ msg="Cannot import by ID, error with definition: %s" % image_ref
+ )
tag = result.get("tag") or None
if not self.params.get("all") and not tag:
tag = "latest"
@@ -345,7 +368,6 @@ class OpenShiftImportImage(AnsibleOpenshiftModule):
return dict(name=result.get("name"), tag=tag, source=image_ref)
def execute_module(self):
-
names = []
name = self.params.get("name")
if isinstance(name, string_types):
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_ldap.py b/ansible_collections/community/okd/plugins/module_utils/openshift_ldap.py
index bb9229a72..cb1977489 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_ldap.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_ldap.py
@@ -3,7 +3,8 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
@@ -24,109 +25,119 @@ LDAP_SEARCH_OUT_OF_SCOPE_ERROR = "trying to search by DN for an entry that exist
def validate_ldap_sync_config(config):
# Validate url
- url = config.get('url')
+ url = config.get("url")
if not url:
return "url should be non empty attribute."
# Make sure bindDN and bindPassword are both set, or both unset
- bind_dn = config.get('bindDN', "")
- bind_password = config.get('bindPassword', "")
+ bind_dn = config.get("bindDN", "")
+ bind_password = config.get("bindPassword", "")
if (len(bind_dn) == 0) != (len(bind_password) == 0):
return "bindDN and bindPassword must both be specified, or both be empty."
- insecure = boolean(config.get('insecure'))
- ca_file = config.get('ca')
+ insecure = boolean(config.get("insecure"))
+ ca_file = config.get("ca")
if insecure:
- if url.startswith('ldaps://'):
+ if url.startswith("ldaps://"):
return "Cannot use ldaps scheme with insecure=true."
if ca_file:
return "Cannot specify a ca with insecure=true."
elif ca_file and not os.path.isfile(ca_file):
return "could not read ca file: {0}.".format(ca_file)
- nameMapping = config.get('groupUIDNameMapping', {})
+ nameMapping = config.get("groupUIDNameMapping", {})
for k, v in iteritems(nameMapping):
if len(k) == 0 or len(v) == 0:
return "groupUIDNameMapping has empty key or value"
schemas = []
- schema_list = ('rfc2307', 'activeDirectory', 'augmentedActiveDirectory')
+ schema_list = ("rfc2307", "activeDirectory", "augmentedActiveDirectory")
for schema in schema_list:
if schema in config:
schemas.append(schema)
if len(schemas) == 0:
- return "No schema-specific config was provided, should be one of %s" % ", ".join(schema_list)
+ return (
+ "No schema-specific config was provided, should be one of %s"
+ % ", ".join(schema_list)
+ )
if len(schemas) > 1:
- return "Exactly one schema-specific config is required; found (%d) %s" % (len(schemas), ','.join(schemas))
+ return "Exactly one schema-specific config is required; found (%d) %s" % (
+ len(schemas),
+ ",".join(schemas),
+ )
- if schemas[0] == 'rfc2307':
+ if schemas[0] == "rfc2307":
return validate_RFC2307(config.get("rfc2307"))
- elif schemas[0] == 'activeDirectory':
+ elif schemas[0] == "activeDirectory":
return validate_ActiveDirectory(config.get("activeDirectory"))
- elif schemas[0] == 'augmentedActiveDirectory':
+ elif schemas[0] == "augmentedActiveDirectory":
return validate_AugmentedActiveDirectory(config.get("augmentedActiveDirectory"))
def validate_ldap_query(qry, isDNOnly=False):
-
# validate query scope
- scope = qry.get('scope')
+ scope = qry.get("scope")
if scope and scope not in ("", "sub", "one", "base"):
return "invalid scope %s" % scope
# validate deref aliases
- derefAlias = qry.get('derefAliases')
+ derefAlias = qry.get("derefAliases")
if derefAlias and derefAlias not in ("never", "search", "base", "always"):
return "not a valid LDAP alias dereferncing behavior: %s", derefAlias
# validate timeout
- timeout = qry.get('timeout')
+ timeout = qry.get("timeout")
if timeout and float(timeout) < 0:
return "timeout must be equal to or greater than zero"
# Validate DN only
- qry_filter = qry.get('filter', "")
+ qry_filter = qry.get("filter", "")
if isDNOnly:
if len(qry_filter) > 0:
return 'cannot specify a filter when using "dn" as the UID attribute'
else:
# validate filter
- if len(qry_filter) == 0 or qry_filter[0] != '(':
+ if len(qry_filter) == 0 or qry_filter[0] != "(":
return "filter does not start with an '('"
return None
def validate_RFC2307(config):
- qry = config.get('groupsQuery')
+ qry = config.get("groupsQuery")
if not qry or not isinstance(qry, dict):
return "RFC2307: groupsQuery requires a dictionary"
error = validate_ldap_query(qry)
if not error:
return error
- for field in ('groupUIDAttribute', 'groupNameAttributes', 'groupMembershipAttributes',
- 'userUIDAttribute', 'userNameAttributes'):
+ for field in (
+ "groupUIDAttribute",
+ "groupNameAttributes",
+ "groupMembershipAttributes",
+ "userUIDAttribute",
+ "userNameAttributes",
+ ):
value = config.get(field)
if not value:
return "RFC2307: {0} is required.".format(field)
- users_qry = config.get('usersQuery')
+ users_qry = config.get("usersQuery")
if not users_qry or not isinstance(users_qry, dict):
return "RFC2307: usersQuery requires a dictionary"
- isUserDNOnly = (config.get('userUIDAttribute').strip() == 'dn')
+ isUserDNOnly = config.get("userUIDAttribute").strip() == "dn"
return validate_ldap_query(users_qry, isDNOnly=isUserDNOnly)
def validate_ActiveDirectory(config, label="ActiveDirectory"):
- users_qry = config.get('usersQuery')
+ users_qry = config.get("usersQuery")
if not users_qry or not isinstance(users_qry, dict):
return "{0}: usersQuery requires as dictionnary".format(label)
error = validate_ldap_query(users_qry)
if not error:
return error
- for field in ('userNameAttributes', 'groupMembershipAttributes'):
+ for field in ("userNameAttributes", "groupMembershipAttributes"):
value = config.get(field)
if not value:
return "{0}: {1} is required.".format(field, label)
@@ -138,24 +149,24 @@ def validate_AugmentedActiveDirectory(config):
error = validate_ActiveDirectory(config, label="AugmentedActiveDirectory")
if not error:
return error
- for field in ('groupUIDAttribute', 'groupNameAttributes'):
+ for field in ("groupUIDAttribute", "groupNameAttributes"):
value = config.get(field)
if not value:
return "AugmentedActiveDirectory: {0} is required".format(field)
- groups_qry = config.get('groupsQuery')
+ groups_qry = config.get("groupsQuery")
if not groups_qry or not isinstance(groups_qry, dict):
return "AugmentedActiveDirectory: groupsQuery requires as dictionnary."
- isGroupDNOnly = (config.get('groupUIDAttribute').strip() == 'dn')
+ isGroupDNOnly = config.get("groupUIDAttribute").strip() == "dn"
return validate_ldap_query(groups_qry, isDNOnly=isGroupDNOnly)
def determine_ldap_scope(scope):
if scope in ("", "sub"):
return ldap.SCOPE_SUBTREE
- elif scope == 'base':
+ elif scope == "base":
return ldap.SCOPE_BASE
- elif scope == 'one':
+ elif scope == "one":
return ldap.SCOPE_ONELEVEL
return None
@@ -175,28 +186,28 @@ def determine_deref_aliases(derefAlias):
def openshift_ldap_build_base_query(config):
qry = {}
- if config.get('baseDN'):
- qry['base'] = config.get('baseDN')
+ if config.get("baseDN"):
+ qry["base"] = config.get("baseDN")
- scope = determine_ldap_scope(config.get('scope'))
+ scope = determine_ldap_scope(config.get("scope"))
if scope:
- qry['scope'] = scope
+ qry["scope"] = scope
- pageSize = config.get('pageSize')
+ pageSize = config.get("pageSize")
if pageSize and int(pageSize) > 0:
- qry['sizelimit'] = int(pageSize)
+ qry["sizelimit"] = int(pageSize)
- timeout = config.get('timeout')
+ timeout = config.get("timeout")
if timeout and int(timeout) > 0:
- qry['timeout'] = int(timeout)
+ qry["timeout"] = int(timeout)
- filter = config.get('filter')
+ filter = config.get("filter")
if filter:
- qry['filterstr'] = filter
+ qry["filterstr"] = filter
- derefAlias = determine_deref_aliases(config.get('derefAliases'))
+ derefAlias = determine_deref_aliases(config.get("derefAliases"))
if derefAlias:
- qry['derefAlias'] = derefAlias
+ qry["derefAlias"] = derefAlias
return qry
@@ -205,32 +216,30 @@ def openshift_ldap_get_attribute_for_entry(entry, attribute):
if isinstance(attribute, list):
attributes = attribute
for k in attributes:
- if k.lower() == 'dn':
+ if k.lower() == "dn":
return entry[0]
v = entry[1].get(k, None)
if v:
if isinstance(v, list):
result = []
for x in v:
- if hasattr(x, 'decode'):
- result.append(x.decode('utf-8'))
+ if hasattr(x, "decode"):
+ result.append(x.decode("utf-8"))
else:
result.append(x)
return result
else:
- return v.decode('utf-8') if hasattr(v, 'decode') else v
+ return v.decode("utf-8") if hasattr(v, "decode") else v
return ""
def ldap_split_host_port(hostport):
"""
- ldap_split_host_port splits a network address of the form "host:port",
- "host%zone:port", "[host]:port" or "[host%zone]:port" into host or
- host%zone and port.
+ ldap_split_host_port splits a network address of the form "host:port",
+ "host%zone:port", "[host]:port" or "[host%zone]:port" into host or
+ host%zone and port.
"""
- result = dict(
- scheme=None, netlocation=None, host=None, port=None
- )
+ result = dict(scheme=None, netlocation=None, host=None, port=None)
if not hostport:
return result, None
@@ -240,10 +249,10 @@ def ldap_split_host_port(hostport):
if "://" in hostport:
idx = hostport.find(scheme_l)
result["scheme"] = hostport[:idx]
- netlocation = hostport[idx + len(scheme_l):]
+ netlocation = hostport[idx + len(scheme_l):] # fmt: skip
result["netlocation"] = netlocation
- if netlocation[-1] == ']':
+ if netlocation[-1] == "]":
# ipv6 literal (with no port)
result["host"] = netlocation
@@ -259,21 +268,32 @@ def ldap_split_host_port(hostport):
def openshift_ldap_query_for_entries(connection, qry, unique_entry=True):
# set deref alias (TODO: need to set a default value to reset for each transaction)
- derefAlias = qry.pop('derefAlias', None)
+ derefAlias = qry.pop("derefAlias", None)
if derefAlias:
ldap.set_option(ldap.OPT_DEREF, derefAlias)
try:
result = connection.search_ext_s(**qry)
if not result or len(result) == 0:
- return None, "Entry not found for base='{0}' and filter='{1}'".format(qry['base'], qry['filterstr'])
+ return None, "Entry not found for base='{0}' and filter='{1}'".format(
+ qry["base"], qry["filterstr"]
+ )
if len(result) > 1 and unique_entry:
- if qry.get('scope') == ldap.SCOPE_BASE:
- return None, "multiple entries found matching dn={0}: {1}".format(qry['base'], result)
+ if qry.get("scope") == ldap.SCOPE_BASE:
+ return None, "multiple entries found matching dn={0}: {1}".format(
+ qry["base"], result
+ )
else:
- return None, "multiple entries found matching filter {0}: {1}".format(qry['filterstr'], result)
+ return None, "multiple entries found matching filter {0}: {1}".format(
+ qry["filterstr"], result
+ )
return result, None
except ldap.NO_SUCH_OBJECT:
- return None, "search for entry with base dn='{0}' refers to a non-existent entry".format(qry['base'])
+ return (
+ None,
+ "search for entry with base dn='{0}' refers to a non-existent entry".format(
+ qry["base"]
+ ),
+ )
def openshift_equal_dn_objects(dn_obj, other_dn_obj):
@@ -303,7 +323,9 @@ def openshift_ancestorof_dn(dn, other):
if len(dn_obj) >= len(other_dn_obj):
return False
# Take the last attribute from the other DN to compare against
- return openshift_equal_dn_objects(dn_obj, other_dn_obj[len(other_dn_obj) - len(dn_obj):])
+ return openshift_equal_dn_objects(
+ dn_obj, other_dn_obj[len(other_dn_obj) - len(dn_obj):] # fmt: skip
+ )
class OpenshiftLDAPQueryOnAttribute(object):
@@ -324,33 +346,38 @@ class OpenshiftLDAPQueryOnAttribute(object):
output = []
hex_string = "0123456789abcdef"
for c in buffer:
- if ord(c) > 0x7f or c in ('(', ')', '\\', '*') or c == 0:
+ if ord(c) > 0x7F or c in ("(", ")", "\\", "*") or c == 0:
first = ord(c) >> 4
- second = ord(c) & 0xf
- output += ['\\', hex_string[first], hex_string[second]]
+ second = ord(c) & 0xF
+ output += ["\\", hex_string[first], hex_string[second]]
else:
output.append(c)
- return ''.join(output)
+ return "".join(output)
def build_request(self, ldapuid, attributes):
params = copy.deepcopy(self.qry)
- if self.query_attribute.lower() == 'dn':
+ if self.query_attribute.lower() == "dn":
if ldapuid:
- if not openshift_equal_dn(ldapuid, params['base']) and not openshift_ancestorof_dn(params['base'], ldapuid):
+ if not openshift_equal_dn(
+ ldapuid, params["base"]
+ ) and not openshift_ancestorof_dn(params["base"], ldapuid):
return None, LDAP_SEARCH_OUT_OF_SCOPE_ERROR
- params['base'] = ldapuid
- params['scope'] = ldap.SCOPE_BASE
+ params["base"] = ldapuid
+ params["scope"] = ldap.SCOPE_BASE
# filter that returns all values
- params['filterstr'] = "(objectClass=*)"
- params['attrlist'] = attributes
+ params["filterstr"] = "(objectClass=*)"
+ params["attrlist"] = attributes
else:
# Builds the query containing a filter that conjoins the common filter given
# in the configuration with the specific attribute filter for which the attribute value is given
- specificFilter = "%s=%s" % (self.escape_filter(self.query_attribute), self.escape_filter(ldapuid))
- qry_filter = params.get('filterstr', None)
+ specificFilter = "%s=%s" % (
+ self.escape_filter(self.query_attribute),
+ self.escape_filter(ldapuid),
+ )
+ qry_filter = params.get("filterstr", None)
if qry_filter:
- params['filterstr'] = "(&%s(%s))" % (qry_filter, specificFilter)
- params['attrlist'] = attributes
+ params["filterstr"] = "(&%s(%s))" % (qry_filter, specificFilter)
+ params["attrlist"] = attributes
return params, None
def ldap_search(self, connection, ldapuid, required_attributes, unique_entry=True):
@@ -358,21 +385,29 @@ class OpenshiftLDAPQueryOnAttribute(object):
if error:
return None, error
# set deref alias (TODO: need to set a default value to reset for each transaction)
- derefAlias = query.pop('derefAlias', None)
+ derefAlias = query.pop("derefAlias", None)
if derefAlias:
ldap.set_option(ldap.OPT_DEREF, derefAlias)
try:
result = connection.search_ext_s(**query)
if not result or len(result) == 0:
- return None, "Entry not found for base='{0}' and filter='{1}'".format(query['base'], query['filterstr'])
+ return None, "Entry not found for base='{0}' and filter='{1}'".format(
+ query["base"], query["filterstr"]
+ )
if unique_entry:
if len(result) > 1:
- return None, "Multiple Entries found matching search criteria: %s (%s)" % (query, result)
+ return (
+ None,
+ "Multiple Entries found matching search criteria: %s (%s)"
+ % (query, result),
+ )
result = result[0]
return result, None
except ldap.NO_SUCH_OBJECT:
- return None, "Entry not found for base='{0}' and filter='{1}'".format(query['base'], query['filterstr'])
+ return None, "Entry not found for base='{0}' and filter='{1}'".format(
+ query["base"], query["filterstr"]
+ )
except Exception as err:
return None, "Request %s failed due to: %s" % (query, err)
@@ -384,30 +419,43 @@ class OpenshiftLDAPQuery(object):
def build_request(self, attributes):
params = copy.deepcopy(self.qry)
- params['attrlist'] = attributes
+ params["attrlist"] = attributes
return params
def ldap_search(self, connection, required_attributes):
query = self.build_request(required_attributes)
# set deref alias (TODO: need to set a default value to reset for each transaction)
- derefAlias = query.pop('derefAlias', None)
+ derefAlias = query.pop("derefAlias", None)
if derefAlias:
ldap.set_option(ldap.OPT_DEREF, derefAlias)
try:
result = connection.search_ext_s(**query)
if not result or len(result) == 0:
- return None, "Entry not found for base='{0}' and filter='{1}'".format(query['base'], query['filterstr'])
+ return None, "Entry not found for base='{0}' and filter='{1}'".format(
+ query["base"], query["filterstr"]
+ )
return result, None
except ldap.NO_SUCH_OBJECT:
- return None, "search for entry with base dn='{0}' refers to a non-existent entry".format(query['base'])
+ return (
+ None,
+ "search for entry with base dn='{0}' refers to a non-existent entry".format(
+ query["base"]
+ ),
+ )
class OpenshiftLDAPInterface(object):
-
- def __init__(self, connection, groupQuery, groupNameAttributes, groupMembershipAttributes,
- userQuery, userNameAttributes, config):
-
+ def __init__(
+ self,
+ connection,
+ groupQuery,
+ groupNameAttributes,
+ groupMembershipAttributes,
+ userQuery,
+ userNameAttributes,
+ config,
+ ):
self.connection = connection
self.groupQuery = copy.deepcopy(groupQuery)
self.groupNameAttributes = groupNameAttributes
@@ -416,8 +464,12 @@ class OpenshiftLDAPInterface(object):
self.userNameAttributes = userNameAttributes
self.config = config
- self.tolerate_not_found = boolean(config.get('tolerateMemberNotFoundErrors', False))
- self.tolerate_out_of_scope = boolean(config.get('tolerateMemberOutOfScopeErrors', False))
+ self.tolerate_not_found = boolean(
+ config.get("tolerateMemberNotFoundErrors", False)
+ )
+ self.tolerate_out_of_scope = boolean(
+ config.get("tolerateMemberOutOfScopeErrors", False)
+ )
self.required_group_attributes = [self.groupQuery.query_attribute]
for x in self.groupNameAttributes + self.groupMembershipAttributes:
@@ -434,13 +486,15 @@ class OpenshiftLDAPInterface(object):
def get_group_entry(self, uid):
"""
- get_group_entry returns an LDAP group entry for the given group UID by searching the internal cache
- of the LDAPInterface first, then sending an LDAP query if the cache did not contain the entry.
+ get_group_entry returns an LDAP group entry for the given group UID by searching the internal cache
+ of the LDAPInterface first, then sending an LDAP query if the cache did not contain the entry.
"""
if uid in self.cached_groups:
return self.cached_groups.get(uid), None
- group, err = self.groupQuery.ldap_search(self.connection, uid, self.required_group_attributes)
+ group, err = self.groupQuery.ldap_search(
+ self.connection, uid, self.required_group_attributes
+ )
if err:
return None, err
self.cached_groups[uid] = group
@@ -448,13 +502,15 @@ class OpenshiftLDAPInterface(object):
def get_user_entry(self, uid):
"""
- get_user_entry returns an LDAP group entry for the given user UID by searching the internal cache
- of the LDAPInterface first, then sending an LDAP query if the cache did not contain the entry.
+ get_user_entry returns an LDAP group entry for the given user UID by searching the internal cache
+ of the LDAPInterface first, then sending an LDAP query if the cache did not contain the entry.
"""
if uid in self.cached_users:
return self.cached_users.get(uid), None
- entry, err = self.userQuery.ldap_search(self.connection, uid, self.required_user_attributes)
+ entry, err = self.userQuery.ldap_search(
+ self.connection, uid, self.required_user_attributes
+ )
if err:
return None, err
self.cached_users[uid] = entry
@@ -466,19 +522,19 @@ class OpenshiftLDAPInterface(object):
def list_groups(self):
group_qry = copy.deepcopy(self.groupQuery.qry)
- group_qry['attrlist'] = self.required_group_attributes
+ group_qry["attrlist"] = self.required_group_attributes
groups, err = openshift_ldap_query_for_entries(
- connection=self.connection,
- qry=group_qry,
- unique_entry=False
+ connection=self.connection, qry=group_qry, unique_entry=False
)
if err:
return None, err
group_uids = []
for entry in groups:
- uid = openshift_ldap_get_attribute_for_entry(entry, self.groupQuery.query_attribute)
+ uid = openshift_ldap_get_attribute_for_entry(
+ entry, self.groupQuery.query_attribute
+ )
if not uid:
return None, "Unable to find LDAP group uid for entry %s" % entry
self.cached_groups[uid] = entry
@@ -487,7 +543,7 @@ class OpenshiftLDAPInterface(object):
def extract_members(self, uid):
"""
- returns the LDAP member entries for a group specified with a ldapGroupUID
+ returns the LDAP member entries for a group specified with a ldapGroupUID
"""
# Get group entry from LDAP
group, err = self.get_group_entry(uid)
@@ -514,39 +570,46 @@ class OpenshiftLDAPInterface(object):
class OpenshiftLDAPRFC2307(object):
-
def __init__(self, config, ldap_connection):
-
self.config = config
self.ldap_interface = self.create_ldap_interface(ldap_connection)
def create_ldap_interface(self, connection):
segment = self.config.get("rfc2307")
- groups_base_qry = openshift_ldap_build_base_query(segment['groupsQuery'])
- users_base_qry = openshift_ldap_build_base_query(segment['usersQuery'])
+ groups_base_qry = openshift_ldap_build_base_query(segment["groupsQuery"])
+ users_base_qry = openshift_ldap_build_base_query(segment["usersQuery"])
- groups_query = OpenshiftLDAPQueryOnAttribute(groups_base_qry, segment['groupUIDAttribute'])
- users_query = OpenshiftLDAPQueryOnAttribute(users_base_qry, segment['userUIDAttribute'])
+ groups_query = OpenshiftLDAPQueryOnAttribute(
+ groups_base_qry, segment["groupUIDAttribute"]
+ )
+ users_query = OpenshiftLDAPQueryOnAttribute(
+ users_base_qry, segment["userUIDAttribute"]
+ )
params = dict(
connection=connection,
groupQuery=groups_query,
- groupNameAttributes=segment['groupNameAttributes'],
- groupMembershipAttributes=segment['groupMembershipAttributes'],
+ groupNameAttributes=segment["groupNameAttributes"],
+ groupMembershipAttributes=segment["groupMembershipAttributes"],
userQuery=users_query,
- userNameAttributes=segment['userNameAttributes'],
- config=segment
+ userNameAttributes=segment["userNameAttributes"],
+ config=segment,
)
return OpenshiftLDAPInterface(**params)
def get_username_for_entry(self, entry):
- username = openshift_ldap_get_attribute_for_entry(entry, self.ldap_interface.userNameAttributes)
+ username = openshift_ldap_get_attribute_for_entry(
+ entry, self.ldap_interface.userNameAttributes
+ )
if not username:
- return None, "The user entry (%s) does not map to a OpenShift User name with the given mapping" % entry
+ return (
+ None,
+ "The user entry (%s) does not map to a OpenShift User name with the given mapping"
+ % entry,
+ )
return username, None
def get_group_name_for_uid(self, uid):
-
# Get name from User defined mapping
groupuid_name_mapping = self.config.get("groupUIDNameMapping")
if groupuid_name_mapping and uid in groupuid_name_mapping:
@@ -555,10 +618,13 @@ class OpenshiftLDAPRFC2307(object):
group, err = self.ldap_interface.get_group_entry(uid)
if err:
return None, err
- group_name = openshift_ldap_get_attribute_for_entry(group, self.ldap_interface.groupNameAttributes)
+ group_name = openshift_ldap_get_attribute_for_entry(
+ group, self.ldap_interface.groupNameAttributes
+ )
if not group_name:
- error = "The group entry (%s) does not map to an OpenShift Group name with the given name attribute (%s)" % (
- group, self.ldap_interface.groupNameAttributes
+ error = (
+ "The group entry (%s) does not map to an OpenShift Group name with the given name attribute (%s)"
+ % (group, self.ldap_interface.groupNameAttributes)
)
return None, error
if isinstance(group_name, list):
@@ -570,7 +636,11 @@ class OpenshiftLDAPRFC2307(object):
def is_ldapgroup_exists(self, uid):
group, err = self.ldap_interface.get_group_entry(uid)
if err:
- if err == LDAP_SEARCH_OUT_OF_SCOPE_ERROR or err.startswith("Entry not found") or "non-existent entry" in err:
+ if (
+ err == LDAP_SEARCH_OUT_OF_SCOPE_ERROR
+ or err.startswith("Entry not found")
+ or "non-existent entry" in err
+ ):
return False, None
return False, err
if group:
@@ -585,7 +655,6 @@ class OpenshiftLDAPRFC2307(object):
class OpenshiftLDAP_ADInterface(object):
-
def __init__(self, connection, user_query, group_member_attr, user_name_attr):
self.connection = connection
self.userQuery = user_query
@@ -609,7 +678,9 @@ class OpenshiftLDAP_ADInterface(object):
def populate_cache(self):
if not self.cache_populated:
self.cache_populated = True
- entries, err = self.userQuery.ldap_search(self.connection, self.required_user_attributes)
+ entries, err = self.userQuery.ldap_search(
+ self.connection, self.required_user_attributes
+ )
if err:
return err
@@ -645,7 +716,9 @@ class OpenshiftLDAP_ADInterface(object):
users_in_group = []
for attr in self.groupMembershipAttributes:
query_on_attribute = OpenshiftLDAPQueryOnAttribute(self.userQuery.qry, attr)
- entries, error = query_on_attribute.ldap_search(self.connection, uid, self.required_user_attributes, unique_entry=False)
+ entries, error = query_on_attribute.ldap_search(
+ self.connection, uid, self.required_user_attributes, unique_entry=False
+ )
if error and "not found" not in error:
return None, error
if not entries:
@@ -660,15 +733,13 @@ class OpenshiftLDAP_ADInterface(object):
class OpenshiftLDAPActiveDirectory(object):
-
def __init__(self, config, ldap_connection):
-
self.config = config
self.ldap_interface = self.create_ldap_interface(ldap_connection)
def create_ldap_interface(self, connection):
segment = self.config.get("activeDirectory")
- base_query = openshift_ldap_build_base_query(segment['usersQuery'])
+ base_query = openshift_ldap_build_base_query(segment["usersQuery"])
user_query = OpenshiftLDAPQuery(base_query)
return OpenshiftLDAP_ADInterface(
@@ -679,9 +750,15 @@ class OpenshiftLDAPActiveDirectory(object):
)
def get_username_for_entry(self, entry):
- username = openshift_ldap_get_attribute_for_entry(entry, self.ldap_interface.userNameAttributes)
+ username = openshift_ldap_get_attribute_for_entry(
+ entry, self.ldap_interface.userNameAttributes
+ )
if not username:
- return None, "The user entry (%s) does not map to a OpenShift User name with the given mapping" % entry
+ return (
+ None,
+ "The user entry (%s) does not map to a OpenShift User name with the given mapping"
+ % entry,
+ )
return username, None
def get_group_name_for_uid(self, uid):
@@ -702,8 +779,15 @@ class OpenshiftLDAPActiveDirectory(object):
class OpenshiftLDAP_AugmentedADInterface(OpenshiftLDAP_ADInterface):
-
- def __init__(self, connection, user_query, group_member_attr, user_name_attr, group_qry, group_name_attr):
+ def __init__(
+ self,
+ connection,
+ user_query,
+ group_member_attr,
+ user_name_attr,
+ group_qry,
+ group_name_attr,
+ ):
super(OpenshiftLDAP_AugmentedADInterface, self).__init__(
connection, user_query, group_member_attr, user_name_attr
)
@@ -719,13 +803,15 @@ class OpenshiftLDAP_AugmentedADInterface(OpenshiftLDAP_ADInterface):
def get_group_entry(self, uid):
"""
- get_group_entry returns an LDAP group entry for the given group UID by searching the internal cache
- of the LDAPInterface first, then sending an LDAP query if the cache did not contain the entry.
+ get_group_entry returns an LDAP group entry for the given group UID by searching the internal cache
+ of the LDAPInterface first, then sending an LDAP query if the cache did not contain the entry.
"""
if uid in self.cached_groups:
return self.cached_groups.get(uid), None
- group, err = self.groupQuery.ldap_search(self.connection, uid, self.required_group_attributes)
+ group, err = self.groupQuery.ldap_search(
+ self.connection, uid, self.required_group_attributes
+ )
if err:
return None, err
self.cached_groups[uid] = group
@@ -750,19 +836,19 @@ class OpenshiftLDAP_AugmentedADInterface(OpenshiftLDAP_ADInterface):
class OpenshiftLDAPAugmentedActiveDirectory(OpenshiftLDAPRFC2307):
-
def __init__(self, config, ldap_connection):
-
self.config = config
self.ldap_interface = self.create_ldap_interface(ldap_connection)
def create_ldap_interface(self, connection):
segment = self.config.get("augmentedActiveDirectory")
- user_base_query = openshift_ldap_build_base_query(segment['usersQuery'])
- groups_base_qry = openshift_ldap_build_base_query(segment['groupsQuery'])
+ user_base_query = openshift_ldap_build_base_query(segment["usersQuery"])
+ groups_base_qry = openshift_ldap_build_base_query(segment["groupsQuery"])
user_query = OpenshiftLDAPQuery(user_base_query)
- groups_query = OpenshiftLDAPQueryOnAttribute(groups_base_qry, segment['groupUIDAttribute'])
+ groups_query = OpenshiftLDAPQueryOnAttribute(
+ groups_base_qry, segment["groupUIDAttribute"]
+ )
return OpenshiftLDAP_AugmentedADInterface(
connection=connection,
@@ -770,7 +856,7 @@ class OpenshiftLDAPAugmentedActiveDirectory(OpenshiftLDAPRFC2307):
group_member_attr=segment["groupMembershipAttributes"],
user_name_attr=segment["userNameAttributes"],
group_qry=groups_query,
- group_name_attr=segment["groupNameAttributes"]
+ group_name_attr=segment["groupNameAttributes"],
)
def is_ldapgroup_exists(self, uid):
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_process.py b/ansible_collections/community/okd/plugins/module_utils/openshift_process.py
index 6fa69d13c..3996aedc2 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_process.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_process.py
@@ -1,15 +1,16 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
import os
-import traceback
from ansible.module_utils._text import to_native
-
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes.dynamic.exceptions import DynamicApiError
@@ -124,7 +125,6 @@ class OpenShiftProcess(AnsibleOpenshiftModule):
self.exit_json(**result)
def create_resources(self, definitions):
-
params = {"namespace": self.params.get("namespace_target")}
self.params["apply"] = False
@@ -139,9 +139,7 @@ class OpenShiftProcess(AnsibleOpenshiftModule):
continue
kind = definition.get("kind")
if kind and kind.endswith("List"):
- flattened_definitions.extend(
- self.flatten_list_kind(definition, params)
- )
+ flattened_definitions.extend(self.flatten_list_kind(definition, params))
else:
flattened_definitions.append(self.merge_params(definition, params))
diff --git a/ansible_collections/community/okd/plugins/module_utils/openshift_registry.py b/ansible_collections/community/okd/plugins/module_utils/openshift_registry.py
index 32a1830df..557a7d1f5 100644
--- a/ansible_collections/community/okd/plugins/module_utils/openshift_registry.py
+++ b/ansible_collections/community/okd/plugins/module_utils/openshift_registry.py
@@ -1,12 +1,15 @@
#!/usr/bin/env python
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
import traceback
from urllib.parse import urlparse
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
from ansible_collections.community.okd.plugins.module_utils.openshift_docker_image import (
parse_docker_image_ref,
@@ -15,6 +18,7 @@ from ansible_collections.community.okd.plugins.module_utils.openshift_docker_ima
try:
from requests import request
from requests.auth import HTTPBasicAuth
+
HAS_REQUESTS_MODULE = True
requests_import_exception = None
except ImportError as e:
@@ -32,11 +36,7 @@ class OpenShiftRegistry(AnsibleOpenshiftModule):
kind = "ImageStream"
api_version = "image.openshift.io/v1"
- params = dict(
- kind=kind,
- api_version=api_version,
- namespace=namespace
- )
+ params = dict(kind=kind, api_version=api_version, namespace=namespace)
result = self.kubernetes_facts(**params)
imagestream = []
if len(result["resources"]) > 0:
@@ -44,7 +44,6 @@ class OpenShiftRegistry(AnsibleOpenshiftModule):
return imagestream
def find_registry_info(self):
-
def _determine_registry(image_stream):
public, internal = None, None
docker_repo = image_stream["status"].get("publicDockerImageRepository")
@@ -72,39 +71,46 @@ class OpenShiftRegistry(AnsibleOpenshiftModule):
self.fail_json(msg="The integrated registry has not been configured")
return internal, public
- self.fail_json(msg="No Image Streams could be located to retrieve registry info.")
+ self.fail_json(
+ msg="No Image Streams could be located to retrieve registry info."
+ )
def execute_module(self):
result = {}
- result["internal_hostname"], result["public_hostname"] = self.find_registry_info()
+ (
+ result["internal_hostname"],
+ result["public_hostname"],
+ ) = self.find_registry_info()
if self.check:
public_registry = result["public_hostname"]
if not public_registry:
result["check"] = dict(
- reached=False,
- msg="Registry does not have a public hostname."
+ reached=False, msg="Registry does not have a public hostname."
)
else:
- headers = {
- 'Content-Type': 'application/json'
- }
- params = {
- 'method': 'GET',
- 'verify': False
- }
+ headers = {"Content-Type": "application/json"}
+ params = {"method": "GET", "verify": False}
if self.client.configuration.api_key:
headers.update(self.client.configuration.api_key)
- elif self.client.configuration.username and self.client.configuration.password:
+ elif (
+ self.client.configuration.username
+ and self.client.configuration.password
+ ):
if not HAS_REQUESTS_MODULE:
result["check"] = dict(
reached=False,
msg="The requests python package is missing, try `pip install requests`",
- error=requests_import_exception
+ error=requests_import_exception,
)
self.exit_json(**result)
params.update(
- dict(auth=HTTPBasicAuth(self.client.configuration.username, self.client.configuration.password))
+ dict(
+ auth=HTTPBasicAuth(
+ self.client.configuration.username,
+ self.client.configuration.password,
+ )
+ )
)
# verify ssl
@@ -112,23 +118,20 @@ class OpenShiftRegistry(AnsibleOpenshiftModule):
if len(host.scheme) == 0:
registry_url = "https://" + public_registry
- if registry_url.startswith("https://") and self.client.configuration.ssl_ca_cert:
- params.update(
- dict(verify=self.client.configuration.ssl_ca_cert)
- )
- params.update(
- dict(headers=headers)
- )
+ if (
+ registry_url.startswith("https://")
+ and self.client.configuration.ssl_ca_cert
+ ):
+ params.update(dict(verify=self.client.configuration.ssl_ca_cert))
+ params.update(dict(headers=headers))
last_bad_status, last_bad_reason = None, None
for path in ("/", "/healthz"):
- params.update(
- dict(url=registry_url + path)
- )
+ params.update(dict(url=registry_url + path))
response = request(**params)
if response.status_code == 200:
result["check"] = dict(
reached=True,
- msg="The local client can contact the integrated registry."
+ msg="The local client can contact the integrated registry.",
)
self.exit_json(**result)
last_bad_reason = response.reason
@@ -136,9 +139,8 @@ class OpenShiftRegistry(AnsibleOpenshiftModule):
result["check"] = dict(
reached=False,
- msg="Unable to contact the integrated registry using local client. Status=%d, Reason=%s" % (
- last_bad_status, last_bad_reason
- )
+ msg="Unable to contact the integrated registry using local client. Status=%d, Reason=%s"
+ % (last_bad_status, last_bad_reason),
)
self.exit_json(**result)
diff --git a/ansible_collections/community/okd/plugins/modules/k8s.py b/ansible_collections/community/okd/plugins/modules/k8s.py
index c3b8d1b66..ae3a9b493 100644
--- a/ansible_collections/community/okd/plugins/modules/k8s.py
+++ b/ansible_collections/community/okd/plugins/modules/k8s.py
@@ -10,7 +10,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: k8s
@@ -142,9 +142,9 @@ requirements:
- "python >= 3.6"
- "kubernetes >= 12.0.0"
- "PyYAML >= 3.11"
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
- name: Create a k8s namespace
community.okd.k8s:
name: testing
@@ -169,10 +169,10 @@ EXAMPLES = r'''
app: galaxy
service: web
ports:
- - protocol: TCP
- targetPort: 8000
- name: port-8000-tcp
- port: 8000
+ - protocol: TCP
+ targetPort: 8000
+ name: port-8000-tcp
+ port: 8000
- name: Remove an existing Service object
community.okd.k8s:
@@ -206,18 +206,18 @@ EXAMPLES = r'''
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
validate:
- fail_on_error: yes
+ fail_on_error: true
- name: warn on validation errors, check for unexpected properties
community.okd.k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
validate:
- fail_on_error: no
- strict: yes
-'''
+ fail_on_error: false
+ strict: true
+"""
-RETURN = r'''
+RETURN = r"""
result:
description:
- The created, patched, or otherwise present object. Will be empty in the case of a deletion.
@@ -254,22 +254,26 @@ result:
type: int
sample: 48
error:
- description: error while trying to create/delete the object.
+ description: Error while trying to create/delete the object.
returned: error
type: complex
-'''
+"""
# ENDREMOVE (downstream)
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
- NAME_ARG_SPEC, RESOURCE_ARG_SPEC, AUTH_ARG_SPEC, WAIT_ARG_SPEC, DELETE_OPTS_ARG_SPEC
+ NAME_ARG_SPEC,
+ RESOURCE_ARG_SPEC,
+ AUTH_ARG_SPEC,
+ WAIT_ARG_SPEC,
+ DELETE_OPTS_ARG_SPEC,
)
def validate_spec():
return dict(
- fail_on_error=dict(type='bool'),
+ fail_on_error=dict(type="bool"),
version=dict(),
- strict=dict(type='bool', default=True)
+ strict=dict(type="bool", default=True),
)
@@ -279,30 +283,41 @@ def argspec():
argument_spec.update(RESOURCE_ARG_SPEC)
argument_spec.update(AUTH_ARG_SPEC)
argument_spec.update(WAIT_ARG_SPEC)
- argument_spec['merge_type'] = dict(type='list', elements='str', choices=['json', 'merge', 'strategic-merge'])
- argument_spec['validate'] = dict(type='dict', default=None, options=validate_spec())
- argument_spec['append_hash'] = dict(type='bool', default=False)
- argument_spec['apply'] = dict(type='bool', default=False)
- argument_spec['template'] = dict(type='raw', default=None)
- argument_spec['delete_options'] = dict(type='dict', default=None, options=DELETE_OPTS_ARG_SPEC)
- argument_spec['continue_on_error'] = dict(type='bool', default=False)
- argument_spec['state'] = dict(default='present', choices=['present', 'absent', 'patched'])
- argument_spec['force'] = dict(type='bool', default=False)
+ argument_spec["merge_type"] = dict(
+ type="list", elements="str", choices=["json", "merge", "strategic-merge"]
+ )
+ argument_spec["validate"] = dict(type="dict", default=None, options=validate_spec())
+ argument_spec["append_hash"] = dict(type="bool", default=False)
+ argument_spec["apply"] = dict(type="bool", default=False)
+ argument_spec["template"] = dict(type="raw", default=None)
+ argument_spec["delete_options"] = dict(
+ type="dict", default=None, options=DELETE_OPTS_ARG_SPEC
+ )
+ argument_spec["continue_on_error"] = dict(type="bool", default=False)
+ argument_spec["state"] = dict(
+ default="present", choices=["present", "absent", "patched"]
+ )
+ argument_spec["force"] = dict(type="bool", default=False)
return argument_spec
def main():
mutually_exclusive = [
- ('resource_definition', 'src'),
- ('merge_type', 'apply'),
- ('template', 'resource_definition'),
- ('template', 'src'),
+ ("resource_definition", "src"),
+ ("merge_type", "apply"),
+ ("template", "resource_definition"),
+ ("template", "src"),
]
from ansible_collections.community.okd.plugins.module_utils.k8s import OKDRawModule
- module = OKDRawModule(argument_spec=argspec(), supports_check_mode=True, mutually_exclusive=mutually_exclusive)
+
+ module = OKDRawModule(
+ argument_spec=argspec(),
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ )
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_adm_groups_sync.py b/ansible_collections/community/okd/plugins/modules/openshift_adm_groups_sync.py
index 66b0fbb15..3f5f14be3 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_adm_groups_sync.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_adm_groups_sync.py
@@ -96,31 +96,31 @@ EXAMPLES = r"""
- name: Sync all groups from an LDAP server
openshift_adm_groups_sync:
src:
- kind: LDAPSyncConfig
- apiVersion: v1
- url: ldap://localhost:1390
- insecure: true
- bindDN: cn=admin,dc=example,dc=org
- bindPassword: adminpassword
- rfc2307:
- groupsQuery:
- baseDN: "cn=admins,ou=groups,dc=example,dc=org"
- scope: sub
- derefAliases: never
- filter: (objectClass=*)
- pageSize: 0
- groupUIDAttribute: dn
- groupNameAttributes: [ cn ]
- groupMembershipAttributes: [ member ]
- usersQuery:
- baseDN: "ou=users,dc=example,dc=org"
- scope: sub
- derefAliases: never
- pageSize: 0
- userUIDAttribute: dn
- userNameAttributes: [ mail ]
- tolerateMemberNotFoundErrors: true
- tolerateMemberOutOfScopeErrors: true
+ kind: LDAPSyncConfig
+ apiVersion: v1
+ url: ldap://localhost:1390
+ insecure: true
+ bindDN: cn=admin,dc=example,dc=org
+ bindPassword: adminpassword
+ rfc2307:
+ groupsQuery:
+ baseDN: "cn=admins,ou=groups,dc=example,dc=org"
+ scope: sub
+ derefAliases: never
+ filter: (objectClass=*)
+ pageSize: 0
+ groupUIDAttribute: dn
+ groupNameAttributes: [cn]
+ groupMembershipAttributes: [member]
+ usersQuery:
+ baseDN: "ou=users,dc=example,dc=org"
+ scope: sub
+ derefAliases: never
+ pageSize: 0
+ userUIDAttribute: dn
+ userNameAttributes: [mail]
+ tolerateMemberNotFoundErrors: true
+ tolerateMemberOutOfScopeErrors: true
# Sync all groups except the ones from the deny_groups from an LDAP server
- name: Sync all groups from an LDAP server using deny_groups
@@ -192,20 +192,21 @@ builds:
# ENDREMOVE (downstream)
import copy
-import traceback
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args.update(
dict(
- state=dict(type='str', choices=['absent', 'present'], default='present'),
- type=dict(type='str', choices=['ldap', 'openshift'], default='ldap'),
- sync_config=dict(type='dict', aliases=['config', 'src'], required=True),
- deny_groups=dict(type='list', elements='str', default=[]),
- allow_groups=dict(type='list', elements='str', default=[]),
+ state=dict(type="str", choices=["absent", "present"], default="present"),
+ type=dict(type="str", choices=["ldap", "openshift"], default="ldap"),
+ sync_config=dict(type="dict", aliases=["config", "src"], required=True),
+ deny_groups=dict(type="list", elements="str", default=[]),
+ allow_groups=dict(type="list", elements="str", default=[]),
)
)
return args
@@ -213,12 +214,14 @@ def argument_spec():
def main():
from ansible_collections.community.okd.plugins.module_utils.openshift_groups import (
- OpenshiftGroupsSync
+ OpenshiftGroupsSync,
)
- module = OpenshiftGroupsSync(argument_spec=argument_spec(), supports_check_mode=True)
+ module = OpenshiftGroupsSync(
+ argument_spec=argument_spec(), supports_check_mode=True
+ )
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_adm_migrate_template_instances.py b/ansible_collections/community/okd/plugins/modules/openshift_adm_migrate_template_instances.py
index 05d5563cd..ba3039d54 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_adm_migrate_template_instances.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_adm_migrate_template_instances.py
@@ -31,14 +31,14 @@ requirements:
"""
EXAMPLES = r"""
- - name: Migrate TemplateInstances in namespace=test
- community.okd.openshift_adm_migrate_template_instances:
- namespace: test
- register: _result
-
- - name: Migrate TemplateInstances in all namespaces
- community.okd.openshift_adm_migrate_template_instances:
- register: _result
+- name: Migrate TemplateInstances in namespace=test
+ community.okd.openshift_adm_migrate_template_instances:
+ namespace: test
+ register: _result
+
+- name: Migrate TemplateInstances in all namespaces
+ community.okd.openshift_adm_migrate_template_instances:
+ register: _result
"""
RETURN = r"""
@@ -235,7 +235,9 @@ result:
from ansible.module_utils._text import to_native
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
from kubernetes.dynamic.exceptions import DynamicApiError
@@ -339,9 +341,7 @@ class OpenShiftMigrateTemplateInstances(AnsibleOpenshiftModule):
if ti_to_be_migrated:
if self.check_mode:
- self.exit_json(
- **{"changed": True, "result": ti_to_be_migrated}
- )
+ self.exit_json(**{"changed": True, "result": ti_to_be_migrated})
else:
for ti_elem in ti_to_be_migrated:
results["result"].append(
@@ -363,7 +363,9 @@ def argspec():
def main():
argument_spec = argspec()
- module = OpenShiftMigrateTemplateInstances(argument_spec=argument_spec, supports_check_mode=True)
+ module = OpenShiftMigrateTemplateInstances(
+ argument_spec=argument_spec, supports_check_mode=True
+ )
module.run_module()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_auth.py b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_auth.py
index a9833fa50..fe0aec2c9 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_auth.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_auth.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_adm_prune_auth
@@ -58,9 +59,9 @@ options:
requirements:
- python >= 3.6
- kubernetes >= 12.0.0
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
- name: Prune all roles from default namespace
openshift_adm_prune_auth:
resource: roles
@@ -72,10 +73,10 @@ EXAMPLES = r'''
namespace: testing
label_selectors:
- phase=production
-'''
+"""
-RETURN = r'''
+RETURN = r"""
cluster_role_binding:
type: list
description: list of cluster role binding deleted.
@@ -96,37 +97,45 @@ group:
type: list
description: list of Security Context Constraints deleted.
returned: I(resource=users)
-'''
+"""
# ENDREMOVE (downstream)
import copy
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args.update(
dict(
- resource=dict(type='str', required=True, choices=['roles', 'clusterroles', 'users', 'groups']),
- namespace=dict(type='str'),
- name=dict(type='str'),
- label_selectors=dict(type='list', elements='str'),
+ resource=dict(
+ type="str",
+ required=True,
+ choices=["roles", "clusterroles", "users", "groups"],
+ ),
+ namespace=dict(type="str"),
+ name=dict(type="str"),
+ label_selectors=dict(type="list", elements="str"),
)
)
return args
def main():
-
from ansible_collections.community.okd.plugins.module_utils.openshift_adm_prune_auth import (
- OpenShiftAdmPruneAuth)
+ OpenShiftAdmPruneAuth,
+ )
- module = OpenShiftAdmPruneAuth(argument_spec=argument_spec(),
- mutually_exclusive=[("name", "label_selectors")],
- supports_check_mode=True)
+ module = OpenShiftAdmPruneAuth(
+ argument_spec=argument_spec(),
+ mutually_exclusive=[("name", "label_selectors")],
+ supports_check_mode=True,
+ )
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_builds.py b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_builds.py
index b0b831e6f..ffc86f16e 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_builds.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_builds.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_adm_prune_builds
@@ -45,14 +46,14 @@ options:
requirements:
- python >= 3.6
- kubernetes >= 12.0.0
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
# Run deleting older completed and failed builds and also including
# all builds whose associated BuildConfig no longer exists
- name: Run delete orphan Builds
community.okd.openshift_adm_prune_builds:
- orphans: True
+ orphans: true
# Run deleting older completed and failed builds keep younger than 2hours
- name: Run delete builds, keep younger than 2h
@@ -63,9 +64,9 @@ EXAMPLES = r'''
- name: Run delete builds from namespace
community.okd.openshift_adm_prune_builds:
namespace: testing_namespace
-'''
+"""
-RETURN = r'''
+RETURN = r"""
builds:
description:
- The builds that were deleted
@@ -92,33 +93,38 @@ builds:
description: Current status details for the object.
returned: success
type: dict
-'''
+"""
# ENDREMOVE (downstream)
import copy
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args.update(
dict(
- namespace=dict(type='str'),
- keep_younger_than=dict(type='int'),
- orphans=dict(type='bool', default=False),
+ namespace=dict(type="str"),
+ keep_younger_than=dict(type="int"),
+ orphans=dict(type="bool", default=False),
)
)
return args
def main():
+ from ansible_collections.community.okd.plugins.module_utils.openshift_builds import (
+ OpenShiftPruneBuilds,
+ )
- from ansible_collections.community.okd.plugins.module_utils.openshift_builds import OpenShiftPruneBuilds
-
- module = OpenShiftPruneBuilds(argument_spec=argument_spec(), supports_check_mode=True)
+ module = OpenShiftPruneBuilds(
+ argument_spec=argument_spec(), supports_check_mode=True
+ )
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_deployments.py b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_deployments.py
index bdef18460..963e3c94c 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_deployments.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_deployments.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_adm_prune_deployments
@@ -45,32 +46,34 @@ options:
requirements:
- python >= 3.6
- kubernetes >= 12.0.0
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
- name: Prune Deployments from testing namespace
community.okd.openshift_adm_prune_deployments:
namespace: testing
- name: Prune orphans deployments, keep younger than 2hours
community.okd.openshift_adm_prune_deployments:
- orphans: True
+ orphans: true
keep_younger_than: 120
-'''
+"""
-RETURN = r'''
+RETURN = r"""
replication_controllers:
type: list
description: list of replication controllers candidate for pruning.
returned: always
-'''
+"""
# ENDREMOVE (downstream)
import copy
try:
- from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+ from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+ )
except ImportError as e:
pass
@@ -79,22 +82,28 @@ def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args.update(
dict(
- namespace=dict(type='str',),
- keep_younger_than=dict(type='int',),
- orphans=dict(type='bool', default=False),
+ namespace=dict(
+ type="str",
+ ),
+ keep_younger_than=dict(
+ type="int",
+ ),
+ orphans=dict(type="bool", default=False),
)
)
return args
def main():
-
from ansible_collections.community.okd.plugins.module_utils.openshift_adm_prune_deployments import (
- OpenShiftAdmPruneDeployment)
+ OpenShiftAdmPruneDeployment,
+ )
- module = OpenShiftAdmPruneDeployment(argument_spec=argument_spec(), supports_check_mode=True)
+ module = OpenShiftAdmPruneDeployment(
+ argument_spec=argument_spec(), supports_check_mode=True
+ )
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_images.py b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_images.py
index d470fa871..41bd5c4f2 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_images.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_adm_prune_images.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_adm_prune_images
@@ -84,9 +85,9 @@ requirements:
- python >= 3.6
- kubernetes >= 12.0.0
- docker-image-py
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
# Prune if only images and their referrers were more than an hour old
- name: Prune image with referrer been more than an hour old
community.okd.openshift_adm_prune_images:
@@ -102,10 +103,10 @@ EXAMPLES = r'''
community.okd.openshift_adm_prune_images:
registry_url: http://registry.example.org
registry_validate_certs: false
-'''
+"""
-RETURN = r'''
+RETURN = r"""
updated_image_streams:
description:
- The images streams updated.
@@ -275,41 +276,44 @@ deleted_images:
},
...
]
-'''
+"""
# ENDREMOVE (downstream)
import copy
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args.update(
dict(
- namespace=dict(type='str'),
- all_images=dict(type='bool', default=True),
- keep_younger_than=dict(type='int'),
- prune_over_size_limit=dict(type='bool', default=False),
- registry_url=dict(type='str'),
- registry_validate_certs=dict(type='bool'),
- registry_ca_cert=dict(type='path'),
- prune_registry=dict(type='bool', default=True),
- ignore_invalid_refs=dict(type='bool', default=False),
+ namespace=dict(type="str"),
+ all_images=dict(type="bool", default=True),
+ keep_younger_than=dict(type="int"),
+ prune_over_size_limit=dict(type="bool", default=False),
+ registry_url=dict(type="str"),
+ registry_validate_certs=dict(type="bool"),
+ registry_ca_cert=dict(type="path"),
+ prune_registry=dict(type="bool", default=True),
+ ignore_invalid_refs=dict(type="bool", default=False),
)
)
return args
def main():
-
from ansible_collections.community.okd.plugins.module_utils.openshift_adm_prune_images import (
- OpenShiftAdmPruneImages
+ OpenShiftAdmPruneImages,
)
- module = OpenShiftAdmPruneImages(argument_spec=argument_spec(), supports_check_mode=True)
+ module = OpenShiftAdmPruneImages(
+ argument_spec=argument_spec(), supports_check_mode=True
+ )
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_auth.py b/ansible_collections/community/okd/plugins/modules/openshift_auth.py
index 422018cc5..4fdb16965 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_auth.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_auth.py
@@ -5,9 +5,10 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_auth
@@ -74,46 +75,49 @@ requirements:
- urllib3
- requests
- requests-oauthlib
-'''
+"""
-EXAMPLES = r'''
-- hosts: localhost
+EXAMPLES = r"""
+- name: Example Playbook
+ hosts: localhost
module_defaults:
group/community.okd.okd:
host: https://k8s.example.com/
ca_cert: ca.pem
tasks:
- - block:
- # It's good practice to store login credentials in a secure vault and not
- # directly in playbooks.
- - include_vars: openshift_passwords.yml
-
- - name: Log in (obtain access token)
- community.okd.openshift_auth:
- username: admin
- password: "{{ openshift_admin_password }}"
- register: openshift_auth_results
-
- # Previous task provides the token/api_key, while all other parameters
- # are taken from module_defaults
- - name: Get a list of all pods from any namespace
- kubernetes.core.k8s_info:
- api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
- kind: Pod
- register: pod_list
-
- always:
- - name: If login succeeded, try to log out (revoke access token)
- when: openshift_auth_results.openshift_auth.api_key is defined
- community.okd.openshift_auth:
- state: absent
- api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
-'''
+ - name: Authenticate to OpenShift cluster and gell a list of all pods from any namespace
+ block:
+ # It's good practice to store login credentials in a secure vault and not
+ # directly in playbooks.
+ - name: Include 'openshift_passwords.yml'
+ ansible.builtin.include_vars: openshift_passwords.yml
+
+ - name: Log in (obtain access token)
+ community.okd.openshift_auth:
+ username: admin
+ password: "{{ openshift_admin_password }}"
+ register: openshift_auth_results
+
+ # Previous task provides the token/api_key, while all other parameters
+ # are taken from module_defaults
+ - name: Get a list of all pods from any namespace
+ kubernetes.core.k8s_info:
+ api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
+ kind: Pod
+ register: pod_list
+
+ always:
+ - name: If login succeeded, try to log out (revoke access token)
+ when: openshift_auth_results.openshift_auth.api_key is defined
+ community.okd.openshift_auth:
+ state: absent
+ api_key: "{{ openshift_auth_results.openshift_auth.api_key }}"
+"""
# Returned value names need to match k8s modules parameter names, to make it
# easy to pass returned values of openshift_auth to other k8s modules.
# Discussion: https://github.com/ansible/ansible/pull/50807#discussion_r248827899
-RETURN = r'''
+RETURN = r"""
openshift_auth:
description: OpenShift authentication facts.
returned: success
@@ -164,7 +168,7 @@ k8s_auth:
description: Username for authenticating with the API server.
returned: success
type: str
-'''
+"""
import traceback
@@ -179,52 +183,52 @@ import hashlib
# 3rd party imports
try:
import requests
+
HAS_REQUESTS = True
except ImportError:
HAS_REQUESTS = False
try:
from requests_oauthlib import OAuth2Session
+
HAS_REQUESTS_OAUTH = True
except ImportError:
HAS_REQUESTS_OAUTH = False
try:
from urllib3.util import make_headers
+
HAS_URLLIB3 = True
except ImportError:
HAS_URLLIB3 = False
K8S_AUTH_ARG_SPEC = {
- 'state': {
- 'default': 'present',
- 'choices': ['present', 'absent'],
- },
- 'host': {'required': True},
- 'username': {},
- 'password': {'no_log': True},
- 'ca_cert': {'type': 'path', 'aliases': ['ssl_ca_cert']},
- 'validate_certs': {
- 'type': 'bool',
- 'default': True,
- 'aliases': ['verify_ssl']
+ "state": {
+ "default": "present",
+ "choices": ["present", "absent"],
},
- 'api_key': {'no_log': True},
+ "host": {"required": True},
+ "username": {},
+ "password": {"no_log": True},
+ "ca_cert": {"type": "path", "aliases": ["ssl_ca_cert"]},
+ "validate_certs": {"type": "bool", "default": True, "aliases": ["verify_ssl"]},
+ "api_key": {"no_log": True},
}
def get_oauthaccesstoken_objectname_from_token(token_name):
-
"""
- openshift convert the access token to an OAuthAccessToken resource name using the algorithm
- https://github.com/openshift/console/blob/9f352ba49f82ad693a72d0d35709961428b43b93/pkg/server/server.go#L609-L613
+ openshift convert the access token to an OAuthAccessToken resource name using the algorithm
+ https://github.com/openshift/console/blob/9f352ba49f82ad693a72d0d35709961428b43b93/pkg/server/server.go#L609-L613
"""
sha256Prefix = "sha256~"
content = token_name.strip(sha256Prefix)
- b64encoded = urlsafe_b64encode(hashlib.sha256(content.encode()).digest()).rstrip(b'=')
+ b64encoded = urlsafe_b64encode(hashlib.sha256(content.encode()).digest()).rstrip(
+ b"="
+ )
return sha256Prefix + b64encoded.decode("utf-8")
@@ -234,42 +238,48 @@ class OpenShiftAuthModule(AnsibleModule):
self,
argument_spec=K8S_AUTH_ARG_SPEC,
required_if=[
- ('state', 'present', ['username', 'password']),
- ('state', 'absent', ['api_key']),
- ]
+ ("state", "present", ["username", "password"]),
+ ("state", "absent", ["api_key"]),
+ ],
)
if not HAS_REQUESTS:
- self.fail("This module requires the python 'requests' package. Try `pip install requests`.")
+ self.fail(
+ "This module requires the python 'requests' package. Try `pip install requests`."
+ )
if not HAS_REQUESTS_OAUTH:
- self.fail("This module requires the python 'requests-oauthlib' package. Try `pip install requests-oauthlib`.")
+ self.fail(
+ "This module requires the python 'requests-oauthlib' package. Try `pip install requests-oauthlib`."
+ )
if not HAS_URLLIB3:
- self.fail("This module requires the python 'urllib3' package. Try `pip install urllib3`.")
+ self.fail(
+ "This module requires the python 'urllib3' package. Try `pip install urllib3`."
+ )
def execute_module(self):
- state = self.params.get('state')
- verify_ssl = self.params.get('validate_certs')
- ssl_ca_cert = self.params.get('ca_cert')
+ state = self.params.get("state")
+ verify_ssl = self.params.get("validate_certs")
+ ssl_ca_cert = self.params.get("ca_cert")
- self.auth_username = self.params.get('username')
- self.auth_password = self.params.get('password')
- self.auth_api_key = self.params.get('api_key')
- self.con_host = self.params.get('host')
+ self.auth_username = self.params.get("username")
+ self.auth_password = self.params.get("password")
+ self.auth_api_key = self.params.get("api_key")
+ self.con_host = self.params.get("host")
# python-requests takes either a bool or a path to a ca file as the 'verify' param
if verify_ssl and ssl_ca_cert:
self.con_verify_ca = ssl_ca_cert # path
else:
- self.con_verify_ca = verify_ssl # bool
+ self.con_verify_ca = verify_ssl # bool
# Get needed info to access authorization APIs
self.openshift_discover()
changed = False
result = dict()
- if state == 'present':
+ if state == "present":
new_api_key = self.openshift_login()
result = dict(
host=self.con_host,
@@ -285,87 +295,114 @@ class OpenShiftAuthModule(AnsibleModule):
self.exit_json(changed=changed, openshift_auth=result, k8s_auth=result)
def openshift_discover(self):
- url = urljoin(self.con_host, '.well-known/oauth-authorization-server')
+ url = urljoin(self.con_host, ".well-known/oauth-authorization-server")
ret = requests.get(url, verify=self.con_verify_ca)
if ret.status_code != 200:
- self.fail_request("Couldn't find OpenShift's OAuth API", method='GET', url=url,
- reason=ret.reason, status_code=ret.status_code)
+ self.fail_request(
+ "Couldn't find OpenShift's OAuth API",
+ method="GET",
+ url=url,
+ reason=ret.reason,
+ status_code=ret.status_code,
+ )
try:
oauth_info = ret.json()
- self.openshift_auth_endpoint = oauth_info['authorization_endpoint']
- self.openshift_token_endpoint = oauth_info['token_endpoint']
+ self.openshift_auth_endpoint = oauth_info["authorization_endpoint"]
+ self.openshift_token_endpoint = oauth_info["token_endpoint"]
except Exception:
- self.fail_json(msg="Something went wrong discovering OpenShift OAuth details.",
- exception=traceback.format_exc())
+ self.fail_json(
+ msg="Something went wrong discovering OpenShift OAuth details.",
+ exception=traceback.format_exc(),
+ )
def openshift_login(self):
- os_oauth = OAuth2Session(client_id='openshift-challenging-client')
- authorization_url, state = os_oauth.authorization_url(self.openshift_auth_endpoint,
- state="1", code_challenge_method='S256')
- auth_headers = make_headers(basic_auth='{0}:{1}'.format(self.auth_username, self.auth_password))
+ os_oauth = OAuth2Session(client_id="openshift-challenging-client")
+ authorization_url, state = os_oauth.authorization_url(
+ self.openshift_auth_endpoint, state="1", code_challenge_method="S256"
+ )
+ auth_headers = make_headers(
+ basic_auth="{0}:{1}".format(self.auth_username, self.auth_password)
+ )
# Request authorization code using basic auth credentials
ret = os_oauth.get(
authorization_url,
- headers={'X-Csrf-Token': state, 'authorization': auth_headers.get('authorization')},
+ headers={
+ "X-Csrf-Token": state,
+ "authorization": auth_headers.get("authorization"),
+ },
verify=self.con_verify_ca,
- allow_redirects=False
+ allow_redirects=False,
)
if ret.status_code != 302:
- self.fail_request("Authorization failed.", method='GET', url=authorization_url,
- reason=ret.reason, status_code=ret.status_code)
+ self.fail_request(
+ "Authorization failed.",
+ method="GET",
+ url=authorization_url,
+ reason=ret.reason,
+ status_code=ret.status_code,
+ )
# In here we have `code` and `state`, I think `code` is the important one
qwargs = {}
- for k, v in parse_qs(urlparse(ret.headers['Location']).query).items():
+ for k, v in parse_qs(urlparse(ret.headers["Location"]).query).items():
qwargs[k] = v[0]
- qwargs['grant_type'] = 'authorization_code'
+ qwargs["grant_type"] = "authorization_code"
# Using authorization code given to us in the Location header of the previous request, request a token
ret = os_oauth.post(
self.openshift_token_endpoint,
headers={
- 'Accept': 'application/json',
- 'Content-Type': 'application/x-www-form-urlencoded',
+ "Accept": "application/json",
+ "Content-Type": "application/x-www-form-urlencoded",
# This is just base64 encoded 'openshift-challenging-client:'
- 'Authorization': 'Basic b3BlbnNoaWZ0LWNoYWxsZW5naW5nLWNsaWVudDo='
+ "Authorization": "Basic b3BlbnNoaWZ0LWNoYWxsZW5naW5nLWNsaWVudDo=",
},
data=urlencode(qwargs),
- verify=self.con_verify_ca
+ verify=self.con_verify_ca,
)
if ret.status_code != 200:
- self.fail_request("Failed to obtain an authorization token.", method='POST',
- url=self.openshift_token_endpoint,
- reason=ret.reason, status_code=ret.status_code)
+ self.fail_request(
+ "Failed to obtain an authorization token.",
+ method="POST",
+ url=self.openshift_token_endpoint,
+ reason=ret.reason,
+ status_code=ret.status_code,
+ )
- return ret.json()['access_token']
+ return ret.json()["access_token"]
def openshift_logout(self):
-
name = get_oauthaccesstoken_objectname_from_token(self.auth_api_key)
headers = {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json',
- 'Authorization': "Bearer {0}".format(self.auth_api_key)
+ "Accept": "application/json",
+ "Content-Type": "application/json",
+ "Authorization": "Bearer {0}".format(self.auth_api_key),
}
- url = "{0}/apis/oauth.openshift.io/v1/useroauthaccesstokens/{1}".format(self.con_host, name)
+ url = "{0}/apis/oauth.openshift.io/v1/useroauthaccesstokens/{1}".format(
+ self.con_host, name
+ )
json = {
"apiVersion": "oauth.openshift.io/v1",
"kind": "DeleteOptions",
- "gracePeriodSeconds": 0
+ "gracePeriodSeconds": 0,
}
- ret = requests.delete(url, json=json, verify=self.con_verify_ca, headers=headers)
+ ret = requests.delete(
+ url, json=json, verify=self.con_verify_ca, headers=headers
+ )
if ret.status_code != 200:
self.fail_json(
- msg="Couldn't delete user oauth access token '{0}' due to: {1}".format(name, ret.json().get("message")),
- status_code=ret.status_code
+ msg="Couldn't delete user oauth access token '{0}' due to: {1}".format(
+ name, ret.json().get("message")
+ ),
+ status_code=ret.status_code,
)
return True
@@ -376,7 +413,7 @@ class OpenShiftAuthModule(AnsibleModule):
def fail_request(self, msg, **kwargs):
req_info = {}
for k, v in kwargs.items():
- req_info['req_' + k] = v
+ req_info["req_" + k] = v
self.fail_json(msg=msg, **req_info)
@@ -388,5 +425,5 @@ def main():
module.fail_json(msg=str(e), exception=traceback.format_exc())
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_build.py b/ansible_collections/community/okd/plugins/modules/openshift_build.py
index 1259a102c..b397e237c 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_build.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_build.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_build
@@ -134,9 +135,9 @@ options:
requirements:
- python >= 3.6
- kubernetes >= 12.0.0
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
# Starts build from build config default/hello-world
- name: Starts build from build config
community.okd.openshift_build:
@@ -171,9 +172,9 @@ EXAMPLES = r'''
build_phases:
- New
state: cancelled
-'''
+"""
-RETURN = r'''
+RETURN = r"""
builds:
description:
- The builds that were started/cancelled.
@@ -200,37 +201,47 @@ builds:
description: Current status details for the object.
returned: success
type: dict
-'''
+"""
# ENDREMOVE (downstream)
import copy
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args_options = dict(
- name=dict(type='str', required=True),
- value=dict(type='str', required=True)
+ name=dict(type="str", required=True), value=dict(type="str", required=True)
)
args.update(
dict(
- state=dict(type='str', choices=['started', 'cancelled', 'restarted'], default="started"),
- build_args=dict(type='list', elements='dict', options=args_options),
- commit=dict(type='str'),
- env_vars=dict(type='list', elements='dict', options=args_options),
- build_name=dict(type='str'),
- build_config_name=dict(type='str'),
- namespace=dict(type='str', required=True),
- incremental=dict(type='bool'),
- no_cache=dict(type='bool'),
- wait=dict(type='bool', default=False),
- wait_sleep=dict(type='int', default=5),
- wait_timeout=dict(type='int', default=120),
- build_phases=dict(type='list', elements='str', default=[], choices=["New", "Pending", "Running"]),
+ state=dict(
+ type="str",
+ choices=["started", "cancelled", "restarted"],
+ default="started",
+ ),
+ build_args=dict(type="list", elements="dict", options=args_options),
+ commit=dict(type="str"),
+ env_vars=dict(type="list", elements="dict", options=args_options),
+ build_name=dict(type="str"),
+ build_config_name=dict(type="str"),
+ namespace=dict(type="str", required=True),
+ incremental=dict(type="bool"),
+ no_cache=dict(type="bool"),
+ wait=dict(type="bool", default=False),
+ wait_sleep=dict(type="int", default=5),
+ wait_timeout=dict(type="int", default=120),
+ build_phases=dict(
+ type="list",
+ elements="str",
+ default=[],
+ choices=["New", "Pending", "Running"],
+ ),
)
)
return args
@@ -238,23 +249,24 @@ def argument_spec():
def main():
mutually_exclusive = [
- ('build_name', 'build_config_name'),
+ ("build_name", "build_config_name"),
]
from ansible_collections.community.okd.plugins.module_utils.openshift_builds import (
- OpenShiftBuilds
+ OpenShiftBuilds,
)
+
module = OpenShiftBuilds(
argument_spec=argument_spec(),
mutually_exclusive=mutually_exclusive,
required_one_of=[
[
- 'build_name',
- 'build_config_name',
+ "build_name",
+ "build_config_name",
]
],
)
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_import_image.py b/ansible_collections/community/okd/plugins/modules/openshift_import_image.py
index df0588cf4..e5f371b67 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_import_image.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_import_image.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_import_image
@@ -75,9 +76,9 @@ requirements:
- python >= 3.6
- kubernetes >= 12.0.0
- docker-image-py
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
# Import tag latest into a new image stream.
- name: Import tag latest into new image stream
community.okd.openshift_import_image:
@@ -122,10 +123,10 @@ EXAMPLES = r'''
- mystream3
source: registry.io/repo/image:latest
all: true
-'''
+"""
-RETURN = r'''
+RETURN = r"""
result:
description:
- List with all ImageStreamImport that have been created.
@@ -153,42 +154,44 @@ result:
description: Current status details for the object.
returned: success
type: dict
-'''
+"""
# ENDREMOVE (downstream)
import copy
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
args.update(
dict(
- namespace=dict(type='str', required=True),
- name=dict(type='raw', required=True),
- all=dict(type='bool', default=False),
- validate_registry_certs=dict(type='bool'),
- reference_policy=dict(type='str', choices=["source", "local"], default="source"),
- scheduled=dict(type='bool', default=False),
- source=dict(type='str'),
+ namespace=dict(type="str", required=True),
+ name=dict(type="raw", required=True),
+ all=dict(type="bool", default=False),
+ validate_registry_certs=dict(type="bool"),
+ reference_policy=dict(
+ type="str", choices=["source", "local"], default="source"
+ ),
+ scheduled=dict(type="bool", default=False),
+ source=dict(type="str"),
)
)
return args
def main():
-
from ansible_collections.community.okd.plugins.module_utils.openshift_import_image import (
- OpenShiftImportImage
+ OpenShiftImportImage,
)
module = OpenShiftImportImage(
- argument_spec=argument_spec(),
- supports_check_mode=True
+ argument_spec=argument_spec(), supports_check_mode=True
)
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_process.py b/ansible_collections/community/okd/plugins/modules/openshift_process.py
index fb00ffbba..01b1bda0f 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_process.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_process.py
@@ -2,13 +2,14 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# Copyright (c) 2020-2021, Red Hat
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_process
short_description: Process an OpenShift template.openshift.io/v1 Template
@@ -49,6 +50,7 @@ options:
description:
- The namespace that resources should be created, updated, or deleted in.
- Only used when I(state) is present or absent.
+ type: str
parameters:
description:
- 'A set of key: value pairs that will be used to set/override values in the Template.'
@@ -70,9 +72,9 @@ options:
type: str
default: rendered
choices: [ absent, present, rendered ]
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
- name: Process a template in the cluster
community.okd.openshift_process:
name: nginx-example
@@ -87,8 +89,8 @@ EXAMPLES = r'''
community.okd.k8s:
namespace: default
definition: '{{ item }}'
- wait: yes
- apply: yes
+ wait: true
+ apply: true
loop: '{{ result.resources }}'
- name: Process a template with parameters from an env file and create the resources
@@ -98,7 +100,7 @@ EXAMPLES = r'''
namespace_target: default
parameter_file: 'files/nginx.env'
state: present
- wait: yes
+ wait: true
- name: Process a local template and create the resources
community.okd.openshift_process:
@@ -113,10 +115,10 @@ EXAMPLES = r'''
parameter_file: files/example.env
namespace_target: default
state: absent
- wait: yes
-'''
+ wait: true
+"""
-RETURN = r'''
+RETURN = r"""
result:
description:
- The created, patched, or otherwise present object. Will be empty in the case of a deletion.
@@ -200,11 +202,13 @@ resources:
conditions:
type: complex
description: Array of status conditions for the object. Not guaranteed to be present
-'''
+"""
# ENDREMOVE (downstream)
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
- AUTH_ARG_SPEC, RESOURCE_ARG_SPEC, WAIT_ARG_SPEC
+ AUTH_ARG_SPEC,
+ RESOURCE_ARG_SPEC,
+ WAIT_ARG_SPEC,
)
@@ -213,24 +217,26 @@ def argspec():
argument_spec.update(AUTH_ARG_SPEC)
argument_spec.update(WAIT_ARG_SPEC)
argument_spec.update(RESOURCE_ARG_SPEC)
- argument_spec['state'] = dict(type='str', default='rendered', choices=['present', 'absent', 'rendered'])
- argument_spec['namespace'] = dict(type='str')
- argument_spec['namespace_target'] = dict(type='str')
- argument_spec['parameters'] = dict(type='dict')
- argument_spec['name'] = dict(type='str')
- argument_spec['parameter_file'] = dict(type='str')
+ argument_spec["state"] = dict(
+ type="str", default="rendered", choices=["present", "absent", "rendered"]
+ )
+ argument_spec["namespace"] = dict(type="str")
+ argument_spec["namespace_target"] = dict(type="str")
+ argument_spec["parameters"] = dict(type="dict")
+ argument_spec["name"] = dict(type="str")
+ argument_spec["parameter_file"] = dict(type="str")
return argument_spec
def main():
-
from ansible_collections.community.okd.plugins.module_utils.openshift_process import (
- OpenShiftProcess)
+ OpenShiftProcess,
+ )
module = OpenShiftProcess(argument_spec=argspec(), supports_check_mode=True)
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_registry_info.py b/ansible_collections/community/okd/plugins/modules/openshift_registry_info.py
index a455ac50b..2693d2534 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_registry_info.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_registry_info.py
@@ -5,10 +5,11 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_registry_info
@@ -40,9 +41,9 @@ requirements:
- python >= 3.6
- kubernetes >= 12.0.0
- docker-image-py
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
# Get registry information
- name: Read integrated registry information
community.okd.openshift_registry_info:
@@ -50,11 +51,11 @@ EXAMPLES = r'''
# Read registry integrated information and attempt to contact using local client.
- name: Attempt to contact integrated registry using local client
community.okd.openshift_registry_info:
- check: yes
-'''
+ check: true
+"""
-RETURN = r'''
+RETURN = r"""
internal_hostname:
description:
- The internal registry hostname.
@@ -79,36 +80,30 @@ check:
description: message describing the ping operation.
returned: always
type: str
-'''
+"""
# ENDREMOVE (downstream)
import copy
-from ansible_collections.kubernetes.core.plugins.module_utils.args_common import AUTH_ARG_SPEC
+from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
+ AUTH_ARG_SPEC,
+)
def argument_spec():
args = copy.deepcopy(AUTH_ARG_SPEC)
- args.update(
- dict(
- check=dict(type='bool', default=False)
- )
- )
+ args.update(dict(check=dict(type="bool", default=False)))
return args
def main():
-
from ansible_collections.community.okd.plugins.module_utils.openshift_registry import (
- OpenShiftRegistry
+ OpenShiftRegistry,
)
- module = OpenShiftRegistry(
- argument_spec=argument_spec(),
- supports_check_mode=True
- )
+ module = OpenShiftRegistry(argument_spec=argument_spec(), supports_check_mode=True)
module.run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/plugins/modules/openshift_route.py b/ansible_collections/community/okd/plugins/modules/openshift_route.py
index e452fc534..ea73db767 100644
--- a/ansible_collections/community/okd/plugins/modules/openshift_route.py
+++ b/ansible_collections/community/okd/plugins/modules/openshift_route.py
@@ -9,7 +9,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
# STARTREMOVE (downstream)
-DOCUMENTATION = r'''
+DOCUMENTATION = r"""
module: openshift_route
short_description: Expose a Service as an OpenShift Route.
@@ -133,9 +133,9 @@ options:
- insecure
default: insecure
type: str
-'''
+"""
-EXAMPLES = r'''
+EXAMPLES = r"""
- name: Create hello-world deployment
community.okd.k8s:
definition:
@@ -155,10 +155,10 @@ EXAMPLES = r'''
app: hello-kubernetes
spec:
containers:
- - name: hello-kubernetes
- image: paulbouwer/hello-kubernetes:1.8
- ports:
- - containerPort: 8080
+ - name: hello-kubernetes
+ image: paulbouwer/hello-kubernetes:1.8
+ ports:
+ - containerPort: 8080
- name: Create Service for the hello-world deployment
community.okd.k8s:
@@ -170,8 +170,8 @@ EXAMPLES = r'''
namespace: default
spec:
ports:
- - port: 80
- targetPort: 8080
+ - port: 80
+ targetPort: 8080
selector:
app: hello-kubernetes
@@ -183,9 +183,9 @@ EXAMPLES = r'''
annotations:
haproxy.router.openshift.io/balance: roundrobin
register: route
-'''
+"""
-RETURN = r'''
+RETURN = r"""
result:
description:
- The Route object that was created or updated. Will be empty in the case of deletion.
@@ -303,20 +303,28 @@ duration:
returned: when C(wait) is true
type: int
sample: 48
-'''
+"""
# ENDREMOVE (downstream)
import copy
from ansible.module_utils._text import to_native
-from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
+from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
+ AnsibleOpenshiftModule,
+)
try:
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.runner import perform_action
- from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import Waiter
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.runner import (
+ perform_action,
+ )
+ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import (
+ Waiter,
+ )
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
- AUTH_ARG_SPEC, WAIT_ARG_SPEC, COMMON_ARG_SPEC
+ AUTH_ARG_SPEC,
+ WAIT_ARG_SPEC,
+ COMMON_ARG_SPEC,
)
except ImportError as e:
pass
@@ -329,7 +337,6 @@ except ImportError:
class OpenShiftRoute(AnsibleOpenshiftModule):
-
def __init__(self):
super(OpenShiftRoute, self).__init__(
argument_spec=self.argspec,
@@ -339,7 +346,7 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
self.append_hash = False
self.apply = False
self.warnings = []
- self.params['merge_type'] = None
+ self.params["merge_type"] = None
@property
def argspec(self):
@@ -347,80 +354,95 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
spec.update(copy.deepcopy(WAIT_ARG_SPEC))
spec.update(copy.deepcopy(COMMON_ARG_SPEC))
- spec['service'] = dict(type='str', aliases=['svc'])
- spec['namespace'] = dict(required=True, type='str')
- spec['labels'] = dict(type='dict')
- spec['name'] = dict(type='str')
- spec['hostname'] = dict(type='str')
- spec['path'] = dict(type='str')
- spec['wildcard_policy'] = dict(choices=['Subdomain'], type='str')
- spec['port'] = dict(type='str')
- spec['tls'] = dict(type='dict', options=dict(
- ca_certificate=dict(type='str'),
- certificate=dict(type='str'),
- destination_ca_certificate=dict(type='str'),
- key=dict(type='str', no_log=False),
- insecure_policy=dict(type='str', choices=['allow', 'redirect', 'disallow'], default='disallow'),
- ))
- spec['termination'] = dict(choices=['edge', 'passthrough', 'reencrypt', 'insecure'], default='insecure')
- spec['annotations'] = dict(type='dict')
+ spec["service"] = dict(type="str", aliases=["svc"])
+ spec["namespace"] = dict(required=True, type="str")
+ spec["labels"] = dict(type="dict")
+ spec["name"] = dict(type="str")
+ spec["hostname"] = dict(type="str")
+ spec["path"] = dict(type="str")
+ spec["wildcard_policy"] = dict(choices=["Subdomain"], type="str")
+ spec["port"] = dict(type="str")
+ spec["tls"] = dict(
+ type="dict",
+ options=dict(
+ ca_certificate=dict(type="str"),
+ certificate=dict(type="str"),
+ destination_ca_certificate=dict(type="str"),
+ key=dict(type="str", no_log=False),
+ insecure_policy=dict(
+ type="str",
+ choices=["allow", "redirect", "disallow"],
+ default="disallow",
+ ),
+ ),
+ )
+ spec["termination"] = dict(
+ choices=["edge", "passthrough", "reencrypt", "insecure"], default="insecure"
+ )
+ spec["annotations"] = dict(type="dict")
return spec
def execute_module(self):
-
- service_name = self.params.get('service')
- namespace = self.params['namespace']
- termination_type = self.params.get('termination')
- if termination_type == 'insecure':
+ service_name = self.params.get("service")
+ namespace = self.params["namespace"]
+ termination_type = self.params.get("termination")
+ if termination_type == "insecure":
termination_type = None
- state = self.params.get('state')
+ state = self.params.get("state")
- if state != 'absent' and not service_name:
+ if state != "absent" and not service_name:
self.fail_json("If 'state' is not 'absent' then 'service' must be provided")
# We need to do something a little wonky to wait if the user doesn't supply a custom condition
- custom_wait = self.params.get('wait') and not self.params.get('wait_condition') and state != 'absent'
+ custom_wait = (
+ self.params.get("wait")
+ and not self.params.get("wait_condition")
+ and state != "absent"
+ )
if custom_wait:
# Don't use default wait logic in perform_action
- self.params['wait'] = False
-
- route_name = self.params.get('name') or service_name
- labels = self.params.get('labels')
- hostname = self.params.get('hostname')
- path = self.params.get('path')
- wildcard_policy = self.params.get('wildcard_policy')
- port = self.params.get('port')
- annotations = self.params.get('annotations')
-
- if termination_type and self.params.get('tls'):
- tls_ca_cert = self.params['tls'].get('ca_certificate')
- tls_cert = self.params['tls'].get('certificate')
- tls_dest_ca_cert = self.params['tls'].get('destination_ca_certificate')
- tls_key = self.params['tls'].get('key')
- tls_insecure_policy = self.params['tls'].get('insecure_policy')
- if tls_insecure_policy == 'disallow':
+ self.params["wait"] = False
+
+ route_name = self.params.get("name") or service_name
+ labels = self.params.get("labels")
+ hostname = self.params.get("hostname")
+ path = self.params.get("path")
+ wildcard_policy = self.params.get("wildcard_policy")
+ port = self.params.get("port")
+ annotations = self.params.get("annotations")
+
+ if termination_type and self.params.get("tls"):
+ tls_ca_cert = self.params["tls"].get("ca_certificate")
+ tls_cert = self.params["tls"].get("certificate")
+ tls_dest_ca_cert = self.params["tls"].get("destination_ca_certificate")
+ tls_key = self.params["tls"].get("key")
+ tls_insecure_policy = self.params["tls"].get("insecure_policy")
+ if tls_insecure_policy == "disallow":
tls_insecure_policy = None
else:
- tls_ca_cert = tls_cert = tls_dest_ca_cert = tls_key = tls_insecure_policy = None
+ tls_ca_cert = (
+ tls_cert
+ ) = tls_dest_ca_cert = tls_key = tls_insecure_policy = None
route = {
- 'apiVersion': 'route.openshift.io/v1',
- 'kind': 'Route',
- 'metadata': {
- 'name': route_name,
- 'namespace': namespace,
- 'labels': labels,
+ "apiVersion": "route.openshift.io/v1",
+ "kind": "Route",
+ "metadata": {
+ "name": route_name,
+ "namespace": namespace,
+ "labels": labels,
},
- 'spec': {}
+ "spec": {},
}
if annotations:
- route['metadata']['annotations'] = annotations
+ route["metadata"]["annotations"] = annotations
- if state != 'absent':
- route['spec'] = self.build_route_spec(
- service_name, namespace,
+ if state != "absent":
+ route["spec"] = self.build_route_spec(
+ service_name,
+ namespace,
port=port,
wildcard_policy=wildcard_policy,
hostname=hostname,
@@ -434,79 +456,120 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
)
result = perform_action(self.svc, route, self.params)
- timeout = self.params.get('wait_timeout')
- sleep = self.params.get('wait_sleep')
+ timeout = self.params.get("wait_timeout")
+ sleep = self.params.get("wait_sleep")
if custom_wait:
- v1_routes = self.find_resource('Route', 'route.openshift.io/v1', fail=True)
+ v1_routes = self.find_resource("Route", "route.openshift.io/v1", fail=True)
waiter = Waiter(self.client, v1_routes, wait_predicate)
- success, result['result'], result['duration'] = waiter.wait(timeout=timeout, sleep=sleep, name=route_name, namespace=namespace)
+ success, result["result"], result["duration"] = waiter.wait(
+ timeout=timeout, sleep=sleep, name=route_name, namespace=namespace
+ )
self.exit_json(**result)
- def build_route_spec(self, service_name, namespace, port=None, wildcard_policy=None, hostname=None, path=None, termination_type=None,
- tls_insecure_policy=None, tls_ca_cert=None, tls_cert=None, tls_key=None, tls_dest_ca_cert=None):
- v1_services = self.find_resource('Service', 'v1', fail=True)
+ def build_route_spec(
+ self,
+ service_name,
+ namespace,
+ port=None,
+ wildcard_policy=None,
+ hostname=None,
+ path=None,
+ termination_type=None,
+ tls_insecure_policy=None,
+ tls_ca_cert=None,
+ tls_cert=None,
+ tls_key=None,
+ tls_dest_ca_cert=None,
+ ):
+ v1_services = self.find_resource("Service", "v1", fail=True)
try:
target_service = v1_services.get(name=service_name, namespace=namespace)
except NotFoundError:
if not port:
- self.fail_json(msg="You need to provide the 'port' argument when exposing a non-existent service")
+ self.fail_json(
+ msg="You need to provide the 'port' argument when exposing a non-existent service"
+ )
target_service = None
except DynamicApiError as exc:
- self.fail_json(msg='Failed to retrieve service to be exposed: {0}'.format(exc.body),
- error=exc.status, status=exc.status, reason=exc.reason)
+ self.fail_json(
+ msg="Failed to retrieve service to be exposed: {0}".format(exc.body),
+ error=exc.status,
+ status=exc.status,
+ reason=exc.reason,
+ )
except Exception as exc:
- self.fail_json(msg='Failed to retrieve service to be exposed: {0}'.format(to_native(exc)),
- error='', status='', reason='')
+ self.fail_json(
+ msg="Failed to retrieve service to be exposed: {0}".format(
+ to_native(exc)
+ ),
+ error="",
+ status="",
+ reason="",
+ )
route_spec = {
- 'tls': {},
- 'to': {
- 'kind': 'Service',
- 'name': service_name,
+ "tls": {},
+ "to": {
+ "kind": "Service",
+ "name": service_name,
},
- 'port': {
- 'targetPort': self.set_port(target_service, port),
+ "port": {
+ "targetPort": self.set_port(target_service, port),
},
- 'wildcardPolicy': wildcard_policy
+ "wildcardPolicy": wildcard_policy,
}
# Want to conditionally add these so we don't overwrite what is automically added when nothing is provided
if termination_type:
- route_spec['tls'] = dict(termination=termination_type.capitalize())
+ route_spec["tls"] = dict(termination=termination_type.capitalize())
if tls_insecure_policy:
- if termination_type == 'edge':
- route_spec['tls']['insecureEdgeTerminationPolicy'] = tls_insecure_policy.capitalize()
- elif termination_type == 'passthrough':
- if tls_insecure_policy != 'redirect':
- self.fail_json("'redirect' is the only supported insecureEdgeTerminationPolicy for passthrough routes")
- route_spec['tls']['insecureEdgeTerminationPolicy'] = tls_insecure_policy.capitalize()
- elif termination_type == 'reencrypt':
- self.fail_json("'tls.insecure_policy' is not supported with reencrypt routes")
+ if termination_type == "edge":
+ route_spec["tls"][
+ "insecureEdgeTerminationPolicy"
+ ] = tls_insecure_policy.capitalize()
+ elif termination_type == "passthrough":
+ if tls_insecure_policy != "redirect":
+ self.fail_json(
+ "'redirect' is the only supported insecureEdgeTerminationPolicy for passthrough routes"
+ )
+ route_spec["tls"][
+ "insecureEdgeTerminationPolicy"
+ ] = tls_insecure_policy.capitalize()
+ elif termination_type == "reencrypt":
+ self.fail_json(
+ "'tls.insecure_policy' is not supported with reencrypt routes"
+ )
else:
- route_spec['tls']['insecureEdgeTerminationPolicy'] = None
+ route_spec["tls"]["insecureEdgeTerminationPolicy"] = None
if tls_ca_cert:
- if termination_type == 'passthrough':
- self.fail_json("'tls.ca_certificate' is not supported with passthrough routes")
- route_spec['tls']['caCertificate'] = tls_ca_cert
+ if termination_type == "passthrough":
+ self.fail_json(
+ "'tls.ca_certificate' is not supported with passthrough routes"
+ )
+ route_spec["tls"]["caCertificate"] = tls_ca_cert
if tls_cert:
- if termination_type == 'passthrough':
- self.fail_json("'tls.certificate' is not supported with passthrough routes")
- route_spec['tls']['certificate'] = tls_cert
+ if termination_type == "passthrough":
+ self.fail_json(
+ "'tls.certificate' is not supported with passthrough routes"
+ )
+ route_spec["tls"]["certificate"] = tls_cert
if tls_key:
- if termination_type == 'passthrough':
+ if termination_type == "passthrough":
self.fail_json("'tls.key' is not supported with passthrough routes")
- route_spec['tls']['key'] = tls_key
+ route_spec["tls"]["key"] = tls_key
if tls_dest_ca_cert:
- if termination_type != 'reencrypt':
- self.fail_json("'destination_certificate' is only valid for reencrypt routes")
- route_spec['tls']['destinationCACertificate'] = tls_dest_ca_cert
+ if termination_type != "reencrypt":
+ self.fail_json(
+ "'destination_certificate' is only valid for reencrypt routes"
+ )
+ route_spec["tls"]["destinationCACertificate"] = tls_dest_ca_cert
else:
- route_spec['tls'] = None
+ route_spec["tls"] = None
if hostname:
- route_spec['host'] = hostname
+ route_spec["host"] = hostname
if path:
- route_spec['path'] = path
+ route_spec["path"] = path
return route_spec
@@ -514,7 +577,7 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
if port_arg:
return port_arg
for p in service.spec.ports:
- if p.protocol == 'TCP':
+ if p.protocol == "TCP":
if p.name is not None:
return p.name
return p.targetPort
@@ -525,7 +588,7 @@ def wait_predicate(route):
if not (route.status and route.status.ingress):
return False
for ingress in route.status.ingress:
- match = [x for x in ingress.conditions if x.type == 'Admitted']
+ match = [x for x in ingress.conditions if x.type == "Admitted"]
if not match:
return False
match = match[0]
@@ -538,5 +601,5 @@ def main():
OpenShiftRoute().run_module()
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/okd/requirements.yml b/ansible_collections/community/okd/requirements.yml
index d7d4e6f7a..ac7b465f0 100644
--- a/ansible_collections/community/okd/requirements.yml
+++ b/ansible_collections/community/okd/requirements.yml
@@ -1,3 +1,4 @@
+---
collections:
- name: kubernetes.core
- version: '>=2.4.0'
+ version: '>=3.0.0'
diff --git a/ansible_collections/community/okd/setup.cfg b/ansible_collections/community/okd/setup.cfg
deleted file mode 100644
index 29c924b86..000000000
--- a/ansible_collections/community/okd/setup.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-[flake8]
-max-line-length = 160
-ignore = W503,E402
diff --git a/ansible_collections/community/okd/test-requirements.txt b/ansible_collections/community/okd/test-requirements.txt
index 7f234688f..99e8534cb 100644
--- a/ansible_collections/community/okd/test-requirements.txt
+++ b/ansible_collections/community/okd/test-requirements.txt
@@ -2,3 +2,4 @@ coverage==4.5.4
pytest
pytest-xdist
pytest-forked
+pytest-ansible
diff --git a/ansible_collections/community/okd/tests/config.yml b/ansible_collections/community/okd/tests/config.yml
index 9e402bda7..c26ea5966 100644
--- a/ansible_collections/community/okd/tests/config.yml
+++ b/ansible_collections/community/okd/tests/config.yml
@@ -1,2 +1,3 @@
+---
modules:
- python_requires: ">=3.6"
+ python_requires: ">=3.9"
diff --git a/ansible_collections/community/okd/tests/sanity/ignore-2.16.txt b/ansible_collections/community/okd/tests/sanity/ignore-2.16.txt
new file mode 100644
index 000000000..2fd2bdc90
--- /dev/null
+++ b/ansible_collections/community/okd/tests/sanity/ignore-2.16.txt
@@ -0,0 +1,3 @@
+plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
+plugins/modules/k8s.py validate-modules:return-syntax-error
+plugins/modules/openshift_process.py validate-modules:parameter-type-not-in-doc \ No newline at end of file
diff --git a/ansible_collections/community/okd/tests/sanity/ignore-2.17.txt b/ansible_collections/community/okd/tests/sanity/ignore-2.17.txt
new file mode 100644
index 000000000..2fd2bdc90
--- /dev/null
+++ b/ansible_collections/community/okd/tests/sanity/ignore-2.17.txt
@@ -0,0 +1,3 @@
+plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
+plugins/modules/k8s.py validate-modules:return-syntax-error
+plugins/modules/openshift_process.py validate-modules:parameter-type-not-in-doc \ No newline at end of file
diff --git a/ansible_collections/community/okd/tests/sanity/requirements.yml b/ansible_collections/community/okd/tests/sanity/requirements.yml
new file mode 100644
index 000000000..244be516f
--- /dev/null
+++ b/ansible_collections/community/okd/tests/sanity/requirements.yml
@@ -0,0 +1,5 @@
+---
+collections:
+ - name: https://github.com/ansible-collections/kubernetes.core.git
+ type: git
+ version: main
diff --git a/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_dn.py b/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_dn.py
index 5835f36d7..c312f3b02 100644
--- a/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_dn.py
+++ b/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_dn.py
@@ -5,28 +5,44 @@ __metaclass__ = type
from ansible_collections.community.okd.plugins.module_utils.openshift_ldap import (
openshift_equal_dn,
- openshift_ancestorof_dn
+ openshift_ancestorof_dn,
)
import pytest
try:
- import ldap
+ import ldap # pylint: disable=unused-import
except ImportError:
pytestmark = pytest.mark.skip("This test requires the python-ldap library")
def test_equal_dn():
-
- assert openshift_equal_dn("cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=users,dc=ansible,dc=com")
- assert not openshift_equal_dn("cn=unit,ou=users,dc=ansible,dc=com", "cn=units,ou=users,dc=ansible,dc=com")
- assert not openshift_equal_dn("cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=user,dc=ansible,dc=com")
- assert not openshift_equal_dn("cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=users,dc=ansible,dc=org")
+ assert openshift_equal_dn(
+ "cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=users,dc=ansible,dc=com"
+ )
+ assert not openshift_equal_dn(
+ "cn=unit,ou=users,dc=ansible,dc=com", "cn=units,ou=users,dc=ansible,dc=com"
+ )
+ assert not openshift_equal_dn(
+ "cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=user,dc=ansible,dc=com"
+ )
+ assert not openshift_equal_dn(
+ "cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=users,dc=ansible,dc=org"
+ )
def test_ancestor_of_dn():
-
- assert not openshift_ancestorof_dn("cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=users,dc=ansible,dc=com")
- assert not openshift_ancestorof_dn("cn=unit,ou=users,dc=ansible,dc=com", "cn=units,ou=users,dc=ansible,dc=com")
- assert openshift_ancestorof_dn("ou=users,dc=ansible,dc=com", "cn=john,ou=users,dc=ansible,dc=com")
- assert openshift_ancestorof_dn("ou=users,dc=ansible,dc=com", "cn=mathew,ou=users,dc=ansible,dc=com")
- assert not openshift_ancestorof_dn("ou=users,dc=ansible,dc=com", "cn=mathew,ou=users,dc=ansible,dc=org")
+ assert not openshift_ancestorof_dn(
+ "cn=unit,ou=users,dc=ansible,dc=com", "cn=unit,ou=users,dc=ansible,dc=com"
+ )
+ assert not openshift_ancestorof_dn(
+ "cn=unit,ou=users,dc=ansible,dc=com", "cn=units,ou=users,dc=ansible,dc=com"
+ )
+ assert openshift_ancestorof_dn(
+ "ou=users,dc=ansible,dc=com", "cn=john,ou=users,dc=ansible,dc=com"
+ )
+ assert openshift_ancestorof_dn(
+ "ou=users,dc=ansible,dc=com", "cn=mathew,ou=users,dc=ansible,dc=com"
+ )
+ assert not openshift_ancestorof_dn(
+ "ou=users,dc=ansible,dc=com", "cn=mathew,ou=users,dc=ansible,dc=org"
+ )
diff --git a/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_sync_config.py b/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_sync_config.py
index 1a8ef67e2..303b66f4b 100644
--- a/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_sync_config.py
+++ b/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_ldap_sync_config.py
@@ -9,28 +9,26 @@ from ansible_collections.community.okd.plugins.module_utils.openshift_ldap impor
def test_missing_url():
- config = dict(
- kind="LDAPSyncConfig",
- apiVersion="v1",
- insecure=True
- )
+ config = dict(kind="LDAPSyncConfig", apiVersion="v1", insecure=True)
err = validate_ldap_sync_config(config)
assert err == "url should be non empty attribute."
def test_binddn_and_bindpwd_linked():
"""
- one of bind_dn and bind_pwd cannot be set alone
+ one of bind_dn and bind_pwd cannot be set alone
"""
config = dict(
kind="LDAPSyncConfig",
apiVersion="v1",
url="ldap://LDAP_SERVICE_IP:389",
insecure=True,
- bindDN="cn=admin,dc=example,dc=org"
+ bindDN="cn=admin,dc=example,dc=org",
)
- credentials_error = "bindDN and bindPassword must both be specified, or both be empty."
+ credentials_error = (
+ "bindDN and bindPassword must both be specified, or both be empty."
+ )
assert validate_ldap_sync_config(config) == credentials_error
@@ -39,7 +37,7 @@ def test_binddn_and_bindpwd_linked():
apiVersion="v1",
url="ldap://LDAP_SERVICE_IP:389",
insecure=True,
- bindPassword="testing1223"
+ bindPassword="testing1223",
)
assert validate_ldap_sync_config(config) == credentials_error
@@ -53,11 +51,13 @@ def test_insecure_connection():
insecure=True,
)
- assert validate_ldap_sync_config(config) == "Cannot use ldaps scheme with insecure=true."
+ assert (
+ validate_ldap_sync_config(config)
+ == "Cannot use ldaps scheme with insecure=true."
+ )
- config.update(dict(
- url="ldap://LDAP_SERVICE_IP:389",
- ca="path/to/ca/file"
- ))
+ config.update(dict(url="ldap://LDAP_SERVICE_IP:389", ca="path/to/ca/file"))
- assert validate_ldap_sync_config(config) == "Cannot specify a ca with insecure=true."
+ assert (
+ validate_ldap_sync_config(config) == "Cannot specify a ca with insecure=true."
+ )
diff --git a/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_openshift_docker_image.py b/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_openshift_docker_image.py
index 99cf15cc5..d23f9f186 100644
--- a/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_openshift_docker_image.py
+++ b/ansible_collections/community/okd/tests/unit/plugins/module_utils/test_openshift_docker_image.py
@@ -11,7 +11,6 @@ import pytest
def test_convert_storage_to_bytes():
-
data = [
("1000", 1000),
("1000Ki", 1000 * 1024),
@@ -54,46 +53,48 @@ def validate_docker_response(resp, **kwargs):
def test_parse_docker_image_ref_valid_image_with_digest():
-
image = "registry.access.redhat.com/ubi8/dotnet-21@sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522669"
response, err = parse_docker_image_ref(image)
assert err is None
- validate_docker_response(response,
- hostname="registry.access.redhat.com",
- namespace="ubi8",
- name="dotnet-21",
- digest="sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522669")
+ validate_docker_response(
+ response,
+ hostname="registry.access.redhat.com",
+ namespace="ubi8",
+ name="dotnet-21",
+ digest="sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522669",
+ )
def test_parse_docker_image_ref_valid_image_with_tag_latest():
-
image = "registry.access.redhat.com/ubi8/dotnet-21:latest"
response, err = parse_docker_image_ref(image)
assert err is None
- validate_docker_response(response,
- hostname="registry.access.redhat.com",
- namespace="ubi8",
- name="dotnet-21",
- tag="latest")
+ validate_docker_response(
+ response,
+ hostname="registry.access.redhat.com",
+ namespace="ubi8",
+ name="dotnet-21",
+ tag="latest",
+ )
def test_parse_docker_image_ref_valid_image_with_tag_int():
-
image = "registry.access.redhat.com/ubi8/dotnet-21:0.0.1"
response, err = parse_docker_image_ref(image)
assert err is None
- validate_docker_response(response,
- hostname="registry.access.redhat.com",
- namespace="ubi8",
- name="dotnet-21",
- tag="0.0.1")
+ validate_docker_response(
+ response,
+ hostname="registry.access.redhat.com",
+ namespace="ubi8",
+ name="dotnet-21",
+ tag="0.0.1",
+ )
def test_parse_docker_image_ref_invalid_image():
-
# The hex value of the sha256 is not valid
image = "registry.access.redhat.com/dotnet-21@sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522"
response, err = parse_docker_image_ref(image)
@@ -101,7 +102,6 @@ def test_parse_docker_image_ref_invalid_image():
def test_parse_docker_image_ref_valid_image_without_hostname():
-
image = "ansible:2.10.0"
response, err = parse_docker_image_ref(image)
assert err is None
@@ -110,16 +110,18 @@ def test_parse_docker_image_ref_valid_image_without_hostname():
def test_parse_docker_image_ref_valid_image_without_hostname_and_with_digest():
-
image = "ansible@sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522669"
response, err = parse_docker_image_ref(image)
assert err is None
- validate_docker_response(response, name="ansible", digest="sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522669")
+ validate_docker_response(
+ response,
+ name="ansible",
+ digest="sha256:f7718f5efd3436e781ee4322c92ab0c4ae63e61f5b36f1473a57874cc3522669",
+ )
def test_parse_docker_image_ref_valid_image_with_name_only():
-
image = "ansible"
response, err = parse_docker_image_ref(image)
assert err is None
@@ -128,25 +130,27 @@ def test_parse_docker_image_ref_valid_image_with_name_only():
def test_parse_docker_image_ref_valid_image_without_hostname_with_namespace_and_name():
-
image = "ibmcom/pause@sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d"
response, err = parse_docker_image_ref(image)
assert err is None
- validate_docker_response(response,
- name="pause",
- namespace="ibmcom",
- digest="sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d")
+ validate_docker_response(
+ response,
+ name="pause",
+ namespace="ibmcom",
+ digest="sha256:fcaff905397ba63fd376d0c3019f1f1cb6e7506131389edbcb3d22719f1ae54d",
+ )
def test_parse_docker_image_ref_valid_image_with_complex_namespace_name():
-
image = "registry.redhat.io/jboss-webserver-5/webserver54-openjdk11-tomcat9-openshift-rhel7:1.0"
response, err = parse_docker_image_ref(image)
assert err is None
- validate_docker_response(response,
- hostname="registry.redhat.io",
- name="webserver54-openjdk11-tomcat9-openshift-rhel7",
- namespace="jboss-webserver-5",
- tag="1.0")
+ validate_docker_response(
+ response,
+ hostname="registry.redhat.io",
+ name="webserver54-openjdk11-tomcat9-openshift-rhel7",
+ namespace="jboss-webserver-5",
+ tag="1.0",
+ )
diff --git a/ansible_collections/community/okd/tox.ini b/ansible_collections/community/okd/tox.ini
new file mode 100644
index 000000000..57fd1d921
--- /dev/null
+++ b/ansible_collections/community/okd/tox.ini
@@ -0,0 +1,37 @@
+[tox]
+skipsdist = True
+
+[testenv]
+deps = -r{toxinidir}/requirements.txt
+ -r{toxinidir}/test-requirements.txt
+install_command = pip install {opts} {packages}
+
+[testenv:black]
+deps =
+ black >= 23.0, < 24.0
+
+commands =
+ black {toxinidir}/plugins {toxinidir}/tests
+
+[testenv:ansible-lint]
+deps =
+ ansible-lint==6.21.0
+changedir = {toxinidir}
+commands =
+ ansible-lint
+
+[testenv:linters]
+deps =
+ flake8
+ {[testenv:black]deps}
+
+commands =
+ black -v --check --diff {toxinidir}/plugins {toxinidir}/tests
+ flake8 {toxinidir}
+
+[flake8]
+# E123, E125 skipped as they are invalid PEP-8.
+exclude = .git,.tox,tests/output
+ignore = E123,E125,E203,E402,E501,E741,F401,F811,F841,W503
+max-line-length = 160
+builtins = _
diff --git a/ansible_collections/community/postgresql/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/postgresql/.azure-pipelines/azure-pipelines.yml
index 28f8b2497..431614af9 100644
--- a/ansible_collections/community/postgresql/.azure-pipelines/azure-pipelines.yml
+++ b/ansible_collections/community/postgresql/.azure-pipelines/azure-pipelines.yml
@@ -75,6 +75,18 @@ stages:
- name: Units
test: 'devel/units/1'
+ - stage: Ansible_2_17
+ displayName: Sanity & Units 2.17
+ dependsOn: []
+ jobs:
+ - template: templates/matrix.yml
+ parameters:
+ targets:
+ - name: Sanity
+ test: '2.17/sanity/1'
+ - name: Units
+ test: '2.17/units/1'
+
- stage: Ansible_2_16
displayName: Sanity & Units 2.16
dependsOn: []
@@ -127,6 +139,21 @@ stages:
- name: Ubuntu 22.04
test: ubuntu2204
+ - stage: Docker_2_17
+ displayName: Docker 2.17
+ dependsOn: []
+ jobs:
+ - template: templates/matrix.yml
+ parameters:
+ testFormat: 2.17/linux/{0}/1
+ targets:
+ - name: Fedora 39
+ test: fedora39
+ - name: Ubuntu 20.04
+ test: ubuntu2004
+ - name: Ubuntu 22.04
+ test: ubuntu2204
+
- stage: Docker_2_16
displayName: Docker 2.16
dependsOn: []
@@ -186,6 +213,17 @@ stages:
- name: RHEL 9.3
test: rhel/9.3
+ - stage: Remote_2_17
+ displayName: Remote 2.17
+ dependsOn: []
+ jobs:
+ - template: templates/matrix.yml
+ parameters:
+ testFormat: 2.17/{0}/1
+ targets:
+ - name: RHEL 9.3
+ test: rhel/9.3
+
- stage: Remote_2_16
displayName: Remote 2.16
dependsOn: []
@@ -225,14 +263,17 @@ stages:
condition: succeededOrFailed()
dependsOn:
- Ansible_devel
+ - Ansible_2_17
- Ansible_2_16
- Ansible_2_15
- Ansible_2_14
- Docker_devel
+ - Docker_2_17
- Docker_2_16
- Docker_2_15
- Docker_2_14
- Remote_devel
+ - Remote_2_17
- Remote_2_16
- Remote_2_15
- Remote_2_14
diff --git a/ansible_collections/community/postgresql/CHANGELOG.rst b/ansible_collections/community/postgresql/CHANGELOG.rst
index d9990ab6a..fc0805301 100644
--- a/ansible_collections/community/postgresql/CHANGELOG.rst
+++ b/ansible_collections/community/postgresql/CHANGELOG.rst
@@ -5,6 +5,24 @@ Community PostgreSQL Collection Release Notes
.. contents:: Topics
+v3.4.1
+======
+
+Release Summary
+---------------
+
+This is a patch release of the ``community.postgresql`` collection.
+This changelog contains all changes to the modules and plugins in this collection
+that have been added after the release of ``community.postgresql`` 3.4.0.
+
+Bugfixes
+--------
+
+- postgresql_db - ``restore`` custom format as file instead of stdin to allow the use of --job flag in ``target_opts`` (https://github.com/ansible-collections/community.postgresql/issues/594).
+- postgresql_ext - Reconnect before upgrade to avoid accidental load of the upgraded extension (https://github.com/ansible-collections/community.postgresql/pull/689).
+- postgresql_idx - consider schema name when checking for index (https://github.com/ansible-collections/community.postgresql/issues/692). Index names are only unique within a schema. This allows using the same index name in multiple schemas.
+- postgresql_privs - Enables the ability to revoke functions from user (https://github.com/ansible-collections/community.postgresql/issues/687).
+
v3.4.0
======
diff --git a/ansible_collections/community/postgresql/CONTRIBUTING.md b/ansible_collections/community/postgresql/CONTRIBUTING.md
index ecb18f74a..8beed5512 100644
--- a/ansible_collections/community/postgresql/CONTRIBUTING.md
+++ b/ansible_collections/community/postgresql/CONTRIBUTING.md
@@ -1,12 +1,85 @@
-# Contributing
+# Contributing to this project
-Refer to the [Ansible Contributing guidelines](https://docs.ansible.com/ansible/devel/community/index.html) to learn how to contribute to this collection.
+In this guide, you will find information relevant for code contributions, though any other kinds of contribution mentioned in the [Ansible Contributing guidelines](https://docs.ansible.com/ansible/devel/community/index.html) are equally appreciated and valuable.
-Refer to the [review checklist](https://docs.ansible.com/ansible/devel/community/collection_contributors/collection_reviewing.html) when triaging issues or reviewing PRs.
+If you have any questions after reading, please contact the community via one or more of the [available channels](https://github.com/ansible-collections/community.postgresql#communication). Any feedback on this guide is very welcome.
+
+## Reviewing open issue and pull requests
+
+Refer to the [review checklist](https://docs.ansible.com/ansible/devel/community/collection_contributors/collection_reviewing.html) when triaging issues or reviewing pull requests (hereinafter PRs).
+
+Most important things to pay attention to:
+
+- Do not let major/breaking changes sneak into a minor/bugfix release! All such changes should be discussed in a dedicated issue, added to a corresponding milestone (which can be found or created in the project's Issues), and merged right before the major release. Take a look at similar issues to see what needs to be done and reflect on the steps you did/need to do in the issue.
+- Every PR (except doc, refactoring, test-related, or a PR containing a new module/plugin) contains a [changelog fragment](https://docs.ansible.com/ansible/latest/community/development_process.html#creating-a-changelog-fragment). Let's give users a chance to know about the changes.
+- Every new module `DOCUMENTATION` section contains the `version_added: 'x.y.z'` field. Besides the informative purpose, it is used by the changelog-generating tool to add a corresponding entry to the changelog. As the project follows SemVer, it is typically a next minor (x.y.0) version.
+- Every new module argument contains the `version_added: 'x.y.z'` field. As the project follows SemVer, it is typically a next minor (x.y.0) version.
+- Non-refactoring code changes (bugfixes, new features) are covered with, at least, integration tests! There can be exceptions but generally it is a requirement.
+
+## Code contributions
+
+If you want to submit a bugfix or new feature, refer to the [Quick-start development guide](https://docs.ansible.com/ansible/devel/community/create_pr_quick_start.html) first.
+
+## Project-specific info
+
+We assume you have read the [Quick-start development guide](https://docs.ansible.com/ansible/devel/community/create_pr_quick_start.html).
+
+In order for any submitted PR to get merged, this project requires sanity, unit, and integration tests to pass.
+Codecov job is there but not required.
+We use the Azure Pipelines platform to run the tests.
+You can see the result in the bottom of every PR in the box listing the jobs and their results:
+
+- Green checkmark: the test has been passed, no more action is needed.
+- Red cross: the test has failed. You can see the reason by clicking the ``Details`` link. Fix them locally and push the commit.
+
+Generally, all jobs must be green.
+Sometimes, there can be failures unrelated to a PR, for example, when a test container is unavailable or there is another part of the code that does not satisfy recently introduced additional sanity checks.
+If you think the failure does not relate to your changes, put a comment about it.
+
+## CI testing
+
+The jobs are launched automatically by Azure Pipelines in every PR based on the [matrix](https://github.com/ansible-collections/community.postgresql/blob/main/.azure-pipelines/azure-pipelines.yml).
+
+As the project is included in `ansible` community package, it is a requirement for us to test against all supported `ansible-core` versions and corresponding Python versions.
+To keep the matrix relevant, we are subscribed to the [news-for-maintainers](https://github.com/ansible-collections/news-for-maintainers) repository and the [Collection maintainers & contributors](https://forum.ansible.com/g/CollectionMaintainer) forum group to track announcements affecting CI.
+
+If our matrix is permanently outdated, for example, when supported `ansible-core` versions are missed, the collections can get excluded from the package, so keep it updated!
+
+## Adding tests
+
+If you are new here, read the [Quick-start development guide](https://docs.ansible.com/ansible/devel/community/create_pr_quick_start.html) first.
+
+When fixing a bug, first reproduce it by adding a task as reported to a suitable file under the ``tests/integration/targets/<module_name>/tasks/`` directory and run the integration tests as described below. The same is relevant for new features.
+
+It is not necessary but if you want you can also add unit tests to a suitable file under the ``tests/units/`` directory and run them as described below.
## Checking your code locally
-### By hand
+It will make your and other people's life a bit easier if you run the tests locally and fix all failures before pushing. If you're unable to run the tests locally, please create your PR as a **draft** to avoid reviewers being added automatically.
+
+If you are new here, read the [Quick-start development guide](https://docs.ansible.com/ansible/devel/community/create_pr_quick_start.html) first.
+
+We assume you [prepared your local environment](https://docs.ansible.com/ansible/devel/community/create_pr_quick_start.html#prepare-your-environment) as described in the guide before running the following commands. Otherwise, the command will fail.
+
+### Sanity tests
+
+``` console
+$ ansible-test sanity path/to/changed_file.py --docker -v
+```
+
+### Integration tests
+
+``` console
+$ ansible-test integration <module_name you changed> --docker <container, e.g. ubuntu2204> -v
+```
+
+### Unit tests
+
+``` console
+$ ansible-test units tests/unit/plugins/unit_test_file.py --docker
+```
+
+### tox
You can run flake8 with tox to verify the quality of your code. For that you
can simply call tox with that command:
@@ -14,8 +87,8 @@ can simply call tox with that command:
$ tox -e lint
```
-If you tox is missing on your environment you can probably install it through
-your package manager (Eg: `sudo apt install tox`) or with pip (within a
+If tox is missing on your environment you can probably install it through
+your package manager (for example, `sudo apt install tox`) or with pip (within a
virtualenv):
``` console
diff --git a/ansible_collections/community/postgresql/FILES.json b/ansible_collections/community/postgresql/FILES.json
index 4302f209c..5619dc342 100644
--- a/ansible_collections/community/postgresql/FILES.json
+++ b/ansible_collections/community/postgresql/FILES.json
@@ -109,7 +109,7 @@
"name": ".azure-pipelines/azure-pipelines.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d51571bbcb9d9cd269b46558fbd86071be6a450a189a5383a38b2da0b14b1c86",
+ "chksum_sha256": "21c5919dd3e83d15b1fe22120b78b236f87440c760ba0461aae5a9cb8c1f943b",
"format": 1
},
{
@@ -158,7 +158,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b9669874dadda6fc914c52186ac175b590b7c2c4481da2896dbfaad9d36ea263",
+ "chksum_sha256": "c64b2b9cd3bcd7a5cf4ded207014b072f448416c29f652112ea6c0c168b6fc51",
"format": 1
},
{
@@ -284,21 +284,21 @@
"name": "plugins/modules/postgresql_db.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ee2ae220616261dee6e44204168ec6e67e5cdb89d5fb8cb8a79a3d9969800219",
+ "chksum_sha256": "74361df6b6b5c08dfbae2ce2e06c259a7dc0de5e1ee9cd0e1fe036de75c3ac26",
"format": 1
},
{
"name": "plugins/modules/postgresql_ext.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4e715015d05e5273e6a5c78720e837a31d0b65d8c059242391602d7258401248",
+ "chksum_sha256": "d7685a5e6aa6a012b04f6d473d2e525f3077e857ee3aba4883a47f42312f3c37",
"format": 1
},
{
"name": "plugins/modules/postgresql_idx.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3113e2c7531aaf65c8c5996cdd0906d4a3a4ad603a7eb90ec6c2a61011ef8dbb",
+ "chksum_sha256": "e5cad7d80e230faef5fe681aea7b90eba0a485d70240748d6a0fe14f283d90d1",
"format": 1
},
{
@@ -347,7 +347,7 @@
"name": "plugins/modules/postgresql_privs.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "84b979c32e98cbe03a96ff07b009e5c53a24910289498dd2ba15e850417bbe66",
+ "chksum_sha256": "54b343e1e1699ac2b0c0b562f3552ec57a52370805f215024b76c6d75cf4b299",
"format": 1
},
{
@@ -2339,6 +2339,13 @@
"format": 1
},
{
+ "name": "tests/sanity/ignore-2.18.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f1e2e4351ae7e8b366042aef4f75e1a4df73a64203296484944df297ddbfbdf0",
+ "format": 1
+ },
+ {
"name": "tests/unit",
"ftype": "dir",
"chksum_type": null,
@@ -2538,14 +2545,14 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "02924d737dff1a6dd5b7e9a137a2c426526ec976780e141bfdfb3262e29557b6",
+ "chksum_sha256": "383aef409d69d0aa94f226597152f8d42c43a1eed6339098fb6207f9511cd0fa",
"format": 1
},
{
"name": "CONTRIBUTING.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e1b3cbadfbb785585ca2c984365edef37a0d813798ad5c8ea7c296135045f9ee",
+ "chksum_sha256": "6131e3c155206d545289e3f13aca82a0d9f0a0a6dfa47fb8616fd6a5f8613b2f",
"format": 1
},
{
@@ -2580,7 +2587,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "522dc34d303faf3a818d0a57b1a7b9a7338f3acdadd55de2226ef7720765246f",
+ "chksum_sha256": "375a82d12ffaa2bfae010228498554f9f16f375050379950febc5a7f031aa4eb",
"format": 1
},
{
diff --git a/ansible_collections/community/postgresql/MANIFEST.json b/ansible_collections/community/postgresql/MANIFEST.json
index b16ee0f4d..672a8aa0c 100644
--- a/ansible_collections/community/postgresql/MANIFEST.json
+++ b/ansible_collections/community/postgresql/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "postgresql",
- "version": "3.4.0",
+ "version": "3.4.1",
"authors": [
"Ansible PostgreSQL community"
],
@@ -25,7 +25,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "87d0437e40df1ddaf3161d1baaf5340d03e0c8983c7326257fab831e5f47e682",
+ "chksum_sha256": "ac501f2b0873534b223a2abcc10170a5f29269eb2f1268362ffafc797e6e3cde",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/postgresql/README.md b/ansible_collections/community/postgresql/README.md
index fde669888..13cc89235 100644
--- a/ansible_collections/community/postgresql/README.md
+++ b/ansible_collections/community/postgresql/README.md
@@ -56,23 +56,27 @@ They also should be subscribed to Ansible's [The Bullhorn newsletter](https://do
> `GitHub Discussions` feature is disabled in this repository. Use the `postgresql` tag on the forum in the [Project Discussions](https://forum.ansible.com/new-topic?title=topic%20title&body=topic%20body&category=project&tags=postgresql) or [Get Help](https://forum.ansible.com/new-topic?title=topic%20title&body=topic%20body&category=help&tags=postgresql) category instead.
-We announce important development changes and releases through Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn). If you are a collection developer, be sure you are subscribed.
-
-Join [our team](https://forum.ansible.com/g/PostgreSQLTeam?asc=true&order=) on:
-* The Ansible forums:
- * [News & Announcements](https://forum.ansible.com/c/news/5/none)
- * [Get Help](https://forum.ansible.com/c/help/6/none)
- * [Social Spaces](https://forum.ansible.com/c/chat/4)
- * [Posts tagged 'postgresql'](https://forum.ansible.com/tag/postgresql)
-* Matrix:
- * `#postgresql:ansible.com` [room](https://matrix.to/#/#postgresql:ansible.com): questions on how to contribute and use this collection.
- * `#users:ansible.com` [room](https://matrix.to/#/#users:ansible.com): general use questions and support.
- * `#ansible-community:ansible.com` [room](https://matrix.to/#/#community:ansible.com): community and collection development questions.
- * other Matrix rooms or corresponding bridged Libera.Chat channels. See the [Ansible Communication Guide](https://docs.ansible.com/ansible/devel/community/communication.html) for details.
+### Asynchronous channels
+
+* Join the Ansible forum:
+ * [PostgreSQL Team](https://forum.ansible.com/g/PostgreSQLTeam): by joining the team you will automatically get subscribed to the posts tagged with [postgresql](https://forum.ansible.com/tag/postgresql).
+ * [Get Help](https://forum.ansible.com/c/help/6/none): get help or help others.
+ * [Posts tagged with 'postgresql'](https://forum.ansible.com/tag/postgresql): leverage tags to narrow the scope.
+ * [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
+ * [News & Announcements](https://forum.ansible.com/c/news/5/none): track project-wide announcements including social events.
+
+* The Ansible [Bullhorn newsletter](https://forum.ansible.com/t/about-the-newsletter-category/166): used to announce releases and important changes.
-We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn) and join us.
+### Real-time channels
+
+* Matrix rooms:
+ * [#postgresql:ansible.com](https://matrix.to/#/#postgresql:ansible.com): questions on how to contribute and use this collection.
+ * [#users:ansible.com](https://matrix.to/#/#users:ansible.com): general use questions and support.
+ * [#social:ansible.com](https://matrix.to/#/#social:ansible.com): say hello or share a funny joke and let's laugh together;)
+ * [#ansible-community:ansible.com](https://matrix.to/#/#community:ansible.com): community and collection development questions.
+ * other Matrix rooms or corresponding bridged Libera.Chat channels. See the [Ansible Communication Guide](https://docs.ansible.com/ansible/devel/community/communication.html) for details.
-For more information about communication, refer to the [Ansible Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
+For more information about communication, including how to join these channels, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
## Governance
@@ -93,7 +97,7 @@ The minimum supported and tested versions of Psycopg are 2.5.1 and 3.1.8 respect
We maintain each major release version (1.x.y, 2.x.y, ...) for two years after the next major version is released.
Here is the table for the support timeline:
-- 1.x.y: released 2020-11-17, supported until 2024-02-10
+- 1.x.y: released 2020-11-17, EOL
- 2.x.y: released 2022-02-10, supported until 2025-06-09
- 3.x.y: released 2023-06-09, current
- 4.x.y: to be released; not earlier than after Ansible 10 release (~May 2024)
@@ -104,6 +108,7 @@ Tested with the following `ansible-core` releases:
- 2.14
- 2.15
- 2.16
+- 2.17
- current development version
Ansible-core versions before 2.12.0 are not supported.
diff --git a/ansible_collections/community/postgresql/changelogs/changelog.yaml b/ansible_collections/community/postgresql/changelogs/changelog.yaml
index bacf00e7a..331cc0e02 100644
--- a/ansible_collections/community/postgresql/changelogs/changelog.yaml
+++ b/ansible_collections/community/postgresql/changelogs/changelog.yaml
@@ -678,3 +678,26 @@ releases:
- 3.4.0.yml
- 667-db_icu_provider.yml
release_date: '2024-02-09'
+ 3.4.1:
+ changes:
+ bugfixes:
+ - postgresql_db - ``restore`` custom format as file instead of stdin to allow
+ the use of --job flag in ``target_opts`` (https://github.com/ansible-collections/community.postgresql/issues/594).
+ - postgresql_ext - Reconnect before upgrade to avoid accidental load of the
+ upgraded extension (https://github.com/ansible-collections/community.postgresql/pull/689).
+ - postgresql_idx - consider schema name when checking for index (https://github.com/ansible-collections/community.postgresql/issues/692). Index
+ names are only unique within a schema. This allows using the same index name
+ in multiple schemas.
+ - postgresql_privs - Enables the ability to revoke functions from user (https://github.com/ansible-collections/community.postgresql/issues/687).
+ release_summary: 'This is a patch release of the ``community.postgresql`` collection.
+
+ This changelog contains all changes to the modules and plugins in this collection
+
+ that have been added after the release of ``community.postgresql`` 3.4.0.'
+ fragments:
+ - 3.4.1.yml
+ - 681-restore-custom-format-as-file.yml
+ - 689-reconnect-before-upgrade.yml
+ - 690-revoke-functions-from-user.yaml
+ - 693-idx-consider-schema.yaml
+ release_date: '2024-05-17'
diff --git a/ansible_collections/community/postgresql/plugins/modules/postgresql_db.py b/ansible_collections/community/postgresql/plugins/modules/postgresql_db.py
index ae2faa007..ca9093566 100644
--- a/ansible_collections/community/postgresql/plugins/modules/postgresql_db.py
+++ b/ansible_collections/community/postgresql/plugins/modules/postgresql_db.py
@@ -628,7 +628,7 @@ def db_restore(module, target, target_opts="",
else:
return p2.returncode, '', stderr2, 'cmd: ****'
else:
- if '--format=Directory' in cmd:
+ if any(substring in cmd for substring in ['--format=Directory', '--format=Custom']):
cmd = '{0} {1}'.format(cmd, shlex_quote(target))
else:
cmd = '{0} < {1}'.format(cmd, shlex_quote(target))
diff --git a/ansible_collections/community/postgresql/plugins/modules/postgresql_ext.py b/ansible_collections/community/postgresql/plugins/modules/postgresql_ext.py
index 7dfc95ac4..d302acdaa 100644
--- a/ansible_collections/community/postgresql/plugins/modules/postgresql_ext.py
+++ b/ansible_collections/community/postgresql/plugins/modules/postgresql_ext.py
@@ -469,6 +469,11 @@ def main():
else:
valid_update_path = ext_valid_update_path(cursor, ext, curr_version, real_version)
if valid_update_path:
+ # Reconnect (required by some extensions like timescaledb)
+ if not module.check_mode:
+ db_connection.close()
+ db_connection, dummy = connect_to_db(module, conn_params, autocommit=True)
+ cursor = db_connection.cursor(**pg_cursor_args)
changed = ext_update_version(module.check_mode, cursor, ext, version)
else:
if version == 'latest':
diff --git a/ansible_collections/community/postgresql/plugins/modules/postgresql_idx.py b/ansible_collections/community/postgresql/plugins/modules/postgresql_idx.py
index 7eb35de40..48784d283 100644
--- a/ansible_collections/community/postgresql/plugins/modules/postgresql_idx.py
+++ b/ansible_collections/community/postgresql/plugins/modules/postgresql_idx.py
@@ -344,9 +344,10 @@ class Index(object):
"ON i.indexname = c.relname "
"JOIN pg_catalog.pg_index AS pi "
"ON c.oid = pi.indexrelid "
- "WHERE i.indexname = %(name)s")
+ "WHERE i.schemaname = %(schema)s "
+ "AND i.indexname = %(name)s")
- res = exec_sql(self, query, query_params={'name': self.name}, add_to_executed=False)
+ res = exec_sql(self, query, query_params={'schema': self.schema, 'name': self.name}, add_to_executed=False)
if res:
self.exists = True
self.info = dict(
diff --git a/ansible_collections/community/postgresql/plugins/modules/postgresql_privs.py b/ansible_collections/community/postgresql/plugins/modules/postgresql_privs.py
index 2c4ca7086..56f8c602e 100644
--- a/ansible_collections/community/postgresql/plugins/modules/postgresql_privs.py
+++ b/ansible_collections/community/postgresql/plugins/modules/postgresql_privs.py
@@ -972,7 +972,7 @@ class QueryBuilder(object):
def build_absent(self):
if self._obj_type == 'default_privs':
self.query = []
- for obj in ['TABLES', 'SEQUENCES', 'TYPES']:
+ for obj in ['TABLES', 'FUNCTIONS', 'SEQUENCES', 'TYPES']:
if self._as_who:
self.query.append(
'ALTER DEFAULT PRIVILEGES FOR ROLE {0}{1} REVOKE ALL ON {2} FROM {3};'.format(self._as_who,
diff --git a/ansible_collections/community/postgresql/tests/sanity/ignore-2.18.txt b/ansible_collections/community/postgresql/tests/sanity/ignore-2.18.txt
new file mode 100644
index 000000000..230ec3421
--- /dev/null
+++ b/ansible_collections/community/postgresql/tests/sanity/ignore-2.18.txt
@@ -0,0 +1,5 @@
+plugins/modules/postgresql_db.py use-argspec-type-path
+plugins/modules/postgresql_db.py validate-modules:use-run-command-not-popen
+plugins/module_utils/version.py pylint:unused-import
+tests/utils/shippable/timing.py shebang
+tests/unit/plugins/module_utils/test_postgres.py pylint:unidiomatic-typecheck
diff --git a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/bug_report.yml b/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/bug_report.yml
deleted file mode 100644
index b8d61db62..000000000
--- a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/bug_report.yml
+++ /dev/null
@@ -1,149 +0,0 @@
----
-name: Bug report
-description: Create a report to help us improve
-
-body:
-- type: markdown
- attributes:
- value: |
- âš 
- Verify first that your issue is not [already reported on GitHub][issue search].
- Also test if the latest release and devel branch are affected too.
- *Complete **all** sections as described, this form is processed automatically.*
-
- [issue search]: https://github.com/ansible-collections/community.sap/search?q=is%3Aissue&type=issues
-
-
-- type: textarea
- attributes:
- label: Summary
- description: Explain the problem briefly below.
- placeholder: >-
- When I try to do X with the collection from the main branch on GitHub, Y
- breaks in a way Z under the env E. Here are all the details I know
- about this problem...
- validations:
- required: true
-
-- type: dropdown
- attributes:
- label: Issue Type
- # FIXME: Once GitHub allows defining the default choice, update this
- options:
- - Bug Report
- validations:
- required: true
-
-- type: textarea
- attributes:
- # For smaller collections we could use a multi-select and hardcode the list
- # May generate this list via GitHub action and walking files under https://github.com/ansible-collections/community.sap/tree/main/plugins
- # Select from list, filter as you type (`mysql` would only show the 3 mysql components)
- # OR freeform - doesn't seem to be supported in adaptivecards
- label: Component Name
- description: >-
- Write the short name of the module, plugin, task or feature below,
- *use your best guess if unsure*.
- placeholder: dnf, apt, yum, pip, user etc.
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Ansible Version
- description: >-
- Paste verbatim output from `ansible --version` between
- tripple backticks.
- value: |
- ```console (paste below)
- $ ansible --version
-
- ```
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Community.sap Version
- description: >-
- Paste verbatim output from "ansible-galaxy collection list community.sap"
- between tripple backticks.
- value: |
- ```console (paste below)
- $ ansible-galaxy collection list community.sap
-
- ```
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Configuration
- description: >-
- If this issue has an example piece of YAML that can help to reproduce this problem, please provide it.
- This can be a piece of YAML from, e.g., an automation, script, scene or configuration.
- Paste verbatim output from `ansible-config dump --only-changed` between quotes
- value: |
- ```console (paste below)
- $ ansible-config dump --only-changed
-
- ```
-
-
-- type: textarea
- attributes:
- label: OS / Environment
- description: >-
- Provide all relevant information below, e.g. target OS versions,
- network device firmware, etc.
- placeholder: RHEL 8, SLES
- validations:
- required: false
-
-
-- type: textarea
- attributes:
- label: Steps to Reproduce
- description: |
- Describe exactly how to reproduce the problem, using a minimal test-case. It would *really* help us understand your problem if you could also pased any playbooks, configs and commands you used.
-
- **HINT:** You can paste https://gist.github.com links for larger files.
- value: |
- <!--- Paste example playbooks or commands between quotes below -->
- ```yaml (paste below)
-
- ```
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Expected Results
- description: >-
- Describe what you expected to happen when running the steps above.
- placeholder: >-
- I expected X to happen because I assumed Y.
- that it did not.
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Actual Results
- description: |
- Describe what actually happened. If possible run with extra verbosity (`-vvvv`).
-
- Paste verbatim command output between quotes.
- value: |
- ```console (paste below)
-
- ```
-- type: checkboxes
- attributes:
- label: Code of Conduct
- description: |
- Read the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--ansible-collections) first.
- options:
- - label: I agree to follow the Ansible Code of Conduct
- required: true
-...
diff --git a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/config.yml b/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index f90bd1ad8..000000000
--- a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,27 +0,0 @@
----
-# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
-blank_issues_enabled: false # default: true
-contact_links:
-- name: Security bug report
- url: https://docs.ansible.com/ansible-core/devel/community/reporting_bugs_and_features.html?utm_medium=github&utm_source=issue_template_chooser_ansible_collections
- about: |
- Please learn how to report security vulnerabilities here.
-
- For all security related bugs, email security@ansible.com
- instead of using this issue tracker and you will receive
- a prompt response.
-
- For more information, see
- https://docs.ansible.com/ansible/latest/community/reporting_bugs_and_features.html
-- name: Ansible Code of Conduct
- url: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_template_chooser_ansible_collections
- about: Be nice to other members of the community.
-- name: Talks to the community
- url: https://docs.ansible.com/ansible/latest/community/communication.html?utm_medium=github&utm_source=issue_template_chooser#mailing-list-information
- about: Please ask and answer usage questions here
-- name: Working groups
- url: https://github.com/ansible/community/wiki
- about: Interested in improving a specific area? Become a part of a working group!
-- name: For Enterprise
- url: https://www.ansible.com/products/engine?utm_medium=github&utm_source=issue_template_chooser_ansible_collections
- about: Red Hat offers support for the Ansible Automation Platform
diff --git a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/documentation_report.yml b/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/documentation_report.yml
deleted file mode 100644
index fb023cf46..000000000
--- a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/documentation_report.yml
+++ /dev/null
@@ -1,125 +0,0 @@
----
-name: Documentation Report
-description: Ask us about docs
-# NOTE: issue body is enabled to allow screenshots
-
-body:
-- type: markdown
- attributes:
- value: |
- âš 
- Verify first that your issue is not [already reported on GitHub][issue search].
- Also test if the latest release and devel branch are affected too.
- *Complete **all** sections as described, this form is processed automatically.*
-
- [issue search]: https://github.com/ansible-collections/community.sap/search?q=is%3Aissue&type=issues
-
-
-- type: textarea
- attributes:
- label: Summary
- description: |
- Explain the problem briefly below, add suggestions to wording or structure.
-
- **HINT:** Did you know the documentation has an `Edit on GitHub` link on every page?
- placeholder: >-
- I was reading the Collection documentation of version X and I'm having
- problems understanding Y. It would be very helpful if that got
- rephrased as Z.
- validations:
- required: true
-
-- type: dropdown
- attributes:
- label: Issue Type
- # FIXME: Once GitHub allows defining the default choice, update this
- options:
- - Documentation Report
- validations:
- required: true
-
-- type: input
- attributes:
- label: Component Name
- description: >-
- Write the short name of the rst file, module, plugin, task or
- feature below, *use your best guess if unsure*.
- placeholder: mysql_user
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Ansible Version
- description: >-
- Paste verbatim output from `ansible --version` between
- tripple backticks.
- value: |
- ```console (paste below)
- $ ansible --version
-
- ```
- validations:
- required: false
-
-- type: textarea
- attributes:
- label: Community.general Version
- description: >-
- Paste verbatim output from "ansible-galaxy collection list community.sap"
- between tripple backticks.
- value: |
- ```console (paste below)
- $ ansible-galaxy collection list community.sap
-
- ```
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Configuration
- description: >-
- Paste verbatim output from `ansible-config dump --only-changed` between quotes.
- value: |
- ```console (paste below)
- $ ansible-config dump --only-changed
-
- ```
- validations:
- required: false
-
-- type: textarea
- attributes:
- label: OS / Environment
- description: >-
- Provide all relevant information below, e.g. OS version,
- browser, etc.
- placeholder: SLES, RHEL
- validations:
- required: false
-
-- type: textarea
- attributes:
- label: Additional Information
- description: |
- Describe how this improves the documentation, e.g. before/after situation or screenshots.
-
- **Tip:** It's not possible to upload the screenshot via this field directly but you can use the last textarea in this form to attach them.
-
- **HINT:** You can paste https://gist.github.com links for larger files.
- placeholder: >-
- When the improvement is applied, it makes it more straightforward
- to understand X.
- validations:
- required: false
-
-- type: checkboxes
- attributes:
- label: Code of Conduct
- description: |
- Read the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--ansible-collections) first.
- options:
- - label: I agree to follow the Ansible Code of Conduct
- required: true
-...
diff --git a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/feature_request.yml b/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/feature_request.yml
deleted file mode 100644
index 08de7a62e..000000000
--- a/ansible_collections/community/sap/.github/ISSUE_TEMPLATE/feature_request.yml
+++ /dev/null
@@ -1,69 +0,0 @@
----
-name: Feature request
-description: Suggest an idea for this project
-
-body:
-- type: markdown
- attributes:
- value: |
- âš 
- Verify first that your issue is not [already reported on GitHub][issue search].
- Also test if the latest release and devel branch are affected too.
- *Complete **all** sections as described, this form is processed automatically.*
-
- [issue search]: https://github.com/ansible-collections/community.sap/search?q=is%3Aissue&type=issues
-
-
-- type: textarea
- attributes:
- label: Summary
- description: Describe the new feature/improvement briefly below.
- placeholder: >-
- I am trying to do X with the collection from the main branch on GitHub and
- I think that implementing a feature Y would be very helpful for me and
- every other user of community.sap because of Z.
- validations:
- required: true
-
-- type: dropdown
- attributes:
- label: Issue Type
- # FIXME: Once GitHub allows defining the default choice, update this
- options:
- - Feature Idea
- validations:
- required: true
-
-- type: input
- attributes:
- label: Component Name
- description: >-
- Write the short name of the module, plugin, task or feature below,
- *use your best guess if unsure*.
- placeholder: dnf, apt, yum, pip, user etc.
- validations:
- required: true
-
-- type: textarea
- attributes:
- label: Additional Information
- description: |
- Describe how the feature would be used, why it is needed and what it would solve.
-
- **HINT:** You can paste https://gist.github.com links for larger files.
- value: |
- <!--- Paste example playbooks or commands between quotes below -->
- ```yaml (paste below)
-
- ```
- validations:
- required: false
-- type: checkboxes
- attributes:
- label: Code of Conduct
- description: |
- Read the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--ansible-collections) first.
- options:
- - label: I agree to follow the Ansible Code of Conduct
- required: true
-...
diff --git a/ansible_collections/community/sap/.github/workflows/ansible-test.yml b/ansible_collections/community/sap/.github/workflows/ansible-test.yml
deleted file mode 100644
index c29b8123a..000000000
--- a/ansible_collections/community/sap/.github/workflows/ansible-test.yml
+++ /dev/null
@@ -1,126 +0,0 @@
-# name: CI
-# on:
-# # Run CI against all pushes (direct commits, also merged PRs), Pull Requests
-# push:
-# pull_request:
-# # Run CI once per day (at 06:00 UTC)
-# # This ensures that even if there haven't been commits that we are still testing against latest version of ansible-test for each ansible-base version
-# schedule:
-# - cron: '0 6 * * *'
-# env:
-# NAMESPACE: community
-# COLLECTION_NAME: sap
-
-# jobs:
-# sanity:
-# name: Sanity (â’¶${{ matrix.ansible }})
-# strategy:
-# matrix:
-# ansible:
-# - stable-2.9
-# - stable-2.10
-# - stable-2.11
-# - stable-2.12
-# - devel
-# runs-on: ubuntu-latest
-# steps:
-
-# - name: Check out code
-# uses: actions/checkout@v2
-
-# - name: Perform sanity testing with ansible-test
-# uses: ansible-community/ansible-test-gh-action@release/v1
-# with:
-# ansible-core-version: ${{ matrix.ansible }}
-# testing-type: sanity
-
-
-# units:
-# runs-on: ubuntu-latest
-# name: Units (â’¶${{ matrix.ansible }}+py${{ matrix.python }})
-# strategy:
-# # As soon as the first unit test fails, cancel the others to free up the CI queue
-# fail-fast: true
-# matrix:
-# ansible:
-# - stable-2.9 # Only if your collection supports Ansible 2.9
-# - stable-2.10
-# - stable-2.11
-# - stable-2.12
-# - devel
-# python:
-# - 2.6
-# - 2.7
-# - 3.5
-# - 3.6
-# - 3.7
-# - 3.8
-# - 3.9
-# exclude:
-# # Because ansible-test doesn't support python3.9 for Ansible 2.9
-# - ansible: stable-2.9
-# python: 3.9
-# - ansible: devel
-# python: 2.6
-
-# steps:
-# - name: Check out code
-# uses: actions/checkout@v2
-
-# - name: Perform unit testing with ansible-test
-# uses: ansible-community/ansible-test-gh-action@release/v1
-# with:
-# ansible-core-version: ${{ matrix.ansible }}
-# target-python-version: ${{ matrix.python }}
-# python-version: 3.8
-# testing-type: units
-# test-deps: >-
-# ansible.netcommon
-# ansible.utils
-
-# # Please consult the Readme for information on why we disabled integration tests temporarily.
-
-# # integration:
-# # runs-on: ubuntu-latest
-# # name: I (â’¶${{ matrix.ansible }}+py${{ matrix.python }})
-# # strategy:
-# # fail-fast: false
-# # matrix:
-# # ansible:
-# # - stable-2.9 # Only if your collection supports Ansible 2.9
-# # - stable-2.10
-# # - stable-2.11
-# # - stable-2.12
-# # - devel
-# # python:
-# # - 2.6
-# # - 2.7
-# # - 3.5
-# # - 3.6
-# # - 3.7
-# # - 3.8
-# # - 3.9
-# # exclude:
-# # # Because ansible-test doesn't support python3.9 for Ansible 2.9
-# # - ansible: stable-2.9
-# # python: 3.9
-# # - ansible: devel
-# # python: 2.6
-
-# # steps:
-# # - name: Check out code
-# # uses: actions/checkout@v2
-
-# # - name: Perform integration testing with ansible-test
-# # uses: ansible-community/ansible-test-gh-action@release/v1
-# # with:
-# # ansible-core-version: ${{ matrix.ansible }}
-# # python-version: 3.8
-# # pre-test-cmd: >-
-# # mkdir -p tests/output/
-# # touch tests/output/coverage
-# # target-python-version: ${{ matrix.python }}
-# # testing-type: integration
-# # test-deps: >-
-# # ansible.netcommon
-# # ansible.utils
diff --git a/ansible_collections/community/sap/.vscode/extensions.json b/ansible_collections/community/sap/.vscode/extensions.json
deleted file mode 100644
index 1450d869d..000000000
--- a/ansible_collections/community/sap/.vscode/extensions.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "recommendations": [
- "redhat.ansible"
- ]
-}
diff --git a/ansible_collections/community/sap/CHANGELOG.rst b/ansible_collections/community/sap/CHANGELOG.rst
deleted file mode 100644
index 714ed15a5..000000000
--- a/ansible_collections/community/sap/CHANGELOG.rst
+++ /dev/null
@@ -1,87 +0,0 @@
-===========================
-Community SAP Release Notes
-===========================
-
-.. contents:: Topics
-
-
-v2.0.0
-======
-
-Release Summary
----------------
-
-This release deprecates all modules and redirect them to community.sap_libs. The modules are removed in this release.
-The modules are available in the community.sap_libs repository.
-
-Major Changes
--------------
-
-- all modules - everything is now a redirect to the new collection community.sap_libs
-
-Deprecated Features
--------------------
-
-- community.sap.hana_query - is deprecated in favor of community.sap_libs.sap_hdbsql
-- community.sap.sap_company - is deprecated in favor of community.sap_libs.sap_company
-- community.sap.sap_snote - is deprecated in favor of community.sap_libs.sap_snote
-- community.sap.sap_task_list_execute - is deprecated in favor of community.sap_libs.sap_task_list_execute
-- community.sap.sap_user - is deprecated in favor of community.sap_libs.sap_user
-- community.sap.sapcar_extract - is deprecated in favor of community.sap_libs.sapcar_extract
-
-v1.0.0
-======
-
-Release Summary
----------------
-
-This is the first major release of the ``community.sap`` collection. This changelog contains all changes to the modules and plugins in this collection that have been made after the previous release.
-
-Minor Changes
--------------
-
-- sapcar_extract.py - more strict logic for filenames
-
-New Modules
------------
-
-Identity
-~~~~~~~~
-
-- sap_company - This module will manage a company entities in a SAP S4HANA environment
-- sap_user - This module will manage a user entities in a SAP S4/HANA environment
-
-System
-~~~~~~
-
-- sap_snote - This module will upload and (de)implements C(SNOTES) in a SAP S4HANA environment.
-- sap_system_facts - Gathers SAP facts in a host
-
-v0.1.0
-======
-
-Release Summary
----------------
-
-This is the minor release of the ``community.sap`` collection. It is the initial relase for the ``community.sap`` collection
-
-New Modules
------------
-
-Database
-~~~~~~~~
-
-saphana
-^^^^^^^
-
-- hana_query - Execute SQL on HANA
-
-Files
-~~~~~
-
-- sapcar_extract - Manages SAP SAPCAR archives
-
-System
-~~~~~~
-
-- sap_task_list_execute - Perform SAP Task list execution
diff --git a/ansible_collections/community/sap/CODE_OF_CONDUCT.md b/ansible_collections/community/sap/CODE_OF_CONDUCT.md
deleted file mode 100644
index 0164155b8..000000000
--- a/ansible_collections/community/sap/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Community Code of Conduct
-
-Please see the official [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
diff --git a/ansible_collections/community/sap/CONTRIBUTING.md b/ansible_collections/community/sap/CONTRIBUTING.md
deleted file mode 100644
index b4a17dec0..000000000
--- a/ansible_collections/community/sap/CONTRIBUTING.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Contributing
-
-Refer to the [Contributing guidelines](https://github.com/ansible/community-docs/blob/main/contributing.rst).
diff --git a/ansible_collections/community/sap/FILES.json b/ansible_collections/community/sap/FILES.json
deleted file mode 100644
index 05e702336..000000000
--- a/ansible_collections/community/sap/FILES.json
+++ /dev/null
@@ -1,544 +0,0 @@
-{
- "files": [
- {
- "name": ".",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".github",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".github/ISSUE_TEMPLATE",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".github/ISSUE_TEMPLATE/bug_report.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "eca22676ac9e0554bbdf3ca8cbddcae9e9961de4be8b724fd317c9a0dbd652e1",
- "format": 1
- },
- {
- "name": ".github/ISSUE_TEMPLATE/config.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "2e5f08c57601d637ec507daec616f993993d16f51892ca62214932b4fad0dcd9",
- "format": 1
- },
- {
- "name": ".github/ISSUE_TEMPLATE/documentation_report.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "414b304e8a6f53a78268617968d2386d46bbb421eab7ce9e82e1902fe541cd43",
- "format": 1
- },
- {
- "name": ".github/ISSUE_TEMPLATE/feature_request.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "b59211fd4dc558d2573f89528699e52f36925e0d11e00a4542ff74ebdc19d1e0",
- "format": 1
- },
- {
- "name": ".github/workflows",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".github/workflows/ansible-test.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "141fb2c403baf2847bf06f9281f397e22fc5325262ef017cace4bde09d6f803d",
- "format": 1
- },
- {
- "name": ".vscode",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": ".vscode/extensions.json",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "f72b83e1aa1301adb18ce0fe71ce6613d3cfb148f881b3e39c55359d41d3277f",
- "format": 1
- },
- {
- "name": "changelogs",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "changelogs/fragments",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "changelogs/fragments/.keep",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "changelogs/changelog.yaml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d58ffee3cafd91ae2cebaa92a66100609fcf1a19501b2e00c1d5b93d0bbc7fcb",
- "format": 1
- },
- {
- "name": "changelogs/config.yaml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "5f253a9432287fcdfe3100b556bf39d442a5e8b5a5fd3ec4a971f37f954ebac0",
- "format": 1
- },
- {
- "name": "meta",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "meta/runtime.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "9a8c86337928225fea4abd7361f2813f48b1770c4ae83aac940e7b491a4e143a",
- "format": 1
- },
- {
- "name": "plugins",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/doc_fragments",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/doc_fragments/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "plugins/module_utils",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/module_utils/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "plugins/modules",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/modules/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/integration",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/integration/targets",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/integration/targets/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/integration/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/sanity",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/sanity/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/compat",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/compat/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/compat/builtins.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "0ca4cac919e166b25e601e11acb01f6957dddd574ff0a62569cb994a5ecb63e1",
- "format": 1
- },
- {
- "name": "tests/unit/compat/mock.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "0af958450cf6de3fbafe94b1111eae8ba5a8dbe1d785ffbb9df81f26e4946d99",
- "format": 1
- },
- {
- "name": "tests/unit/compat/unittest.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "5401a046e5ce71fa19b6d905abd0f9bdf816c0c635f7bdda6730b3ef06e67096",
- "format": 1
- },
- {
- "name": "tests/unit/mock",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/mock/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/mock/loader.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "3452ac615f89c99a76d1df4ab1ad84d1aff546e5b5fde18034a241239690d05a",
- "format": 1
- },
- {
- "name": "tests/unit/mock/path.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "f048a12629a6297a676ea56529ecf766cff30bcaa873c6659ac5b7f6e29472b1",
- "format": 1
- },
- {
- "name": "tests/unit/mock/procenv.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e79b2fe520af92318da175c231296e16bf047842a93b1bfa4e1a5afc453baa03",
- "format": 1
- },
- {
- "name": "tests/unit/mock/vault_helper.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "0562db7b9972e6378701e3492c623e5f881732c4792e096032b72c2e54d22298",
- "format": 1
- },
- {
- "name": "tests/unit/mock/yaml_helper.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "cd95a4807e52e9123a8d40132a5f52b75cbc1496e1a32b104b2655bf631cfee4",
- "format": 1
- },
- {
- "name": "tests/unit/plugins",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/database",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/database/saphana",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/database/saphana/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/database/saphana/test_hana_query.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "db8e986504233653384f9b7735c89bb9ab992f48d289494233faf01290f03dc8",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/database/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/files",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/files/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/files/test_sapcar_extract.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "07521a13ba3f072fcd568ced0847c27cf9493f1578f16ab644092e32fcbc83fb",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/identity",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/identity/test_sap_company.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "aee30ac135204fbfbce16477ad2ab3b869b148b80064bf79623aef29e151335f",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/identity/test_sap_user.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "815d8ab9d13edd585fd0c8003fb885f689fe78bebd75ad837141e5093fc5680d",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/system",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/system/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/system/test_sap_snote.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "46a0b927837a539f7e8c995a47beb0b4be708b1c12eb64c4d7c90a0f10a7c929",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/system/test_sap_system_facts.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "f2992ecb0a55a5c93837194c493a4d7f9afe0604dcba0c92eee06cd967e002ab",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/system/test_sap_task_list_execute.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "492b377795da0aa4e5208b6bfae17e8363660aa3ca92e07a374c9c5702c30550",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/modules/utils.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "1427709f0a160776d54c9c78b353caf5d0833819f3ad14f414b523938c467d4d",
- "format": 1
- },
- {
- "name": "tests/unit/plugins/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/__init__.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
- "format": 1
- },
- {
- "name": "tests/unit/requirements.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "57ca135f60a45a67968cae026a738c74d287bd1a69cf99b20e6c0b02ebc72b35",
- "format": 1
- },
- {
- "name": "CHANGELOG.rst",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "63e3ec595a36659d4977981c1abfd3c8efb0fe2eace862746feabe968e13ba3f",
- "format": 1
- },
- {
- "name": "CODE_OF_CONDUCT.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "14ec928234a7ed52bf8b458d31e4862335111e477e4dbe7fb543686c24115140",
- "format": 1
- },
- {
- "name": "CONTRIBUTING.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "eec219dbc09446ed3e9938c8f66378621a0548b056426df33e3ea32e26bb4dc8",
- "format": 1
- },
- {
- "name": "LICENSE",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986",
- "format": 1
- },
- {
- "name": "MAINTAINERS",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "bc751d90416fb1652ef9a5d35d8f60f5e050bc9735eb2fe26378d1695fd1ac46",
- "format": 1
- },
- {
- "name": "MAINTAINING.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "2435665a6562d5f3841fff1631970f95f0466c498e949d2b8579ccc2a0b810ad",
- "format": 1
- },
- {
- "name": "README.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "d600b5ca720d33e93ee89c9bdfba410c8f7dc435fa29ea7ca4ebfa3159f4311b",
- "format": 1
- },
- {
- "name": "REVIEW_CHECKLIST.md",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "91ad4aff2cc14b98f81fbe2d90609c5a69ed96b6d836387a9c697c1112e603c0",
- "format": 1
- },
- {
- "name": "codecov.yml",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "125a07797a54aa0dcd4d5233a69856802686cd567d600fb55abf9e4fdbf56fa6",
- "format": 1
- }
- ],
- "format": 1
-} \ No newline at end of file
diff --git a/ansible_collections/community/sap/LICENSE b/ansible_collections/community/sap/LICENSE
deleted file mode 100644
index f288702d2..000000000
--- a/ansible_collections/community/sap/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<https://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/ansible_collections/community/sap/MAINTAINERS b/ansible_collections/community/sap/MAINTAINERS
deleted file mode 100644
index 6e30606b6..000000000
--- a/ansible_collections/community/sap/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-rainerleber
-rkpobe \ No newline at end of file
diff --git a/ansible_collections/community/sap/MAINTAINING.md b/ansible_collections/community/sap/MAINTAINING.md
deleted file mode 100644
index 9fad0d343..000000000
--- a/ansible_collections/community/sap/MAINTAINING.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Maintaining this collection
-
-Refer to the [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst).
diff --git a/ansible_collections/community/sap/MANIFEST.json b/ansible_collections/community/sap/MANIFEST.json
deleted file mode 100644
index 5385f2f71..000000000
--- a/ansible_collections/community/sap/MANIFEST.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "collection_info": {
- "namespace": "community",
- "name": "sap",
- "version": "2.0.0",
- "authors": [
- "Rainer Leber (github.com/rainerleber)",
- "Robert Kraemer (github.com/rkpobe)"
- ],
- "readme": "README.md",
- "tags": [
- "sap"
- ],
- "description": "SAP community collection for Ansible",
- "license": [],
- "license_file": "LICENSE",
- "dependencies": {
- "community.sap_libs": ">=1.0.0"
- },
- "repository": "https://github.com/ansible-collections/community.sap",
- "documentation": "https://github.com/ansible-collection/community.sap",
- "homepage": "https://github.com/ansible-collections/community.sap",
- "issues": "https://github.com/ansible-collections/community.sap/issues"
- },
- "file_manifest_file": {
- "name": "FILES.json",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "90eb59f365d6576a46b04852a21d5998d4ad14dcbb20ae1547d5a1667dcda9d9",
- "format": 1
- },
- "format": 1
-} \ No newline at end of file
diff --git a/ansible_collections/community/sap/README.md b/ansible_collections/community/sap/README.md
deleted file mode 100644
index dd935b270..000000000
--- a/ansible_collections/community/sap/README.md
+++ /dev/null
@@ -1,181 +0,0 @@
-# Deprecated Community SAP Collection
-
-# **WARNING: This collection is deprecated, not maintained anymore and superseded by the collection [**community.sap_libs**](https://github.com/sap-linuxlab/community.sap_libs)**
-
-**Feel free to raise issues at the new place.
-All CI tests are disabled.**
-
----
-This repository contains the community.sap Ansible Collection. The collection includes modules and plugins supported by the Ansible SAP community to help SAP landscape management.
-
-# SAP Collection for Ansible
-<!-- Add CI and code coverage badges here. Samples included below. -->
-[![CI](https://github.com/ansible-collections/community.sap/workflows/CI/badge.svg?event=push)](https://github.com/ansible-collections/community.sap/actions) [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.sap)](https://codecov.io/gh/ansible-collections/community.sap)
-
-<!-- Describe the collection and why a user would want to use it. What does the collection do? -->
-
-## Code of Conduct
-
-We follow the [Ansible Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html) in all our interactions within this project.
-
-If you encounter abusive behavior, please refer to the [policy violations](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html#policy-violations) section of the Code for information on how to raise a complaint.
-
-## Communication
-
-<!--List available communication channels. In addition to channels specific to your collection, we also recommend to use the following ones.-->
-
-We announce releases and important changes through Ansible's [The Bullhorn newsletter](https://github.com/ansible/community/wiki/News#the-bullhorn). Be sure you are [subscribed](https://eepurl.com/gZmiEP).
-
-Join us in the `#ansible` (general use questions and support), `#ansible-community` (community and collection development questions), and other [Matrix/LiberaChat IRC channels](https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat).
-
-We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
-
-For more information about communication, refer to the [Ansible Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
-
-## Contributing to this collection
-
-<!--Describe how the community can contribute to your collection. At a minimum, fill up and include the CONTRIBUTING.md file containing how and where users can create issues to report problems or request features for this collection. List contribution requirements, including preferred workflows and necessary testing, so you can benefit from community PRs. If you are following general Ansible contributor guidelines, you can link to - [Ansible Community Guide](https://docs.ansible.com/ansible/devel/community/index.html). List the current maintainers (contributors with write or higher access to the repository). The following can be included:-->
-
-The content of this collection is made by people like you, a community of individuals collaborating on making the world better through developing automation software.
-
-We are actively accepting new contributors.
-
-Any kind of contribution is very welcome.
-
-You don't know how to start? Refer to our [contribution guide](CONTRIBUTING.md)!
-
-We use the following guidelines:
-
-* [CONTRIBUTING.md](CONTRIBUTING.md)
-* [REVIEW_CHECKLIST.md](REVIEW_CHECKLIST.md)
-* [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html)
-* [Ansible Development Guide](https://docs.ansible.com/ansible/devel/dev_guide/index.html)
-* [Ansible Collection Development Guide](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections)
-
-## Collection maintenance
-
-The current maintainers are listed in the [MAINTAINERS](MAINTAINERS) file. If you have questions or need help, feel free to mention them in the proposals.
-
-To learn how to maintain / become a maintainer of this collection, refer to the [Maintainer guidelines](MAINTAINING.md).
-
-## Governance
-
-<!--Describe how the collection is governed. Here can be the following text:-->
-
-The process of decision making in this collection is based on discussing and finding consensus among participants.
-
-Every voice is important. If you have something on your mind, create an issue or dedicated discussion and let's discuss it!
-
-## Tested with Ansible and the following Python versions
-
-Tested Ansible versions:
-- 2.9
-- 2.10
-- 2.11
-- 2.12
-- devel
-
-Tested Python versions:
-- 2.6
-- 2.7
-- 3.5
-- 3.6
-- 3.7
-- 3.8
-- 3.9
-
-Due to SAP licensing and hardware requirements, integration tests are momentarily not feasible.
-The modules are tested manually against SAP systems until we found a solution or have some
-modules where we are able to execute integration test we decided to disable these tests.
-
-## External requirements
-
-For some modules the below requirements are needed on the host that executes a module.
-
-- pyrfc >= 2.4.0
-- SAPCAR
-- SAPCONTROL
-
-### Supported connections
-<!-- Optional. If your collection supports only specific connection types (such as HTTPAPI, netconf, or others), list them here. -->
-
-## Included content
-
-- **Modules**:
- - [hana_query](https://docs.ansible.com/ansible/latest/collections/community/sap/hana_query.html)
- - [sap_task_list_execute](https://docs.ansible.com/ansible/latest/collections/community/sap/sap_task_list_execute.html)
- - [sapcar_extract](https://docs.ansible.com/ansible/latest/collections/community/sap/sapcar_extract.html)
- - [sap_company](https://docs.ansible.com/ansible/latest/collections/community/sap/sap_company.html)
- - [sap_snote](https://docs.ansible.com/ansible/latest/collections/community/sap/sap_snote.html)
- - [sap_user](https://docs.ansible.com/ansible/latest/collections/community/sap/sap_user.html)
- - [sap_system_facts](https://docs.ansible.com/ansible/latest/collections/community/sap/sap_system_facts.html)
-
-## Using this collection
-
-<!--Include some quick examples that cover the most common use cases for your collection content. It can include the following examples of installation and upgrade (change NAMESPACE.COLLECTION_NAME correspondingly):-->
-
-### Installing the Collection from Ansible Galaxy
-
-Before using this collection, you need to install it with the Ansible Galaxy command-line tool:
-```bash
-ansible-galaxy collection install community.sap
-```
-
-You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format:
-```yaml
----
-collections:
- - name: community.sap
-```
-
-Note that if you install the collection from Ansible Galaxy, it will not be upgraded automatically when you upgrade the `ansible` package. To upgrade the collection to the latest available version, run the following command:
-```bash
-ansible-galaxy collection install community.sap --upgrade
-```
-
-You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax to install version `0.1.0`:
-
-```bash
-ansible-galaxy collection install community.sap:==0.1.0
-```
-
-See [Ansible Using collections](https://docs.ansible.com/ansible/devel/user_guide/collections_using.html) for more details.
-
-## Release notes
-
-See the [changelog](https://github.com/ansible-collections/community.sap/tree/main/CHANGELOG.rst).
-
-## Releasing, Versioning and Deprecation
-This collection follows Semantic Versioning. More details on versioning can be found in the Ansible docs.
-
-We plan to regularly release new minor or bugfix versions once new features or bugfixes have been implemented.
-
-Releasing the current major version happens from the main branch. We will create a stable-1 branch for 1.x.y versions once we start working on a 2.0.0 release, to allow backporting bugfixes and features from the 2.0.0 branch (main) to stable-1.
-
-For reference have a look at the issue [Releasing, Versioning and Deprecation](https://github.com/ansible-collections/community.sap/issues/4).
-
-
-
-## Roadmap
-
-Please have a look at the project board.
-
-## More information
-
-<!-- List out where the user can find additional information, such as working group meeting times, slack/IRC channels, or documentation for the product this collection automates. At a minimum, link to: -->
-
-- [Ansible Collection overview](https://github.com/ansible-collections/overview)
-- [Ansible User guide](https://docs.ansible.com/ansible/devel/user_guide/index.html)
-- [Ansible Developer guide](https://docs.ansible.com/ansible/devel/dev_guide/index.html)
-- [Ansible Collections Checklist](https://github.com/ansible-collections/overview/blob/master/collection_requirements.rst)
-- [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html)
-- [The Bullhorn (the Ansible Contributor newsletter)](https://us19.campaign-archive.com/home/?u=56d874e027110e35dea0e03c1&id=d6635f5420)
-- [News for Maintainers](https://github.com/ansible-collections/news-for-maintainers)
-
-## Licensing
-
-<!-- Include the appropriate license information here and a pointer to the full licensing details. If the collection contains modules migrated from the ansible/ansible repo, you must use the same license that existed in the ansible/ansible repo. See the GNU license example below. -->
-
-GNU General Public License v3.0 or later.
-
-See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text.
diff --git a/ansible_collections/community/sap/REVIEW_CHECKLIST.md b/ansible_collections/community/sap/REVIEW_CHECKLIST.md
deleted file mode 100644
index 9dccf7ef1..000000000
--- a/ansible_collections/community/sap/REVIEW_CHECKLIST.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Review Checklist
-
-Refer to the [Collection review checklist](https://github.com/ansible/community-docs/blob/main/review_checklist.rst).
diff --git a/ansible_collections/community/sap/changelogs/changelog.yaml b/ansible_collections/community/sap/changelogs/changelog.yaml
deleted file mode 100644
index 39f79a298..000000000
--- a/ansible_collections/community/sap/changelogs/changelog.yaml
+++ /dev/null
@@ -1,63 +0,0 @@
-ancestor: null
-releases:
- 0.1.0:
- changes:
- release_summary: This is the minor release of the ``community.sap`` collection.
- It is the initial relase for the ``community.sap`` collection
- fragments:
- - 0.1.0.yml
- modules:
- - description: Execute SQL on HANA
- name: hana_query
- namespace: database.saphana
- - description: Perform SAP Task list execution
- name: sap_task_list_execute
- namespace: system
- - description: Manages SAP SAPCAR archives
- name: sapcar_extract
- namespace: files
- release_date: '2021-12-06'
- 1.0.0:
- changes:
- minor_changes:
- - sapcar_extract.py - more strict logic for filenames
- release_summary: This is the first major release of the ``community.sap`` collection.
- This changelog contains all changes to the modules and plugins in this collection
- that have been made after the previous release.
- fragments:
- - 1.0.0.yml
- - 11-filenamesuffixcheck.yml
- modules:
- - description: This module will manage a company entities in a SAP S4HANA environment
- name: sap_company
- namespace: identity
- - description: This module will upload and (de)implements C(SNOTES) in a SAP S4HANA
- environment.
- name: sap_snote
- namespace: system
- - description: Gathers SAP facts in a host
- name: sap_system_facts
- namespace: system
- - description: This module will manage a user entities in a SAP S4/HANA environment
- name: sap_user
- namespace: identity
- release_date: '2022-02-17'
- 2.0.0:
- changes:
- deprecated_features:
- - community.sap.hana_query - is deprecated in favor of community.sap_libs.sap_hdbsql
- - community.sap.sap_company - is deprecated in favor of community.sap_libs.sap_company
- - community.sap.sap_snote - is deprecated in favor of community.sap_libs.sap_snote
- - community.sap.sap_task_list_execute - is deprecated in favor of community.sap_libs.sap_task_list_execute
- - community.sap.sap_user - is deprecated in favor of community.sap_libs.sap_user
- - community.sap.sapcar_extract - is deprecated in favor of community.sap_libs.sapcar_extract
- major_changes:
- - all modules - everything is now a redirect to the new collection community.sap_libs
- release_summary: 'This release deprecates all modules and redirect them to community.sap_libs.
- The modules are removed in this release.
-
- The modules are available in the community.sap_libs repository.'
- fragments:
- - 0029-deprecation.yml
- - 2.0.0.yml
- release_date: '2023-07-14'
diff --git a/ansible_collections/community/sap/changelogs/config.yaml b/ansible_collections/community/sap/changelogs/config.yaml
deleted file mode 100644
index db443763c..000000000
--- a/ansible_collections/community/sap/changelogs/config.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-changelog_filename_template: ../CHANGELOG.rst
-changelog_filename_version_depth: 0
-changes_file: changelog.yaml
-changes_format: combined
-keep_fragments: false
-mention_ancestor: true
-flatmap: true
-new_plugins_after_name: removed_features
-notesdir: fragments
-prelude_section_name: release_summary
-prelude_section_title: Release Summary
-sections:
-- - major_changes
- - Major Changes
-- - minor_changes
- - Minor Changes
-- - breaking_changes
- - Breaking Changes / Porting Guide
-- - deprecated_features
- - Deprecated Features
-- - removed_features
- - Removed Features (previously deprecated)
-- - security_fixes
- - Security Fixes
-- - bugfixes
- - Bugfixes
-- - known_issues
- - Known Issues
-title: Community SAP
-trivial_section_name: trivial
diff --git a/ansible_collections/community/sap/changelogs/fragments/.keep b/ansible_collections/community/sap/changelogs/fragments/.keep
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/changelogs/fragments/.keep
+++ /dev/null
diff --git a/ansible_collections/community/sap/codecov.yml b/ansible_collections/community/sap/codecov.yml
deleted file mode 100644
index 604cc9ba0..000000000
--- a/ansible_collections/community/sap/codecov.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-fixes:
- - "/ansible_collections/community/sap/::"
diff --git a/ansible_collections/community/sap/meta/runtime.yml b/ansible_collections/community/sap/meta/runtime.yml
deleted file mode 100644
index 15cbcba59..000000000
--- a/ansible_collections/community/sap/meta/runtime.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-requires_ansible: '>=2.9.10'
-
-plugin_routing:
- modules:
- community.sap.hana_query:
- redirect: community.sap_libs.sap_hdbsql
- deprecation:
- warning_text: Use community.sap_libs.sap_hdbsql instead.
- community.sap.sap_company:
- redirect: community.sap_libs.sap_company
- deprecation:
- warning_text: Use community.sap_libs.sap_company instead.
- community.sap.sap_snote:
- redirect: community.sap_libs.sap_snote
- deprecation:
- warning_text: Use community.sap_libs.sap_snote instead.
- community.sap.sap_snote:
- redirect: community.sap_libs.sap_system_facts
- deprecation:
- warning_text: Use community.sap_libs.sap_system_facts instead.
- community.sap.sap_user:
- redirect: community.sap_libs.sap_user
- deprecation:
- warning_text: Use community.sap_libs.sap_user instead.
- community.sap.sap_task_list_execute:
- redirect: community.sap_libs.sap_task_list_execute
- deprecation:
- warning_text: Use community.sap_libs.sap_task_list_execute instead.
- community.sap.sapcar_extract:
- redirect: community.sap_libs.sapcar_extract
- deprecation:
- warning_text: Use community.sap_libs.sapcar_extract instead.
diff --git a/ansible_collections/community/sap/plugins/doc_fragments/__init__.py b/ansible_collections/community/sap/plugins/doc_fragments/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/plugins/doc_fragments/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/plugins/module_utils/__init__.py b/ansible_collections/community/sap/plugins/module_utils/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/plugins/module_utils/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/plugins/modules/__init__.py b/ansible_collections/community/sap/plugins/modules/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/plugins/modules/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/integration/__init__.py b/ansible_collections/community/sap/tests/integration/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/integration/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/integration/targets/__init__.py b/ansible_collections/community/sap/tests/integration/targets/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/integration/targets/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/sanity/__init__.py b/ansible_collections/community/sap/tests/sanity/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/sanity/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/__init__.py b/ansible_collections/community/sap/tests/unit/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/compat/__init__.py b/ansible_collections/community/sap/tests/unit/compat/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/compat/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/compat/builtins.py b/ansible_collections/community/sap/tests/unit/compat/builtins.py
deleted file mode 100644
index f60ee6782..000000000
--- a/ansible_collections/community/sap/tests/unit/compat/builtins.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-# Make coding more python3-ish
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-#
-# Compat for python2.7
-#
-
-# One unittest needs to import builtins via __import__() so we need to have
-# the string that represents it
-try:
- import __builtin__
-except ImportError:
- BUILTINS = 'builtins'
-else:
- BUILTINS = '__builtin__'
diff --git a/ansible_collections/community/sap/tests/unit/compat/mock.py b/ansible_collections/community/sap/tests/unit/compat/mock.py
deleted file mode 100644
index 0972cd2e8..000000000
--- a/ansible_collections/community/sap/tests/unit/compat/mock.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-# Make coding more python3-ish
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-'''
-Compat module for Python3.x's unittest.mock module
-'''
-import sys
-
-# Python 2.7
-
-# Note: Could use the pypi mock library on python3.x as well as python2.x. It
-# is the same as the python3 stdlib mock library
-
-try:
- # Allow wildcard import because we really do want to import all of mock's
- # symbols into this compat shim
- # pylint: disable=wildcard-import,unused-wildcard-import
- from unittest.mock import *
-except ImportError:
- # Python 2
- # pylint: disable=wildcard-import,unused-wildcard-import
- try:
- from mock import *
- except ImportError:
- print('You need the mock library installed on python2.x to run tests')
-
-
-# Prior to 3.4.4, mock_open cannot handle binary read_data
-if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
- file_spec = None
-
- def _iterate_read_data(read_data):
- # Helper for mock_open:
- # Retrieve lines from read_data via a generator so that separate calls to
- # readline, read, and readlines are properly interleaved
- sep = b'\n' if isinstance(read_data, bytes) else '\n'
- data_as_list = [l + sep for l in read_data.split(sep)]
-
- if data_as_list[-1] == sep:
- # If the last line ended in a newline, the list comprehension will have an
- # extra entry that's just a newline. Remove this.
- data_as_list = data_as_list[:-1]
- else:
- # If there wasn't an extra newline by itself, then the file being
- # emulated doesn't have a newline to end the last line remove the
- # newline that our naive format() added
- data_as_list[-1] = data_as_list[-1][:-1]
-
- for line in data_as_list:
- yield line
-
- def mock_open(mock=None, read_data=''):
- """
- A helper function to create a mock to replace the use of `open`. It works
- for `open` called directly or used as a context manager.
-
- The `mock` argument is the mock object to configure. If `None` (the
- default) then a `MagicMock` will be created for you, with the API limited
- to methods or attributes available on standard file handles.
-
- `read_data` is a string for the `read` methoddline`, and `readlines` of the
- file handle to return. This is an empty string by default.
- """
- def _readlines_side_effect(*args, **kwargs):
- if handle.readlines.return_value is not None:
- return handle.readlines.return_value
- return list(_data)
-
- def _read_side_effect(*args, **kwargs):
- if handle.read.return_value is not None:
- return handle.read.return_value
- return type(read_data)().join(_data)
-
- def _readline_side_effect():
- if handle.readline.return_value is not None:
- while True:
- yield handle.readline.return_value
- for line in _data:
- yield line
-
- global file_spec
- if file_spec is None:
- import _io
- file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))))
-
- if mock is None:
- mock = MagicMock(name='open', spec=open)
-
- handle = MagicMock(spec=file_spec)
- handle.__enter__.return_value = handle
-
- _data = _iterate_read_data(read_data)
-
- handle.write.return_value = None
- handle.read.return_value = None
- handle.readline.return_value = None
- handle.readlines.return_value = None
-
- handle.read.side_effect = _read_side_effect
- handle.readline.side_effect = _readline_side_effect()
- handle.readlines.side_effect = _readlines_side_effect
-
- mock.return_value = handle
- return mock
diff --git a/ansible_collections/community/sap/tests/unit/compat/unittest.py b/ansible_collections/community/sap/tests/unit/compat/unittest.py
deleted file mode 100644
index 98f08ad6a..000000000
--- a/ansible_collections/community/sap/tests/unit/compat/unittest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-# Make coding more python3-ish
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-'''
-Compat module for Python2.7's unittest module
-'''
-
-import sys
-
-# Allow wildcard import because we really do want to import all of
-# unittests's symbols into this compat shim
-# pylint: disable=wildcard-import,unused-wildcard-import
-if sys.version_info < (2, 7):
- try:
- # Need unittest2 on python2.6
- from unittest2 import *
- except ImportError:
- print('You need unittest2 installed on python2.6.x to run tests')
-else:
- from unittest import *
diff --git a/ansible_collections/community/sap/tests/unit/mock/__init__.py b/ansible_collections/community/sap/tests/unit/mock/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/mock/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/mock/loader.py b/ansible_collections/community/sap/tests/unit/mock/loader.py
deleted file mode 100644
index 5389bdcb2..000000000
--- a/ansible_collections/community/sap/tests/unit/mock/loader.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
-#
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import os
-
-from ansible.errors import AnsibleParserError
-from ansible.parsing.dataloader import DataLoader
-from ansible.module_utils.common.text.converters import to_bytes, to_text
-
-
-class DictDataLoader(DataLoader):
-
- def __init__(self, file_mapping=None):
- file_mapping = {} if file_mapping is None else file_mapping
- assert type(file_mapping) == dict
-
- super(DictDataLoader, self).__init__()
-
- self._file_mapping = file_mapping
- self._build_known_directories()
- self._vault_secrets = None
-
- def load_from_file(self, path, cache=True, unsafe=False):
- path = to_text(path)
- if path in self._file_mapping:
- return self.load(self._file_mapping[path], path)
- return None
-
- # TODO: the real _get_file_contents returns a bytestring, so we actually convert the
- # unicode/text it's created with to utf-8
- def _get_file_contents(self, file_name):
- path = to_text(file_name)
- if path in self._file_mapping:
- return (to_bytes(self._file_mapping[path]), False)
- else:
- raise AnsibleParserError("file not found: %s" % path)
-
- def path_exists(self, path):
- path = to_text(path)
- return path in self._file_mapping or path in self._known_directories
-
- def is_file(self, path):
- path = to_text(path)
- return path in self._file_mapping
-
- def is_directory(self, path):
- path = to_text(path)
- return path in self._known_directories
-
- def list_directory(self, path):
- ret = []
- path = to_text(path)
- for x in (list(self._file_mapping.keys()) + self._known_directories):
- if x.startswith(path):
- if os.path.dirname(x) == path:
- ret.append(os.path.basename(x))
- return ret
-
- def is_executable(self, path):
- # FIXME: figure out a way to make paths return true for this
- return False
-
- def _add_known_directory(self, directory):
- if directory not in self._known_directories:
- self._known_directories.append(directory)
-
- def _build_known_directories(self):
- self._known_directories = []
- for path in self._file_mapping:
- dirname = os.path.dirname(path)
- while dirname not in ('/', ''):
- self._add_known_directory(dirname)
- dirname = os.path.dirname(dirname)
-
- def push(self, path, content):
- rebuild_dirs = False
- if path not in self._file_mapping:
- rebuild_dirs = True
-
- self._file_mapping[path] = content
-
- if rebuild_dirs:
- self._build_known_directories()
-
- def pop(self, path):
- if path in self._file_mapping:
- del self._file_mapping[path]
- self._build_known_directories()
-
- def clear(self):
- self._file_mapping = dict()
- self._known_directories = []
-
- def get_basedir(self):
- return os.getcwd()
-
- def set_vault_secrets(self, vault_secrets):
- self._vault_secrets = vault_secrets
diff --git a/ansible_collections/community/sap/tests/unit/mock/path.py b/ansible_collections/community/sap/tests/unit/mock/path.py
deleted file mode 100644
index c1c075bc0..000000000
--- a/ansible_collections/community/sap/tests/unit/mock/path.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-from ansible_collections.community.general.tests.unit.compat.mock import MagicMock
-from ansible.utils.path import unfrackpath
-
-
-mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x)
diff --git a/ansible_collections/community/sap/tests/unit/mock/procenv.py b/ansible_collections/community/sap/tests/unit/mock/procenv.py
deleted file mode 100644
index 5673863e1..000000000
--- a/ansible_collections/community/sap/tests/unit/mock/procenv.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# (c) 2016, Matt Davis <mdavis@ansible.com>
-# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com>
-#
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-import json
-
-from contextlib import contextmanager
-from io import BytesIO, StringIO
-from ansible_collections.community.general.tests.unit.compat import unittest
-from ansible.module_utils.six import PY3
-from ansible.module_utils.common.text.converters import to_bytes
-
-
-@contextmanager
-def swap_stdin_and_argv(stdin_data='', argv_data=tuple()):
- """
- context manager that temporarily masks the test runner's values for stdin and argv
- """
- real_stdin = sys.stdin
- real_argv = sys.argv
-
- if PY3:
- fake_stream = StringIO(stdin_data)
- fake_stream.buffer = BytesIO(to_bytes(stdin_data))
- else:
- fake_stream = BytesIO(to_bytes(stdin_data))
-
- try:
- sys.stdin = fake_stream
- sys.argv = argv_data
-
- yield
- finally:
- sys.stdin = real_stdin
- sys.argv = real_argv
-
-
-@contextmanager
-def swap_stdout():
- """
- context manager that temporarily replaces stdout for tests that need to verify output
- """
- old_stdout = sys.stdout
-
- if PY3:
- fake_stream = StringIO()
- else:
- fake_stream = BytesIO()
-
- try:
- sys.stdout = fake_stream
-
- yield fake_stream
- finally:
- sys.stdout = old_stdout
-
-
-class ModuleTestCase(unittest.TestCase):
- def setUp(self, module_args=None):
- if module_args is None:
- module_args = {'_ansible_remote_tmp': '/tmp', '_ansible_keep_remote_files': False}
-
- args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args))
-
- # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
- self.stdin_swap = swap_stdin_and_argv(stdin_data=args)
- self.stdin_swap.__enter__()
-
- def tearDown(self):
- # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
- self.stdin_swap.__exit__(None, None, None)
diff --git a/ansible_collections/community/sap/tests/unit/mock/vault_helper.py b/ansible_collections/community/sap/tests/unit/mock/vault_helper.py
deleted file mode 100644
index 6bd2db9c3..000000000
--- a/ansible_collections/community/sap/tests/unit/mock/vault_helper.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-from ansible.module_utils.common.text.converters import to_bytes
-
-from ansible.parsing.vault import VaultSecret
-
-
-class TextVaultSecret(VaultSecret):
- '''A secret piece of text. ie, a password. Tracks text encoding.
-
- The text encoding of the text may not be the default text encoding so
- we keep track of the encoding so we encode it to the same bytes.'''
-
- def __init__(self, text, encoding=None, errors=None, _bytes=None):
- super(TextVaultSecret, self).__init__()
- self.text = text
- self.encoding = encoding or 'utf-8'
- self._bytes = _bytes
- self.errors = errors or 'strict'
-
- @property
- def bytes(self):
- '''The text encoded with encoding, unless we specifically set _bytes.'''
- return self._bytes or to_bytes(self.text, encoding=self.encoding, errors=self.errors)
diff --git a/ansible_collections/community/sap/tests/unit/mock/yaml_helper.py b/ansible_collections/community/sap/tests/unit/mock/yaml_helper.py
deleted file mode 100644
index a646c0241..000000000
--- a/ansible_collections/community/sap/tests/unit/mock/yaml_helper.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import io
-import yaml
-
-from ansible.module_utils.six import PY3
-from ansible.parsing.yaml.loader import AnsibleLoader
-from ansible.parsing.yaml.dumper import AnsibleDumper
-
-
-class YamlTestUtils(object):
- """Mixin class to combine with a unittest.TestCase subclass."""
- def _loader(self, stream):
- """Vault related tests will want to override this.
-
- Vault cases should setup a AnsibleLoader that has the vault password."""
- return AnsibleLoader(stream)
-
- def _dump_stream(self, obj, stream, dumper=None):
- """Dump to a py2-unicode or py3-string stream."""
- if PY3:
- return yaml.dump(obj, stream, Dumper=dumper)
- else:
- return yaml.dump(obj, stream, Dumper=dumper, encoding=None)
-
- def _dump_string(self, obj, dumper=None):
- """Dump to a py2-unicode or py3-string"""
- if PY3:
- return yaml.dump(obj, Dumper=dumper)
- else:
- return yaml.dump(obj, Dumper=dumper, encoding=None)
-
- def _dump_load_cycle(self, obj):
- # Each pass though a dump or load revs the 'generation'
- # obj to yaml string
- string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper)
-
- # wrap a stream/file like StringIO around that yaml
- stream_from_object_dump = io.StringIO(string_from_object_dump)
- loader = self._loader(stream_from_object_dump)
- # load the yaml stream to create a new instance of the object (gen 2)
- obj_2 = loader.get_data()
-
- # dump the gen 2 objects directory to strings
- string_from_object_dump_2 = self._dump_string(obj_2,
- dumper=AnsibleDumper)
-
- # The gen 1 and gen 2 yaml strings
- self.assertEqual(string_from_object_dump, string_from_object_dump_2)
- # the gen 1 (orig) and gen 2 py object
- self.assertEqual(obj, obj_2)
-
- # again! gen 3... load strings into py objects
- stream_3 = io.StringIO(string_from_object_dump_2)
- loader_3 = self._loader(stream_3)
- obj_3 = loader_3.get_data()
-
- string_from_object_dump_3 = self._dump_string(obj_3, dumper=AnsibleDumper)
-
- self.assertEqual(obj, obj_3)
- # should be transitive, but...
- self.assertEqual(obj_2, obj_3)
- self.assertEqual(string_from_object_dump, string_from_object_dump_3)
-
- def _old_dump_load_cycle(self, obj):
- '''Dump the passed in object to yaml, load it back up, dump again, compare.'''
- stream = io.StringIO()
-
- yaml_string = self._dump_string(obj, dumper=AnsibleDumper)
- self._dump_stream(obj, stream, dumper=AnsibleDumper)
-
- yaml_string_from_stream = stream.getvalue()
-
- # reset stream
- stream.seek(0)
-
- loader = self._loader(stream)
- # loader = AnsibleLoader(stream, vault_password=self.vault_password)
- obj_from_stream = loader.get_data()
-
- stream_from_string = io.StringIO(yaml_string)
- loader2 = self._loader(stream_from_string)
- # loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password)
- obj_from_string = loader2.get_data()
-
- stream_obj_from_stream = io.StringIO()
- stream_obj_from_string = io.StringIO()
-
- if PY3:
- yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper)
- yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper)
- else:
- yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper, encoding=None)
- yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper, encoding=None)
-
- yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue()
- yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue()
-
- stream_obj_from_stream.seek(0)
- stream_obj_from_string.seek(0)
-
- if PY3:
- yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper)
- yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper)
- else:
- yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper, encoding=None)
- yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper, encoding=None)
-
- assert yaml_string == yaml_string_obj_from_stream
- assert yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
- assert (yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string == yaml_string_stream_obj_from_stream ==
- yaml_string_stream_obj_from_string)
- assert obj == obj_from_stream
- assert obj == obj_from_string
- assert obj == yaml_string_obj_from_stream
- assert obj == yaml_string_obj_from_string
- assert obj == obj_from_stream == obj_from_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
- return {'obj': obj,
- 'yaml_string': yaml_string,
- 'yaml_string_from_stream': yaml_string_from_stream,
- 'obj_from_stream': obj_from_stream,
- 'obj_from_string': obj_from_string,
- 'yaml_string_obj_from_string': yaml_string_obj_from_string}
diff --git a/ansible_collections/community/sap/tests/unit/plugins/__init__.py b/ansible_collections/community/sap/tests/unit/plugins/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/__init__.py b/ansible_collections/community/sap/tests/unit/plugins/modules/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/database/__init__.py b/ansible_collections/community/sap/tests/unit/plugins/modules/database/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/database/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/__init__.py b/ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/test_hana_query.py b/ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/test_hana_query.py
deleted file mode 100644
index 2df6b13c9..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/database/saphana/test_hana_query.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber (@rainerleber) <rainerleber@gmail.com>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-from ansible_collections.community.sap.plugins.modules import hana_query
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import (
- AnsibleExitJson,
- AnsibleFailJson,
- ModuleTestCase,
- set_module_args,
-)
-from ansible_collections.community.sap.tests.unit.compat.mock import patch
-from ansible.module_utils import basic
-
-
-def get_bin_path(*args, **kwargs):
- """Function to return path of hdbsql"""
- return "/usr/sap/HDB/HDB01/exe/hdbsql"
-
-
-class Testhana_query(ModuleTestCase):
- """Main class for testing hana_query module."""
-
- def setUp(self):
- """Setup."""
- super(Testhana_query, self).setUp()
- self.module = hana_query
- self.mock_get_bin_path = patch.object(basic.AnsibleModule, 'get_bin_path', get_bin_path)
- self.mock_get_bin_path.start()
- self.addCleanup(self.mock_get_bin_path.stop) # ensure that the patching is 'undone'
-
- def tearDown(self):
- """Teardown."""
- super(Testhana_query, self).tearDown()
-
- def test_without_required_parameters(self):
- """Failure must occurs when all parameters are missing."""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({})
- self.module.main()
-
- def test_hana_query(self):
- """Check that result is processed."""
- set_module_args({
- 'sid': "HDB",
- 'instance': "01",
- 'encrypted': False,
- 'host': "localhost",
- 'user': "SYSTEM",
- 'password': "1234Qwer",
- 'database': "HDB",
- 'query': "SELECT * FROM users;"
- })
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = 0, 'username,name\n testuser,test user \n myuser, my user \n', ''
- with self.assertRaises(AnsibleExitJson) as result:
- hana_query.main()
- self.assertEqual(result.exception.args[0]['query_result'], [[
- {'username': 'testuser', 'name': 'test user'},
- {'username': 'myuser', 'name': 'my user'},
- ]])
- self.assertEqual(run_command.call_count, 1)
-
- def test_hana_userstore_query(self):
- """Check that result is processed with userstore."""
- set_module_args({
- 'sid': "HDB",
- 'instance': "01",
- 'encrypted': False,
- 'host': "localhost",
- 'user': "SYSTEM",
- 'userstore': True,
- 'database': "HDB",
- 'query': "SELECT * FROM users;"
- })
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = 0, 'username,name\n testuser,test user \n myuser, my user \n', ''
- with self.assertRaises(AnsibleExitJson) as result:
- hana_query.main()
- self.assertEqual(result.exception.args[0]['query_result'], [[
- {'username': 'testuser', 'name': 'test user'},
- {'username': 'myuser', 'name': 'my user'},
- ]])
- self.assertEqual(run_command.call_count, 1)
-
- def test_hana_failed_no_passwd(self):
- """Check that result is failed with no password."""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({
- 'sid': "HDB",
- 'instance': "01",
- 'encrypted': False,
- 'host': "localhost",
- 'user': "SYSTEM",
- 'database': "HDB",
- 'query': "SELECT * FROM users;"
- })
- self.module.main()
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/files/__init__.py b/ansible_collections/community/sap/tests/unit/plugins/modules/files/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/files/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/files/test_sapcar_extract.py b/ansible_collections/community/sap/tests/unit/plugins/modules/files/test_sapcar_extract.py
deleted file mode 100644
index 5fe2edd1f..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/files/test_sapcar_extract.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber (@rainerleber) <rainerleber@gmail.com>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-from ansible_collections.community.sap.plugins.modules.files import sapcar_extract
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
-from ansible_collections.community.sap.tests.unit.compat.mock import patch
-from ansible.module_utils import basic
-
-
-def get_bin_path(*args, **kwargs):
- """Function to return path of SAPCAR"""
- return "/tmp/sapcar"
-
-
-class Testsapcar_extract(ModuleTestCase):
- """Main class for testing sapcar_extract module."""
-
- def setUp(self):
- """Setup."""
- super(Testsapcar_extract, self).setUp()
- self.module = sapcar_extract
- self.mock_get_bin_path = patch.object(basic.AnsibleModule, 'get_bin_path', get_bin_path)
- self.mock_get_bin_path.start()
- self.addCleanup(self.mock_get_bin_path.stop) # ensure that the patching is 'undone'
-
- def tearDown(self):
- """Teardown."""
- super(Testsapcar_extract, self).tearDown()
-
- def test_without_required_parameters(self):
- """Failure must occurs when all parameters are missing."""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({})
- self.module.main()
-
- def test_sapcar_extract(self):
- """Check that result is changed."""
- set_module_args({
- 'path': "/tmp/HANA_CLIENT_REV2_00_053_00_LINUX_X86_64.SAR",
- 'dest': "/tmp/test2",
- 'binary_path': "/tmp/sapcar"
- })
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = 0, '', '' # successful execution, no output
- with self.assertRaises(AnsibleExitJson) as result:
- sapcar_extract.main()
- self.assertTrue(result.exception.args[0]['changed'])
- self.assertEqual(run_command.call_count, 1)
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_company.py b/ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_company.py
deleted file mode 100644
index 23490ccde..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_company.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-from ansible_collections.community.sap.tests.unit.compat.mock import patch, MagicMock
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
-
-sys.modules['pyrfc'] = MagicMock()
-sys.modules['pyrfc.Connection'] = MagicMock()
-
-from ansible_collections.community.sap.plugins.modules.identity import sap_company
-
-
-class TestSAPRfcModule(ModuleTestCase):
-
- def setUp(self):
- super(TestSAPRfcModule, self).setUp()
- self.module = sap_company
-
- def tearDown(self):
- super(TestSAPRfcModule, self).tearDown()
-
- def define_rfc_connect(self, mocker):
- return mocker.patch(self.module.call_rfc_method)
-
- def test_without_required_parameters(self):
- """Failure must occurs when all parameters are missing"""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({})
- self.module.main()
-
- def test_error_user_create(self):
- """test fail to create company"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "company_id": "Comp_ID",
- "name": "Test_comp",
- "name_2": "LTD",
- "country": "DE",
- "time_zone": "UTC",
- "city": "City",
- "post_code": "12345",
- "street": "test_street",
- "street_no": "1",
- "e_mail": "test@test.de",
- })
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': '', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'Something went wrong', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '199',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'E'}]}
-
- with self.assertRaises(AnsibleFailJson) as result:
- sap_company.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Something went wrong')
-
- def test_success(self):
- """test execute company create success"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "company_id": "Comp_ID",
- "name": "Test_comp",
- "name_2": "LTD",
- "country": "DE",
- "time_zone": "UTC",
- "city": "City",
- "post_code": "12345",
- "street": "test_street",
- "street_no": "1",
- "e_mail": "test@test.de",
- })
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': '', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'Company address COMP_ID created', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '102',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_company.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Company address COMP_ID created')
-
- def test_no_changes(self):
- """test execute company no changes"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "company_id": "Comp_ID",
- "name": "Test_comp",
- "name_2": "LTD",
- "country": "DE",
- "time_zone": "UTC",
- "city": "City",
- "post_code": "12345",
- "street": "test_street",
- "street_no": "1",
- "e_mail": "test@test.de",
- })
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': '', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'Company address COMP_ID changed', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '079',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_company.main()
- self.assertEqual(result.exception.args[0]['msg'], 'No changes where made.')
-
- def test_absent(self):
- """test execute company delete success"""
-
- set_module_args({
- "state": "absent",
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "company_id": "Comp_ID",
- })
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': '', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'Company address COMP_ID deleted', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '080',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_company.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Company address COMP_ID deleted')
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_user.py b/ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_user.py
deleted file mode 100644
index 982689f7e..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/identity/test_sap_user.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-from ansible_collections.community.sap.tests.unit.compat.mock import patch, MagicMock
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
-
-sys.modules['pyrfc'] = MagicMock()
-sys.modules['pyrfc.Connection'] = MagicMock()
-
-from ansible_collections.community.sap.plugins.modules.identity import sap_user
-
-
-class TestSAPRfcModule(ModuleTestCase):
-
- def setUp(self):
- super(TestSAPRfcModule, self).setUp()
- self.module = sap_user
-
- def tearDown(self):
- super(TestSAPRfcModule, self).tearDown()
-
- def define_rfc_connect(self, mocker):
- return mocker.patch(self.module.call_rfc_method)
-
- def test_without_required_parameters(self):
- """Failure must occurs when all parameters are missing"""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({})
- self.module.main()
-
- def test_error_user_create(self):
- """test fail to create user"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "username": "ADMIN",
- "firstname": "first_admin",
- "lastname": "last_admin",
- "email": "admin@test.de",
- "password": "Test123456",
- "useralias": "ADMIN",
- "company": "DEFAULT_COMPANY"
- })
-
- with patch.object(self.module, 'check_user') as check:
- check.return_value = False
-
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': 'BNAME', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'Something went wrong', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '199',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'E'}]}
-
- with self.assertRaises(AnsibleFailJson) as result:
- sap_user.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Something went wrong')
-
- def test_success(self):
- """test execute user create success"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "username": "ADMIN",
- "firstname": "first_admin",
- "lastname": "last_admin",
- "email": "admin@test.de",
- "password": "Test123456",
- "useralias": "ADMIN",
- "company": "DEFAULT_COMPANY"
- })
- with patch.object(self.module, 'check_user') as check:
- check.return_value = False
-
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': 'BNAME', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'User ADMIN created', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '102',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_user.main()
- self.assertEqual(result.exception.args[0]['msg'], 'User ADMIN created')
-
- def test_no_changes(self):
- """test execute user no changes"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "username": "ADMIN",
- "firstname": "first_admin",
- "lastname": "last_admin",
- "email": "admin@test.de",
- "password": "Test123456",
- "useralias": "ADMIN",
- "company": "DEFAULT_COMPANY"
- })
- with patch.object(self.module, 'check_user') as check:
- check.return_value = True
-
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': 'BNAME', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': '', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '029',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with patch.object(self.module, 'all') as DETAIL:
- DETAIL.return_value = True
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_user.main()
- self.assertEqual(result.exception.args[0]['msg'], 'No changes where made.')
-
- def test_absent(self):
- """test execute user delete success"""
-
- set_module_args({
- "state": "absent",
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "username": "ADMIN",
- })
- with patch.object(self.module, 'check_user') as check:
- check.return_value = True
-
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': 'BNAME', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'User ADMIN deleted', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '102',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_user.main()
- self.assertEqual(result.exception.args[0]['msg'], 'User ADMIN deleted')
-
- def test_lock(self):
- """test execute user lock success"""
-
- set_module_args({
- "state": "lock",
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "username": "ADMIN",
- })
- with patch.object(self.module, 'check_user') as check:
- check.return_value = True
-
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': 'BNAME', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'User ADMIN locked', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '206',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_user.main()
- self.assertEqual(result.exception.args[0]['msg'], 'User ADMIN locked')
-
- def test_unlock(self):
- """test execute user lock success"""
-
- set_module_args({
- "state": "lock",
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "username": "ADMIN",
- })
- with patch.object(self.module, 'check_user') as check:
- check.return_value = True
-
- with patch.object(self.module, 'call_rfc_method') as RAW:
- RAW.return_value = {'RETURN': [{'FIELD': 'BNAME', 'ID': '01', 'LOG_MSG_NO': '000000',
- 'LOG_NO': '', 'MESSAGE': 'User ADMIN unlocked', 'MESSAGE_V1': 'ADMIN',
- 'MESSAGE_V2': '', 'MESSAGE_V3': '', 'MESSAGE_V4': '', 'NUMBER': '210',
- 'PARAMETER': '', 'ROW': 0, 'SYSTEM': '', 'TYPE': 'S'}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_user.main()
- self.assertEqual(result.exception.args[0]['msg'], 'User ADMIN unlocked')
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/system/__init__.py b/ansible_collections/community/sap/tests/unit/plugins/modules/system/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/system/__init__.py
+++ /dev/null
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_snote.py b/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_snote.py
deleted file mode 100644
index 09ee81186..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_snote.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-from ansible_collections.community.sap.tests.unit.compat.mock import patch, MagicMock, Mock
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
-
-sys.modules['pyrfc'] = MagicMock()
-sys.modules['pyrfc.Connection'] = MagicMock()
-
-from ansible_collections.community.sap.plugins.modules.system import sap_snote
-
-
-class TestSAPRfcModule(ModuleTestCase):
-
- def setUp(self):
- super(TestSAPRfcModule, self).setUp()
- self.module = sap_snote
-
- def tearDown(self):
- super(TestSAPRfcModule, self).tearDown()
-
- def define_rfc_connect(self, mocker):
- return mocker.patch(self.module.call_rfc_method)
-
- def test_without_required_parameters(self):
- """Failure must occurs when all parameters are missing"""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({})
- self.module.main()
-
- def test_error_module_not_found(self):
- """tests fail module error"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "snote_path": "/user/sap/trans/temp/000123456.txt"
- })
- with self.assertRaises(AnsibleFailJson) as result:
- self.module.HAS_PYRFC_LIBRARY = False
- self.module.ANOTHER_LIBRARY_IMPORT_ERROR = 'Module not found'
- self.module.main()
- self.assertEqual(result.exception.args[0]['exception'], 'Module not found')
-
- def test_error_connection(self):
- """tests fail module error"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "snote_path": "/user/sap/trans/temp/000123456.txt"
- })
- with self.assertRaises(AnsibleFailJson) as result:
- self.module.Connection.side_effect = Mock(side_effect=Exception('Test'))
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Something went wrong connecting to the SAP system.')
-
- def test_error_wrong_path(self):
- """tests fail wrong path extension"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "snote_path": "/user/sap/trans/temp/000123456_00.tx"
- })
-
- with self.assertRaises(AnsibleFailJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'The path must include the extracted snote file and ends with txt.')
-
- def test_error_wrong_user(self):
- """tests fail wrong path extension"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "snote_path": "/user/sap/trans/temp/000123456_00.tx"
- })
-
- with self.assertRaises(AnsibleFailJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'User C(DDIC) or C(SAP*) not allowed for this operation.')
-
- def test_success_absent(self):
- """test absent execute snote"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "state": "absent",
- "snote_path": "/user/sap/trans/temp/000123456.txt"
- })
- with patch.object(self.module, 'call_rfc_method') as call:
- call.return_value = {'EV_RC': 0}
- with self.assertRaises(AnsibleExitJson) as result:
- with patch.object(self.module, 'check_implementation') as check:
- check.side_effect = [True, False]
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'SNOTE "000123456" deimplemented.')
-
- def test_success_absent_snot_only(self):
- """test absent execute snote"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "state": "absent",
- "snote": "000123456"
- })
- with patch.object(self.module, 'call_rfc_method') as call:
- call.return_value = {'EV_RC': 0}
- with self.assertRaises(AnsibleExitJson) as result:
- with patch.object(self.module, 'check_implementation') as check:
- check.side_effect = [True, False]
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'SNOTE "000123456" deimplemented.')
-
- def test_nothing_to_do(self):
- """test nothing to do"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "state": "present",
- "snote_path": "/user/sap/trans/temp/000123456.txt"
- })
- with patch.object(self.module, 'check_implementation') as check:
- check.return_value = True
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Nothing to do.')
-
- def test_success_present_with_copy(self):
- """test present execute snote"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "state": "present",
- "snote_path": "/user/sap/trans/temp/000123456.txt"
- })
- with patch.object(self.module, 'call_rfc_method') as call:
- call.return_value = {'EV_RC': 0}
- with self.assertRaises(AnsibleExitJson) as result:
- with patch.object(self.module, 'check_implementation') as check:
- check.side_effect = [False, True]
- with patch.object(self.module, 'call_rfc_method') as callrfc:
- callrfc.side_effect = [{'EV_RC': 0}, {'EV_RC': 0}, {'ET_MANUAL_ACTIVITIES': ''}]
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'SNOTE "000123456" implemented.')
-
- def test_success_present_implement_only(self):
- """test present implement snote"""
-
- set_module_args({
- "conn_username": "ADMIN",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "state": "present",
- "snote": "000123456"
- })
- with patch.object(self.module, 'call_rfc_method') as call:
- call.return_value = {'EV_RC': 0}
- with self.assertRaises(AnsibleExitJson) as result:
- with patch.object(self.module, 'check_implementation') as check:
- check.side_effect = [False, True]
- with patch.object(self.module, 'call_rfc_method') as callrfc:
- callrfc.side_effect = [{'EV_RC': 0}, {'ET_MANUAL_ACTIVITIES': ''}]
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'SNOTE "000123456" implemented.')
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_system_facts.py b/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_system_facts.py
deleted file mode 100644
index b63d90d35..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_system_facts.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber (@rainerleber) <rainerleber@gmail.com>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-
-import mock
-__metaclass__ = type
-
-from ansible_collections.community.sap.plugins.modules.system import sap_system_facts
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import AnsibleExitJson, ModuleTestCase
-from ansible_collections.community.sap.tests.unit.compat.mock import patch, MagicMock
-from ansible.module_utils import basic
-
-
-def get_bin_path(*args, **kwargs):
- """Function to return path of sapcontrol"""
- return "/usr/sap/hostctrl/exe/sapcontrol"
-
-
-class Testsap_system_facts(ModuleTestCase):
- """Main class for testing sap_system_facts module."""
-
- def setUp(self):
- """Setup."""
- super(Testsap_system_facts, self).setUp()
- self.module = sap_system_facts
- self.mock_get_bin_path = patch.object(basic.AnsibleModule, 'get_bin_path', get_bin_path)
- self.mock_get_bin_path.start()
- self.addCleanup(self.mock_get_bin_path.stop)
-
- def tearDown(self):
- """Teardown."""
- super(Testsap_system_facts, self).tearDown()
-
- def test_no_systems_available(self):
- """No SAP Systems"""
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['ansible_facts'], {})
-
- def test_sap_system_facts_all(self):
- """Check that result is changed when all is one system."""
- with patch.object(self.module, 'get_all_hana_sid') as get_all_hana_sid:
- get_all_hana_sid.return_value = ['HDB']
- with patch.object(self.module, 'get_hana_nr') as get_hana_nr:
- get_hana_nr.return_value = [{"InstanceType": "HANA", "NR": "01", "SID": "HDB", "TYPE": "HDB"}]
- with patch.object(self.module, 'get_all_nw_sid') as get_all_nw_sid:
- get_all_nw_sid.return_value = ['ABC']
- with patch.object(self.module, 'get_nw_nr') as get_nw_nr:
- get_nw_nr.return_value = [{"InstanceType": "NW", "NR": "00", "SID": "ABC", "TYPE": "ASCS"},
- {"InstanceType": "NW", "NR": "01", "SID": "ABC", "TYPE": "PAS"}]
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['ansible_facts'], {'sap': [{"InstanceType": "HANA", "NR": "01", "SID": "HDB", "TYPE": "HDB"},
- {"InstanceType": "NW", "NR": "00", "SID": "ABC", "TYPE": "ASCS"},
- {"InstanceType": "NW", "NR": "01", "SID": "ABC", "TYPE": "PAS"}]})
-
- def test_sap_system_facts_command_hana(self):
- """Check that result for HANA is correct."""
- with patch.object(self.module, 'get_all_hana_sid') as mock_all_hana_sid:
- mock_all_hana_sid.return_value = ['HDB']
- with patch.object(self.module.os, 'listdir') as mock_listdir:
- mock_listdir.return_value = ['HDB01']
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = [0, '', '']
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['ansible_facts'], {'sap': [{"InstanceType": "HANA", "NR": "01", "SID": "HDB", "TYPE": "HDB"}]})
-
- def test_sap_system_facts_pas_nw(self):
- """Check that result for NW is correct."""
- with patch.object(self.module, 'get_all_nw_sid') as mock_all_nw_sid:
- mock_all_nw_sid.return_value = ['ABC']
- with patch.object(self.module.os, 'listdir') as mock_listdir:
- mock_listdir.return_value = ['D00']
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = [0, 'SAP\nINSTANCE_NAME, Attribute, D00\nSAP', '']
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['ansible_facts'], {'sap': [{'InstanceType': 'NW', 'NR': '00', 'SID': 'ABC', 'TYPE': 'PAS'}]})
-
- def test_sap_system_facts_future_nw(self):
- """Check that future apps for NW are correct handled."""
- with patch.object(self.module, 'get_all_nw_sid') as mock_all_nw_sid:
- mock_all_nw_sid.return_value = ['ABC']
- with patch.object(self.module.os, 'listdir') as mock_listdir:
- mock_listdir.return_value = ['XY00']
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = [0, 'SAP\nINSTANCE_NAME, Attribute, XY00\nSAP', '']
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['ansible_facts'], {'sap': [{'InstanceType': 'NW', 'NR': '00', 'SID': 'ABC', 'TYPE': 'XXX'}]})
-
- def test_sap_system_facts_wd_nw(self):
- """Check that WD for NW is correct handled."""
- with patch.object(self.module, 'get_all_nw_sid') as mock_all_nw_sid:
- mock_all_nw_sid.return_value = ['ABC']
- with patch.object(self.module.os, 'listdir') as mock_listdir:
- mock_listdir.return_value = ['WD80']
- with patch.object(basic.AnsibleModule, 'run_command') as run_command:
- run_command.return_value = [0, 'SAP\nINSTANCE_NAME, Attribute, WD80\nSAP', '']
- with self.assertRaises(AnsibleExitJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['ansible_facts'], {'sap': [{'InstanceType': 'NW', 'NR': '80', 'SID': 'ABC', 'TYPE': 'WebDisp'}]})
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_task_list_execute.py b/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_task_list_execute.py
deleted file mode 100644
index 7362c13d8..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/system/test_sap_task_list_execute.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import sys
-from ansible_collections.community.sap.tests.unit.compat.mock import patch, MagicMock
-from ansible_collections.community.sap.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args
-
-sys.modules['pyrfc'] = MagicMock()
-sys.modules['pyrfc.Connection'] = MagicMock()
-sys.modules['xmltodict'] = MagicMock()
-sys.modules['xmltodict.parse'] = MagicMock()
-
-from ansible_collections.community.sap.plugins.modules.system import sap_task_list_execute
-
-
-class TestSAPRfcModule(ModuleTestCase):
-
- def setUp(self):
- super(TestSAPRfcModule, self).setUp()
- self.module = sap_task_list_execute
-
- def tearDown(self):
- super(TestSAPRfcModule, self).tearDown()
-
- def define_rfc_connect(self, mocker):
- return mocker.patch(self.module.call_rfc_method)
-
- def test_without_required_parameters(self):
- """Failure must occurs when all parameters are missing"""
- with self.assertRaises(AnsibleFailJson):
- set_module_args({})
- self.module.main()
-
- def test_error_no_task_list(self):
- """tests fail to exec task list"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "task_to_execute": "SAP_BASIS_SSL_CHECK"
- })
-
- with patch.object(self.module, 'Connection') as conn:
- conn.return_value = ''
- with self.assertRaises(AnsibleFailJson) as result:
- self.module.main()
- self.assertEqual(result.exception.args[0]['msg'], 'The task list does not exist.')
-
- def test_success(self):
- """test execute task list success"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "task_to_execute": "SAP_BASIS_SSL_CHECK"
- })
- with patch.object(self.module, 'xml_to_dict') as XML:
- XML.return_value = {'item': [{'TASK': {'CHECK_STATUS_DESCR': 'Check successfully',
- 'STATUS_DESCR': 'Executed successfully', 'TASKNAME': 'CL_STCT_CHECK_SEC_CRYPTO',
- 'LNR': '1', 'DESCRIPTION': 'Check SAP Cryptographic Library', 'DOCU_EXIST': 'X',
- 'LOG_EXIST': 'X', 'ACTION_SKIP': None, 'ACTION_UNSKIP': None, 'ACTION_CONFIRM': None,
- 'ACTION_MAINTAIN': None}}]}
-
- with self.assertRaises(AnsibleExitJson) as result:
- sap_task_list_execute.main()
- self.assertEqual(result.exception.args[0]['out'], {'item': [{'TASK': {'CHECK_STATUS_DESCR': 'Check successfully',
- 'STATUS_DESCR': 'Executed successfully', 'TASKNAME': 'CL_STCT_CHECK_SEC_CRYPTO',
- 'LNR': '1', 'DESCRIPTION': 'Check SAP Cryptographic Library', 'DOCU_EXIST': 'X',
- 'LOG_EXIST': 'X', 'ACTION_SKIP': None, 'ACTION_UNSKIP': None,
- 'ACTION_CONFIRM': None, 'ACTION_MAINTAIN': None}}]})
-
- def test_success_no_log(self):
- """test execute task list success without logs"""
-
- set_module_args({
- "conn_username": "DDIC",
- "conn_password": "Test1234",
- "host": "10.1.8.9",
- "task_to_execute": "SAP_BASIS_SSL_CHECK"
- })
- with patch.object(self.module, 'xml_to_dict') as XML:
- XML.return_value = "No logs available."
- with self.assertRaises(AnsibleExitJson) as result:
- sap_task_list_execute.main()
- self.assertEqual(result.exception.args[0]['out'], 'No logs available.')
diff --git a/ansible_collections/community/sap/tests/unit/plugins/modules/utils.py b/ansible_collections/community/sap/tests/unit/plugins/modules/utils.py
deleted file mode 100644
index 8f20b4575..000000000
--- a/ansible_collections/community/sap/tests/unit/plugins/modules/utils.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import json
-
-from ansible_collections.community.sap.tests.unit.compat import unittest
-from ansible_collections.community.sap.tests.unit.compat.mock import patch
-from ansible.module_utils import basic
-from ansible.module_utils.common.text.converters import to_bytes
-
-
-def set_module_args(args):
- if '_ansible_remote_tmp' not in args:
- args['_ansible_remote_tmp'] = '/tmp'
- if '_ansible_keep_remote_files' not in args:
- args['_ansible_keep_remote_files'] = False
-
- args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
- basic._ANSIBLE_ARGS = to_bytes(args)
-
-
-class AnsibleExitJson(Exception):
- pass
-
-
-class AnsibleFailJson(Exception):
- pass
-
-
-def exit_json(*args, **kwargs):
- if 'changed' not in kwargs:
- kwargs['changed'] = False
- raise AnsibleExitJson(kwargs)
-
-
-def fail_json(*args, **kwargs):
- kwargs['failed'] = True
- raise AnsibleFailJson(kwargs)
-
-
-class ModuleTestCase(unittest.TestCase):
-
- def setUp(self):
- self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
- self.mock_module.start()
- self.mock_sleep = patch('time.sleep')
- self.mock_sleep.start()
- set_module_args({})
- self.addCleanup(self.mock_module.stop)
- self.addCleanup(self.mock_sleep.stop)
diff --git a/ansible_collections/community/sap/tests/unit/requirements.txt b/ansible_collections/community/sap/tests/unit/requirements.txt
deleted file mode 100644
index 49654b8b5..000000000
--- a/ansible_collections/community/sap/tests/unit/requirements.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-unittest2 ; python_version < '2.7'
-importlib ; python_version < '2.7'
-
-# requirement sap_task_list_execute
-lxml < 4.3.0 ; python_version < '2.7' # lxml 4.3.0 and later require python 2.7 or later
-lxml ; python_version >= '2.7'
-argparse ; python_version >= '2.6' \ No newline at end of file
diff --git a/ansible_collections/community/vmware/.github/workflows/ansible-test.yml b/ansible_collections/community/vmware/.github/workflows/ansible-test.yml
index 6a5866e13..79531def6 100644
--- a/ansible_collections/community/vmware/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/vmware/.github/workflows/ansible-test.yml
@@ -91,7 +91,8 @@ jobs:
testing-type: sanity
# OPTIONAL If your sanity tests require code
# from other collections, install them like this
- # test-deps: >-
+ test-deps: >-
+ vmware.vmware
# ansible.netcommon
# ansible.utils
# OPTIONAL If set to true, will test only against changed files,
@@ -151,6 +152,7 @@ jobs:
test-deps: >-
ansible.netcommon
ansible.utils
+ vmware.vmware
# OPTIONAL If set to true, will test only against changed files,
# which should improve CI performance. See limitations on
# https://github.com/ansible-community/ansible-test-gh-action#pull-request-change-detection
diff --git a/ansible_collections/community/vmware/CHANGELOG.rst b/ansible_collections/community/vmware/CHANGELOG.rst
index 4162c1885..a65557bc0 100644
--- a/ansible_collections/community/vmware/CHANGELOG.rst
+++ b/ansible_collections/community/vmware/CHANGELOG.rst
@@ -6,6 +6,21 @@ community.vmware Release Notes
This changelog describes changes after version 3.9.0.
+v4.4.0
+======
+
+Minor Changes
+-------------
+
+- vmware_dvs_portgroup - Make `state` default to `present` instead of having it as a required parameter (https://github.com/ansible-collections/community.vmware/pull/2055).
+
+Bugfixes
+--------
+
+- Clarify pyVmomi requirement (https://github.com/ansible-collections/community.vmware/pull/2071).
+- vmware_cluster_dpm - Handle case where DPM config has not been initialized yet and is None (https://github.com/ansible-collections/community.vmware/pull/2057).
+- vmware_dvs_portgroup - Fix erroneously reporting a change when `port_binding` is static and `num_ports` not specified (https://github.com/ansible-collections/community.vmware/pull/2053).
+
v4.3.0
======
diff --git a/ansible_collections/community/vmware/FILES.json b/ansible_collections/community/vmware/FILES.json
index 68fe7037b..ca7811202 100644
--- a/ansible_collections/community/vmware/FILES.json
+++ b/ansible_collections/community/vmware/FILES.json
@@ -25,7 +25,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "75ced302218d85f3484c215700b3626db0288f380c6d549f666f13ddd05585e8",
+ "chksum_sha256": "03d0884033021aee8129dec83b8f3443844743e9d6a1a3f81f8261b61be37a39",
"format": 1
},
{
@@ -88,7 +88,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fa92ffc48b8d5e744ed8748724d0623b9bdc81a4e57798fe99098640234cc5bc",
+ "chksum_sha256": "3a15dd1e41ea5e7c5183d62584d11ef00cc90c34583f1dcf1a3da094180fdb44",
"format": 1
},
{
@@ -277,7 +277,7 @@
"name": "plugins/module_utils/vmware.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "902d67e645b235e10d27e179666442625e6ea9df4a4e4589ee6ba1427376b652",
+ "chksum_sha256": "8379242e20efae1092d67d62665bfc7fd84774d75668439a788e87b374cd8938",
"format": 1
},
{
@@ -410,7 +410,7 @@
"name": "plugins/modules/vmware_cluster_dpm.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "823d0eba4ad0a749924bc16b0ac8540211a54add654b4ca445c8ad246bddf250",
+ "chksum_sha256": "017a074c3d73a814baf6c06b7de579942877ab137a4126e4c967c3290bb4f994",
"format": 1
},
{
@@ -438,7 +438,7 @@
"name": "plugins/modules/vmware_cluster_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2f1c85c2da228ca18fd165303c4bf6e3820785433f8e4c4b29da5532f097ae55",
+ "chksum_sha256": "ed5923cdc15305e8412b05f37b6d2b0103ed9d41befbbeeb8a8598b28b0afa2a",
"format": 1
},
{
@@ -508,7 +508,7 @@
"name": "plugins/modules/vmware_datacenter_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "206991b567645c273700b018f4453bb777f3a182f73844a7ed658c38c9d41311",
+ "chksum_sha256": "12490a660df9d43092b1e3a6075f399a5895799d7d4e7909a103a27f5605e755",
"format": 1
},
{
@@ -536,7 +536,7 @@
"name": "plugins/modules/vmware_datastore_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "324deb8bd961b7c4834f581d1979ab0aba69e7a7e82879f060a4b37ec2a4edda",
+ "chksum_sha256": "39a6da2a806ee94b1ad41676287541052a9e30f5e0b808de9ae9ed5da78185e3",
"format": 1
},
{
@@ -592,7 +592,7 @@
"name": "plugins/modules/vmware_dvs_portgroup.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "62e5113c13f94cb054db298f8e7ba9ea775fab8f7b148312f2837ffcd68c4eba",
+ "chksum_sha256": "f72f4e7664b47113e421c73620d2f2950d87f1482ab488af450b879acae509cb",
"format": 1
},
{
@@ -620,7 +620,7 @@
"name": "plugins/modules/vmware_dvswitch_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "60c4835bda0af924c470d6fa719849a1189e8877b9580e207927b82095a15b25",
+ "chksum_sha256": "155fbe06751bd991140d913909069ac49373e2eab87081014b31ef0d8d38c23f",
"format": 1
},
{
@@ -774,7 +774,7 @@
"name": "plugins/modules/vmware_guest_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "da25048b3ce8b821bb13c1c12f71546303867535cbcc8cf0957fd0d82a70d22d",
+ "chksum_sha256": "b76f0876359e7bb7f0f56956c1d24aaece045f725888ff85553229d14eb26c4c",
"format": 1
},
{
@@ -998,7 +998,7 @@
"name": "plugins/modules/vmware_host_facts.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0be83e8553f01c0feee73f3256d60828c7a599bb99828afa64ed359c30ba1bb8",
+ "chksum_sha256": "5ed17567e7cd480c23e384c24937a5fdb53350db9bf521a0885a5a99c0acfc98",
"format": 1
},
{
@@ -1376,7 +1376,7 @@
"name": "plugins/modules/vmware_vcenter_settings_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "00e24ba53faf96b10b84298e0a97b2a1915b0bb9d63e62ff0ff3ed17797bb271",
+ "chksum_sha256": "006aab37a213f3bc88fdbd3b1bfbcaf95cceafd466f7a539cf3ffb9364951780",
"format": 1
},
{
@@ -1481,7 +1481,7 @@
"name": "plugins/modules/vmware_vsan_health_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f1f1cd15f00fc30518dff21437bc09178e8e7d78746a08686f4879992f19d2a5",
+ "chksum_sha256": "46458bb24562c4677938db0efe562de66cb8d9b54c2d360bb00717fec4c82792",
"format": 1
},
{
@@ -2531,7 +2531,7 @@
"name": "tests/integration/targets/vmware_content_library_manager/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f8746ce261098f3b9959c236b65b5f905c80b90dddfb4ed53baaf5bf21cb51a1",
+ "chksum_sha256": "8290f7eeff6ef6efbe373acc9c4526c7a7fcb110ccdabef07a7143e3e147cf16",
"format": 1
},
{
@@ -2951,7 +2951,7 @@
"name": "tests/integration/targets/vmware_dvs_portgroup/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "aa654a9325a4ed0af466f17af77dbf9623cf65298d16472f1a01436ca3fa1af8",
+ "chksum_sha256": "884a4101577841f2fd99c3064e339630f10db088d284eb50b7214ee25cda5f2c",
"format": 1
},
{
@@ -7025,7 +7025,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6b2e0c075305c8d5f1b662a7533014e70ec9d1733eb79d5f70f1e024ecc06d99",
+ "chksum_sha256": "e2bff3adb02c855ffa4cc5c55d911169d560a30bd0825d44eac85c6a058c72dc",
"format": 1
},
{
@@ -7053,7 +7053,7 @@
"name": "requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0925a1e635ac14a5c481a16d2e3e59ccc5b7411579ddb3a27199ae069fe7deca",
+ "chksum_sha256": "9e5d71254beec2adb7e2df9075aedca54b6e6dc7d13b65dfb3a38a5d81165594",
"format": 1
},
{
diff --git a/ansible_collections/community/vmware/MANIFEST.json b/ansible_collections/community/vmware/MANIFEST.json
index d1bc8edfe..1b9ad314f 100644
--- a/ansible_collections/community/vmware/MANIFEST.json
+++ b/ansible_collections/community/vmware/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "vmware",
- "version": "4.3.0",
+ "version": "4.4.0",
"authors": [
"Ansible (https://github.com/ansible)"
],
@@ -28,7 +28,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "af79d3641999ba756f51b0b3c0562e0ebba66c8c764a0aff81496d5906a7398a",
+ "chksum_sha256": "4ee26340abe1773c12bad33eb99b9c3d9584f421dbeaeef0e19fd05add0b0f26",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/vmware/changelogs/changelog.yaml b/ansible_collections/community/vmware/changelogs/changelog.yaml
index 2b250b5fd..b0d9afb0a 100644
--- a/ansible_collections/community/vmware/changelogs/changelog.yaml
+++ b/ansible_collections/community/vmware/changelogs/changelog.yaml
@@ -130,3 +130,20 @@ releases:
- 2036-missing_error_msg_in_vmware_guest.yml
- 2044-error_in_adding_disk_to_vm_in_vmware_guest.yml
release_date: '2024-04-20'
+ 4.4.0:
+ changes:
+ bugfixes:
+ - Clarify pyVmomi requirement (https://github.com/ansible-collections/community.vmware/pull/2071).
+ - vmware_cluster_dpm - Handle case where DPM config has not been initialized
+ yet and is None (https://github.com/ansible-collections/community.vmware/pull/2057).
+ - vmware_dvs_portgroup - Fix erroneously reporting a change when `port_binding`
+ is static and `num_ports` not specified (https://github.com/ansible-collections/community.vmware/pull/2053).
+ minor_changes:
+ - vmware_dvs_portgroup - Make `state` default to `present` instead of having
+ it as a required parameter (https://github.com/ansible-collections/community.vmware/pull/2055).
+ fragments:
+ - 2053-vmware_dvs_portgroup.yml
+ - 2055-vmware_dvs_portgroup-status_default.yml
+ - 2057-vmware_cluster_dpm-handle-dpm-none-config.yml
+ - 2071-clarify-pyvmomi-requirement.yml
+ release_date: '2024-05-19'
diff --git a/ansible_collections/community/vmware/plugins/module_utils/vmware.py b/ansible_collections/community/vmware/plugins/module_utils/vmware.py
index 12bdf5107..c2c9a4f23 100644
--- a/ansible_collections/community/vmware/plugins/module_utils/vmware.py
+++ b/ansible_collections/community/vmware/plugins/module_utils/vmware.py
@@ -39,11 +39,9 @@ try:
from pyVim import connect
from pyVmomi import vim, vmodl, VmomiSupport
HAS_PYVMOMI = True
- HAS_PYVMOMIJSON = hasattr(VmomiSupport, 'VmomiJSONEncoder')
except ImportError:
PYVMOMI_IMP_ERR = traceback.format_exc()
HAS_PYVMOMI = False
- HAS_PYVMOMIJSON = False
from ansible.module_utils._text import to_text, to_native
from ansible.module_utils.six import integer_types, iteritems, string_types, raise_from
@@ -1972,9 +1970,6 @@ class PyVmomi(object):
provided then all properties are deeply converted. The resulting
JSON is sorted to improve human readability.
- Requires upstream support from pyVmomi > 6.7.1
- (https://github.com/vmware/pyvmomi/pull/732)
-
Args:
- obj (object): vim object
- properties (list, optional): list of properties following
@@ -1985,9 +1980,6 @@ class PyVmomi(object):
Return:
dict
"""
- if not HAS_PYVMOMIJSON:
- self.module.fail_json(msg='The installed version of pyvmomi lacks JSON output support; need pyvmomi>6.7.1')
-
result = dict()
if properties:
for prop in properties:
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py
index 1215f52c3..5a63baea8 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py
@@ -117,7 +117,7 @@ class VMwareCluster(PyVmomi):
change_message = None
changes = False
- if dpm_config.enabled != self.enable_dpm:
+ if dpm_config is None or dpm_config.enabled != self.enable_dpm:
change_message = 'DPM enabled status changes'
changes = True
return changes, change_message
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py
index 24ca77bc8..273f7a351 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py
@@ -42,7 +42,7 @@ options:
description:
- Specify the output schema desired.
- The V(summary) output schema is the legacy output from the module.
- - The V(vsphere) output schema is the vSphere API class definition which requires pyvmomi>6.7.1.
+ - The V(vsphere) output schema is the vSphere API class definition.
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_datacenter_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_datacenter_info.py
index 3b8dfc878..2d5ef8729 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_datacenter_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_datacenter_info.py
@@ -29,7 +29,7 @@ options:
description:
- Specify the output schema desired.
- The V(summary) output schema is the legacy output from the module.
- - The V(vsphere) output schema is the vSphere API class definition which requires pyvmomi>6.7.1.
+ - The V(vsphere) output schema is the vSphere API class definition.
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py
index 4c3fdc1e1..618e929c9 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py
@@ -58,7 +58,6 @@ options:
- Specify the output schema desired.
- The 'summary' output schema is the legacy output from the module
- The 'vsphere' output schema is the vSphere API class definition
- which requires pyvmomi>6.7.1
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_dvs_portgroup.py b/ansible_collections/community/vmware/plugins/modules/vmware_dvs_portgroup.py
index a7b09d0c7..fbe790be6 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_dvs_portgroup.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_dvs_portgroup.py
@@ -64,11 +64,12 @@ options:
state:
description:
- Determines if the portgroup should be present or not.
- required: true
+ required: false
type: str
choices:
- 'present'
- 'absent'
+ default: 'present'
vlan_trunk:
description:
- Indicates whether this is a VLAN trunk or not.
@@ -734,7 +735,7 @@ class VMwareDvsPortgroup(PyVmomi):
# Check config
if self.module.params['port_allocation'] != 'elastic' and self.module.params['port_binding'] != 'ephemeral':
- if self.dvs_portgroup.config.numPorts != self.module.params['num_ports']:
+ if self.module.params['num_ports'] is not None and self.dvs_portgroup.config.numPorts != self.module.params['num_ports']:
return 'update'
# Default port config
@@ -893,7 +894,7 @@ def main():
num_ports=dict(type='int'),
port_binding=dict(required=True, type='str', choices=['static', 'ephemeral']),
port_allocation=dict(type='str', choices=['fixed', 'elastic']),
- state=dict(required=True, choices=['present', 'absent'], type='str'),
+ state=dict(type='str', choices=['present', 'absent'], default='present'),
vlan_trunk=dict(type='bool', default=False),
vlan_private=dict(type='bool', default=False),
network_policy=dict(
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch_info.py
index b4fa9c7c3..7e3a3b082 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch_info.py
@@ -43,7 +43,6 @@ options:
- Specify the output schema desired.
- The 'summary' output schema is the legacy output from the module
- The 'vsphere' output schema is the vSphere API class definition
- which requires pyvmomi>6.7.1
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_info.py
index 470f76642..4f3678e37 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_info.py
@@ -87,7 +87,6 @@ options:
- Specify the output schema desired.
- The V(summary) output schema is the legacy output from the module
- The V(vsphere) output schema is the vSphere API class definition
- which requires pyvmomi>6.7.1
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_host_facts.py b/ansible_collections/community/vmware/plugins/modules/vmware_host_facts.py
index a4738b117..1bfd64012 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_host_facts.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_host_facts.py
@@ -47,7 +47,6 @@ options:
- Specify the output schema desired.
- The V(summary) output schema is the legacy output from the module
- The V(vsphere) output schema is the vSphere API class definition
- which requires pyvmomi>6.7.1
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_vcenter_settings_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_vcenter_settings_info.py
index 3936cc770..183a58244 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_vcenter_settings_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_vcenter_settings_info.py
@@ -22,7 +22,7 @@ options:
description:
- Specify the output schema desired.
- The 'summary' output schema is the legacy output from the module.
- - The 'vsphere' output schema is the vSphere API class definition which requires pyvmomi>6.7.1.
+ - The 'vsphere' output schema is the vSphere API class definition.
choices: ['summary', 'vsphere']
default: 'summary'
type: str
diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_vsan_health_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_vsan_health_info.py
index 565b2b859..7a6b68735 100644
--- a/ansible_collections/community/vmware/plugins/modules/vmware_vsan_health_info.py
+++ b/ansible_collections/community/vmware/plugins/modules/vmware_vsan_health_info.py
@@ -108,11 +108,9 @@ import traceback
try:
from pyVmomi import vmodl, VmomiSupport
HAS_PYVMOMI = True
- HAS_PYVMOMIJSON = hasattr(VmomiSupport, 'VmomiJSONEncoder')
except ImportError:
PYVMOMI_IMP_ERR = traceback.format_exc()
HAS_PYVMOMI = False
- HAS_PYVMOMIJSON = False
VSANPYTHONSDK_IMP_ERR = None
try:
@@ -186,9 +184,6 @@ def main():
if not HAS_VSANPYTHONSDK:
module.fail_json(msg=missing_required_lib('vSAN Management SDK for Python'), exception=VSANPYTHONSDK_IMP_ERR)
- if not HAS_PYVMOMIJSON:
- module.fail_json(msg='The installed version of pyvmomi lacks JSON output support; need pyvmomi>6.7.1')
-
vsan_info_manager = VSANInfoManager(module)
vsan_info_manager.gather_info()
diff --git a/ansible_collections/community/vmware/requirements.txt b/ansible_collections/community/vmware/requirements.txt
index cca52e3da..c2bbb7911 100644
--- a/ansible_collections/community/vmware/requirements.txt
+++ b/ansible_collections/community/vmware/requirements.txt
@@ -1,2 +1,2 @@
-pyVmomi>=6.7
+pyVmomi>=6.7.1
git+https://github.com/vmware/vsphere-automation-sdk-python.git ; python_version >= '2.7' # Python 2.6 is not supported
diff --git a/ansible_collections/community/vmware/tests/integration/targets/vmware_content_library_manager/tasks/main.yml b/ansible_collections/community/vmware/tests/integration/targets/vmware_content_library_manager/tasks/main.yml
index c12b57b57..86b00dc85 100644
--- a/ansible_collections/community/vmware/tests/integration/targets/vmware_content_library_manager/tasks/main.yml
+++ b/ansible_collections/community/vmware/tests/integration/targets/vmware_content_library_manager/tasks/main.yml
@@ -100,7 +100,7 @@
state: absent
- name: get finger print
- shell: echo | openssl s_client -connect wp-content.vmware.com:443 |& openssl x509 -fingerprint -noout
+ shell: echo | openssl s_client -connect wp-content.broadcom.com:443 |& openssl x509 -fingerprint -noout
register: _finger_print
- debug: var=_finger_print
@@ -113,7 +113,7 @@
validate_certs: false
library_name: Sample_Subscribed_Library
library_description: Sample Description
- subscription_url: "https://wp-content.vmware.com/v2/latest/lib.json"
+ subscription_url: "https://wp-content.broadcom.com/v2/latest/lib.json"
update_on_demand: true
library_type: subscribed
ssl_thumbprint: '{{ _finger_print.stdout.split("=")[1] }}'
@@ -144,7 +144,7 @@
validate_certs: false
library_name: Sample_Subscribed_Library
library_description: Update Sample Description
- subscription_url: https://download3.vmware.com/software/vmw-tools/lib.json
+ subscription_url: "https://wp-content.broadcom.com/v2/latest/lib.json"
update_on_demand: true
library_type: subscribed
ssl_thumbprint: '{{ _finger_print.stdout.split("=")[1] }}'
diff --git a/ansible_collections/community/vmware/tests/integration/targets/vmware_dvs_portgroup/tasks/main.yml b/ansible_collections/community/vmware/tests/integration/targets/vmware_dvs_portgroup/tasks/main.yml
index 8d45b2e28..2feff488c 100644
--- a/ansible_collections/community/vmware/tests/integration/targets/vmware_dvs_portgroup/tasks/main.yml
+++ b/ansible_collections/community/vmware/tests/integration/targets/vmware_dvs_portgroup/tasks/main.yml
@@ -805,3 +805,85 @@
- assert:
that:
- delete_test_dvs_port_group_issues_637_idempotency_check_result.changed is sameas true
+
+- name: Create portgroup for num_ports check
+ community.vmware.vmware_dvs_portgroup:
+ hostname: "{{ vcenter_hostname }}"
+ username: "{{ vcenter_username }}"
+ password: "{{ vcenter_password }}"
+ validate_certs: false
+ portgroup_name: "portgroup2053"
+ switch_name: "{{ dvswitch1 }}"
+ vlan_id: 2053
+ port_binding: static
+ register: create_portgroup2053_result
+
+- assert:
+ that:
+ - create_portgroup2053_result is changed
+
+- name: Check idempotency for unspecified num_ports
+ community.vmware.vmware_dvs_portgroup:
+ hostname: "{{ vcenter_hostname }}"
+ username: "{{ vcenter_username }}"
+ password: "{{ vcenter_password }}"
+ validate_certs: false
+ portgroup_name: "portgroup2053"
+ switch_name: "{{ dvswitch1 }}"
+ vlan_id: 2053
+ port_binding: static
+ register: portgroup2053_check1_result
+
+- assert:
+ that:
+ - portgroup2053_check1_result is not changed
+
+- name: Update for num_ports
+ community.vmware.vmware_dvs_portgroup:
+ hostname: "{{ vcenter_hostname }}"
+ username: "{{ vcenter_username }}"
+ password: "{{ vcenter_password }}"
+ validate_certs: false
+ portgroup_name: "portgroup2053"
+ switch_name: "{{ dvswitch1 }}"
+ vlan_id: 2053
+ port_binding: static
+ num_ports: 8
+ register: portgroup2053_check2_result
+
+- assert:
+ that:
+ - portgroup2053_check2_result is changed
+
+- name: Check idempotency for unspecified num_ports
+ community.vmware.vmware_dvs_portgroup:
+ hostname: "{{ vcenter_hostname }}"
+ username: "{{ vcenter_username }}"
+ password: "{{ vcenter_password }}"
+ validate_certs: false
+ portgroup_name: "portgroup2053"
+ switch_name: "{{ dvswitch1 }}"
+ vlan_id: 2053
+ port_binding: static
+ register: portgroup2053_check3_result
+
+- assert:
+ that:
+ - portgroup2053_check3_result is not changed
+
+- name: Delete num_ports check portgroup
+ community.vmware.vmware_dvs_portgroup:
+ hostname: "{{ vcenter_hostname }}"
+ username: "{{ vcenter_username }}"
+ password: "{{ vcenter_password }}"
+ validate_certs: false
+ portgroup_name: "portgroup2053"
+ switch_name: "{{ dvswitch1 }}"
+ vlan_id: 2053
+ port_binding: static
+ state: absent
+ register: delete_portgroup2053_result
+
+- assert:
+ that:
+ - delete_portgroup2053_result is changed
diff --git a/ansible_collections/community/zabbix/.github/workflows/agent.yml b/ansible_collections/community/zabbix/.github/workflows/agent.yml
index ca04f5843..55b7e1b72 100644
--- a/ansible_collections/community/zabbix/.github/workflows/agent.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/agent.yml
@@ -29,9 +29,9 @@ jobs:
- debian11
- debian10
version:
- - v64
- - v62
- - v60
+ - v64
+ - v62
+ - v60
scenario_name:
- default
- autopsk
@@ -46,7 +46,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up Python 3.9
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: 3.9
@@ -60,11 +60,19 @@ jobs:
- name: Build the collection
run: |
+ # Pin versions to speed up CI
+ sed -i 's/ansible\.windows:\s*"\*"/ansible.windows: "2.3.0"/' galaxy.yml
+ sed -i 's/ansible\.netcommon:\s*"\*"/ansible.netcommon: "6.1.1"/' galaxy.yml
+ sed -i 's/ansible\.posix:\s*"\*"/ansible.posix: "1.5.4"/' galaxy.yml
+ sed -i 's/community\.general:\s*"\*"/community.general: "8.6.0"/' galaxy.yml
+ sed -i 's/community\.mysql:\s*"\*"/community.mysql: "3.9.0"/' galaxy.yml
+ sed -i 's/community\.postgresql:\s*"\*"/community.postgresql: "3.4.0"/' galaxy.yml
+
collection_file=$( basename $(ansible-galaxy collection build -f | awk -F" " '{print $NF}'))
echo "COLLECTION_FILE=$collection_file" >> $GITHUB_ENV
- name: Install the collection
- run: ansible-galaxy collection install $COLLECTION_FILE
+ run: ansible-galaxy collection install -vvvv $COLLECTION_FILE
- name: Run role tests
working-directory: molecule/zabbix_agent_tests
@@ -73,4 +81,4 @@ jobs:
MY_MOLECULE_IMAGE=${{ matrix.container }}
MY_MOLECULE_VERSION=${{ matrix.version }}
MY_MOLECULE_DOCKER_COMMAND=${{ matrix.command }}
- molecule -c common/molecule.yml test -s ${{ matrix.scenario_name }} \ No newline at end of file
+ molecule -c common/molecule.yml test -s ${{ matrix.scenario_name }}
diff --git a/ansible_collections/community/zabbix/.github/workflows/javagateway.yml b/ansible_collections/community/zabbix/.github/workflows/javagateway.yml
index bd6885ef7..22bc5ede1 100644
--- a/ansible_collections/community/zabbix/.github/workflows/javagateway.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/javagateway.yml
@@ -47,7 +47,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up Python 3.9
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: 3.9
@@ -58,11 +58,19 @@ jobs:
- name: Build the collection
run: |
+ # Pin versions to speed up CI
+ sed -i 's/ansible\.windows:\s*"\*"/ansible.windows: "2.3.0"/' galaxy.yml
+ sed -i 's/ansible\.netcommon:\s*"\*"/ansible.netcommon: "6.1.1"/' galaxy.yml
+ sed -i 's/ansible\.posix:\s*"\*"/ansible.posix: "1.5.4"/' galaxy.yml
+ sed -i 's/community\.general:\s*"\*"/community.general: "8.6.0"/' galaxy.yml
+ sed -i 's/community\.mysql:\s*"\*"/community.mysql: "3.9.0"/' galaxy.yml
+ sed -i 's/community\.postgresql:\s*"\*"/community.postgresql: "3.4.0"/' galaxy.yml
+
collection_file=$( basename $(ansible-galaxy collection build -f | awk -F" " '{print $NF}'))
echo "COLLECTION_FILE=$collection_file" >> $GITHUB_ENV
- name: Install the collection
- run: ansible-galaxy collection install $COLLECTION_FILE
+ run: ansible-galaxy collection install -vvvv $COLLECTION_FILE
- name: Run server role tests
run: >-
diff --git a/ansible_collections/community/zabbix/.github/workflows/plugins-integration.yml b/ansible_collections/community/zabbix/.github/workflows/plugins-integration.yml
index f23071a1b..644ba2ca3 100644
--- a/ansible_collections/community/zabbix/.github/workflows/plugins-integration.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/plugins-integration.yml
@@ -41,7 +41,7 @@ jobs:
path: ansible_collections/community/zabbix
- name: Set up Python ${{ matrix.python }}
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
diff --git a/ansible_collections/community/zabbix/.github/workflows/proxy.yml b/ansible_collections/community/zabbix/.github/workflows/proxy.yml
index 985bb8ceb..ad5f61b34 100644
--- a/ansible_collections/community/zabbix/.github/workflows/proxy.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/proxy.yml
@@ -51,7 +51,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up Python 3.9
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: 3.9
@@ -62,11 +62,19 @@ jobs:
- name: Build the collection
run: |
+ # Pin versions to speed up CI
+ sed -i 's/ansible\.windows:\s*"\*"/ansible.windows: "2.3.0"/' galaxy.yml
+ sed -i 's/ansible\.netcommon:\s*"\*"/ansible.netcommon: "6.1.1"/' galaxy.yml
+ sed -i 's/ansible\.posix:\s*"\*"/ansible.posix: "1.5.4"/' galaxy.yml
+ sed -i 's/community\.general:\s*"\*"/community.general: "8.6.0"/' galaxy.yml
+ sed -i 's/community\.mysql:\s*"\*"/community.mysql: "3.9.0"/' galaxy.yml
+ sed -i 's/community\.postgresql:\s*"\*"/community.postgresql: "3.4.0"/' galaxy.yml
+
collection_file=$( basename $(ansible-galaxy collection build -f | awk -F" " '{print $NF}'))
echo "COLLECTION_FILE=$collection_file" >> $GITHUB_ENV
- name: Install the collection
- run: ansible-galaxy collection install $COLLECTION_FILE
+ run: ansible-galaxy collection install -vvvv $COLLECTION_FILE
- name: Run role tests
run: >-
diff --git a/ansible_collections/community/zabbix/.github/workflows/repo-sanity.yml b/ansible_collections/community/zabbix/.github/workflows/repo-sanity.yml
index 499d2f1ae..ba776e54f 100644
--- a/ansible_collections/community/zabbix/.github/workflows/repo-sanity.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/repo-sanity.yml
@@ -19,7 +19,7 @@ jobs:
path: ansible_collections/community/zabbix
- name: Set up Python ${{ matrix.python }}
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
diff --git a/ansible_collections/community/zabbix/.github/workflows/server.yml b/ansible_collections/community/zabbix/.github/workflows/server.yml
index b169aa9f1..33f5cd5fd 100644
--- a/ansible_collections/community/zabbix/.github/workflows/server.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/server.yml
@@ -55,7 +55,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up Python 3.9
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: 3.9
@@ -66,11 +66,19 @@ jobs:
- name: Build the collection
run: |
+ # Pin versions to speed up CI
+ sed -i 's/ansible\.windows:\s*"\*"/ansible.windows: "2.3.0"/' galaxy.yml
+ sed -i 's/ansible\.netcommon:\s*"\*"/ansible.netcommon: "6.1.1"/' galaxy.yml
+ sed -i 's/ansible\.posix:\s*"\*"/ansible.posix: "1.5.4"/' galaxy.yml
+ sed -i 's/community\.general:\s*"\*"/community.general: "8.6.0"/' galaxy.yml
+ sed -i 's/community\.mysql:\s*"\*"/community.mysql: "3.9.0"/' galaxy.yml
+ sed -i 's/community\.postgresql:\s*"\*"/community.postgresql: "3.4.0"/' galaxy.yml
+
collection_file=$( basename $(ansible-galaxy collection build -f | awk -F" " '{print $NF}'))
echo "COLLECTION_FILE=$collection_file" >> $GITHUB_ENV
- name: Install the collection
- run: ansible-galaxy collection install $COLLECTION_FILE
+ run: ansible-galaxy collection install -vvvv $COLLECTION_FILE
- name: Run server role tests
run: >-
diff --git a/ansible_collections/community/zabbix/.github/workflows/web.yml b/ansible_collections/community/zabbix/.github/workflows/web.yml
index 79b7beb11..0541a2457 100644
--- a/ansible_collections/community/zabbix/.github/workflows/web.yml
+++ b/ansible_collections/community/zabbix/.github/workflows/web.yml
@@ -57,7 +57,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up Python 3.9
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: 3.9
@@ -68,11 +68,19 @@ jobs:
- name: Build the collection
run: |
+ # Pin versions to speed up CI
+ sed -i 's/ansible\.windows:\s*"\*"/ansible.windows: "2.3.0"/' galaxy.yml
+ sed -i 's/ansible\.netcommon:\s*"\*"/ansible.netcommon: "6.1.1"/' galaxy.yml
+ sed -i 's/ansible\.posix:\s*"\*"/ansible.posix: "1.5.4"/' galaxy.yml
+ sed -i 's/community\.general:\s*"\*"/community.general: "8.6.0"/' galaxy.yml
+ sed -i 's/community\.mysql:\s*"\*"/community.mysql: "3.9.0"/' galaxy.yml
+ sed -i 's/community\.postgresql:\s*"\*"/community.postgresql: "3.4.0"/' galaxy.yml
+
collection_file=$( basename $(ansible-galaxy collection build -f | awk -F" " '{print $NF}'))
echo "COLLECTION_FILE=$collection_file" >> $GITHUB_ENV
- name: Install the collection
- run: ansible-galaxy collection install $COLLECTION_FILE
+ run: ansible-galaxy collection install -vvvv $COLLECTION_FILE
- name: Run role tests
run: >-
diff --git a/ansible_collections/community/zabbix/CHANGELOG.rst b/ansible_collections/community/zabbix/CHANGELOG.rst
index e6b53e476..4675d1a5a 100644
--- a/ansible_collections/community/zabbix/CHANGELOG.rst
+++ b/ansible_collections/community/zabbix/CHANGELOG.rst
@@ -4,6 +4,42 @@ community.zabbix Release Notes
.. contents:: Topics
+v2.4.0
+======
+
+Minor Changes
+-------------
+
+- Add slash at the end of the location directives, to prevent path traversal attacks.
+- Added active_since and active_till in zabbix_maintenance
+- Added content_type for email in zabbix_mediatypes
+- Introduce flag `enable_version_check` to allow installations on non-supported platforms.
+- agent, javagateway, proxy, server, and web role - added the http_proxy and https_proxy environment variables to "Debian | Download gpg key" analog to other tasks
+- agent, javagateway, proxy, server, and web role - introduced default variable zabbix_repo_deb_gpg_key_url with value http://repo.zabbix.com/zabbix-official-repo.key
+- agent, javagateway, proxy, server, and web role - introduced default variable zabbix_repo_deb_include_deb_src with value true
+- agent, javagateway, proxy, server, and web role - removed superfluous slash in zabbix_gpg_key of the Debian vars and renamed key to zabbix-repo instead of zabbix-official-repo
+- agent, javagateway, proxy, server, and web role - used variable zabbix_repo_deb_include_deb_src in "Debian | Installing repository" to determine whether deb-src should be added to /etc/apt/sources.list.d/zabbix.sources
+- agent, javagateway, proxy, server, and web role - used zabbix_repo_deb_gpg_key_url in "Debian | Download gpg key" instead of hardcoded url
+- zabbix_correlation module added
+- zabbix_service_info module added
+- zabbix_template - Add template_yaml parameter.
+- zabbix_web role, Refactored zabbix_selinux variable names to correlate with selinux boolean names.
+
+Bugfixes
+--------
+
+- zabbix_agent - Fixed IPMI authentication algorithm default setting
+- zabbix_agent - Fixed issue to where scripts can be deployed alongside userparameters
+- zabbix_host - Don't reset IPMI setting when update inventory data of a host
+- zabbix_host - Finish task with failed if host_group parameter is empty list
+- zabbix_server - proper indentaion of become in selinux.yaml
+- zabbix_web - Added missing semicolon to nginx vhost template.
+- zabbix_web role, Add missing selinux.yml tasks.
+
+New Modules
+-----------
+
+- community.zabbix.zabbix_correlation - Create/update/delete Zabbix correlation
v2.3.1
======
@@ -598,7 +634,6 @@ Release Summary
| Release date: 2020-10-22
-
Minor Changes
-------------
@@ -625,7 +660,6 @@ Release Summary
| Release date: 2020-08-16
-
Minor Changes
-------------
@@ -665,7 +699,6 @@ Release Summary
| Release date: 2020-07-26
-
Minor Changes
-------------
@@ -738,7 +771,6 @@ Release Summary
| Release date: 2020-06-15
-
Minor Changes
-------------
diff --git a/ansible_collections/community/zabbix/FILES.json b/ansible_collections/community/zabbix/FILES.json
index d8e8b2611..694f37957 100644
--- a/ansible_collections/community/zabbix/FILES.json
+++ b/ansible_collections/community/zabbix/FILES.json
@@ -46,49 +46,49 @@
"name": ".github/workflows/agent.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1f4eaa1cf578bb1ac84173e292873c14483a3e9b0218badf5f99b949b1d19f75",
+ "chksum_sha256": "ab09e77c1cfb09d0ead5281bcfcd6cfb54d6eaa8380affbd53ec47c38c577855",
"format": 1
},
{
"name": ".github/workflows/javagateway.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "282c567de319fd40b888e0bea2b8340418acaf3e1360b1f4cd2fcec845580c4d",
+ "chksum_sha256": "5fece5724408d5a2170a22b1fdedf601451248c723f84066b7d1076dff06dbec",
"format": 1
},
{
"name": ".github/workflows/plugins-integration.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c8ab5f2a2482938905571a63bc80edb9bc421a7356526adff54978f158c998be",
+ "chksum_sha256": "45f764928578ae0ce15106c9470a6c9de97871904086e379b1f0fdd9d9008652",
"format": 1
},
{
"name": ".github/workflows/proxy.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0b93f36762cb804aa12a46d2e15ec2b0cf4ec61198db451fb5e8d60601c4e2c7",
+ "chksum_sha256": "f21f654a95b514e188c7cc090b21685521112a90610fef14bc487301141b17af",
"format": 1
},
{
"name": ".github/workflows/repo-sanity.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7df59ea87533f81dea79e8869b8a4074e0caafa171b62d07d24fc53ae4447af2",
+ "chksum_sha256": "d422174bd05376e9615660ed1f3d25d6c70cbda68a4869854d468469a562da93",
"format": 1
},
{
"name": ".github/workflows/server.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "20f9e0d9de9e0b5fba678c672628e0bf2900794a61e7a9b4414e16dd10eda3b3",
+ "chksum_sha256": "1925557e00452541d0105523033dba1edd9e3ee8ca95b3373c006c1f96973380",
"format": 1
},
{
"name": ".github/workflows/web.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c5e042f11aeabebedb326853b6a5712c3ef02fbc884329b26c4b38d3d942861a",
+ "chksum_sha256": "b8665c7b983f6b76cba7da881ab0cd450439217a5bd519ae7f30933a3ded554a",
"format": 1
},
{
@@ -116,14 +116,14 @@
"name": "changelogs/.plugin-cache.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d64872f24dbd6423bc177cc30e44f48f8f2c008fb83d98320c86507e52bc4fd2",
+ "chksum_sha256": "ddbed2431f771d0b08ec1059fcfc03df63768d78c59488ffadfddae737f52028",
"format": 1
},
{
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7ec8214d899a562092105e8650db5a80d38065ac6f21e8eba77ce6b31c1be9b9",
+ "chksum_sha256": "25653a4be548f83eb8db9059d833a8298cc278f4ff812ff3b79abaa9fcb63f1e",
"format": 1
},
{
@@ -158,35 +158,35 @@
"name": "docs/ZABBIX_AGENT_ROLE.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "426cdb2833f6b41fae8e6d3eceb45e5d7e53bb64fda20238a4843e1f23ce6bc5",
+ "chksum_sha256": "d256f34122a50d20bf5d074df98558de74774e591bb2bc309e858ab0f2c7a7b8",
"format": 1
},
{
"name": "docs/ZABBIX_JAVAGATEWAY_ROLE.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "950880306b5d99f842830620bcb03e3a67d487ab62b60c650421027b620824c9",
+ "chksum_sha256": "168aae7236576e4baf77c7b056833d5c90527c99365d7c9487f05f7af4d7281a",
"format": 1
},
{
"name": "docs/ZABBIX_PROXY_ROLE.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "137aa537b0643a8aba1e3b94965bd33d91a53a780a8873a398e07620a1c64ec4",
+ "chksum_sha256": "5fb7298372379197055d9221660fa37ec078d7b2c5aaa4545ed09a943daa7baf",
"format": 1
},
{
"name": "docs/ZABBIX_SERVER_ROLE.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "434d9e12ff1d20c7f2e1891e2518628eea9f8497502a5032a7f83ea488477665",
+ "chksum_sha256": "e7b83a2f01c4ef1388cba62476dbbe0596c483b345f4a79aabc2cd107cf16b61",
"format": 1
},
{
"name": "docs/ZABBIX_WEB_ROLE.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "228030e059e30b229a82e7c31b609d5d122d710338557ebd74ee151eda79c0fb",
+ "chksum_sha256": "c52def2249d4416ac228eb03d6b57322578e2fb5c118967fb1e11634ff66f64f",
"format": 1
},
{
@@ -242,7 +242,7 @@
"name": "molecule/zabbix_agent_tests/common/playbooks/prepare.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "eebc4f8c272317fba0f96c482780a2850b9474b2b992b3a80d2f3d59c3db9a52",
+ "chksum_sha256": "b49c8f28d430ffbe38f9a37995b5e555935108553a8cdfc624d31622a17ad7d8",
"format": 1
},
{
@@ -543,7 +543,7 @@
"name": "molecule/zabbix_javagateway/molecule.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8e5003cb9d8bcd490b46fe8358affc9cc4c7f60b582c2f42a4713c7fd001768a",
+ "chksum_sha256": "ad23fd87f26a7f5f70b7dbbb1e82fe661052315c2b8ad0f09939d5542641a521",
"format": 1
},
{
@@ -585,21 +585,21 @@
"name": "molecule/zabbix_proxy/destroy.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "99cb34a22f36b18227686720c750aa70745fdd22227d5aeb08a42891998ac09a",
+ "chksum_sha256": "59749010b09c0790699ca54ddb18724640889b53363b8c8d3fbc8259ec9d57c7",
"format": 1
},
{
"name": "molecule/zabbix_proxy/molecule.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "59ff07c357b6c9d01f0337b6c6b5878c90efb396132faec46b37628680bce34d",
+ "chksum_sha256": "4800b75f49e7496f80ace71d84f8f07dc7b9335c8f158bc4155c44a8d8492cc1",
"format": 1
},
{
"name": "molecule/zabbix_proxy/prepare.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d3fde6e25ce3b39d5c70324f7db1ac9aed31e0a3106c51dc77c3be7293f55a19",
+ "chksum_sha256": "4495bcd19fac7b44c8d02c80133e37f554c1f66244a10c4a88e85c11ce97b814",
"format": 1
},
{
@@ -634,21 +634,21 @@
"name": "molecule/zabbix_server/destroy.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "99cb34a22f36b18227686720c750aa70745fdd22227d5aeb08a42891998ac09a",
+ "chksum_sha256": "59749010b09c0790699ca54ddb18724640889b53363b8c8d3fbc8259ec9d57c7",
"format": 1
},
{
"name": "molecule/zabbix_server/molecule.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "eb8ff715881d9046a2aa6d4b0ec64f68c59e7cf48bff7644236e44399570bb53",
+ "chksum_sha256": "7c0b54e3f4f40288f5a772263d1f56a44aebb39e70aad6ec542546b40d7653a9",
"format": 1
},
{
"name": "molecule/zabbix_server/prepare.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "34346df48a4e44910398adcea6030e76735f03464ea0b0415160b2c8b86297d7",
+ "chksum_sha256": "883f99742d21dc27b93d8c8ca8185537a7e7c1c658efd81effdce91e5f8eefee",
"format": 1
},
{
@@ -683,21 +683,21 @@
"name": "molecule/zabbix_web/destroy.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "99cb34a22f36b18227686720c750aa70745fdd22227d5aeb08a42891998ac09a",
+ "chksum_sha256": "59749010b09c0790699ca54ddb18724640889b53363b8c8d3fbc8259ec9d57c7",
"format": 1
},
{
"name": "molecule/zabbix_web/molecule.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "160ca8984b2f48f84e64e2d928ef1ab8a807f5cfb6c36d1c37d7920ca284efca",
+ "chksum_sha256": "18e071b47e76db950db04d6be9ed3e6e16ab750ca276e4e59d1f32cf0c659b89",
"format": 1
},
{
"name": "molecule/zabbix_web/prepare.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "46f227d436fbf62c6a18677746e4b3b2f6854473ea58ea889781d60a5d86acaa",
+ "chksum_sha256": "7628246084a0692187d2408ee30afc478999d24c1e08d6fc0609f59ed828b23e",
"format": 1
},
{
@@ -711,7 +711,7 @@
"name": "molecule/requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "274a2a68c3bac9fefa051ff068179fce63df05424461ff973dd44473c890382b",
+ "chksum_sha256": "26a9987c8545a84ddf26c2774fc1bf16c0dc68fa790dde49b46ce17a1720700e",
"format": 1
},
{
@@ -746,7 +746,7 @@
"name": "plugins/httpapi/zabbix.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bef450e3b5700be1a1cc35981b229a53522a35a0e1d13f1ba715922f3ee79d2c",
+ "chksum_sha256": "d598e1db3a57dda9a90eaf324c066be904c91a5bab099b6c65d612b5141c96ec",
"format": 1
},
{
@@ -848,6 +848,13 @@
"format": 1
},
{
+ "name": "plugins/modules/zabbix_correlation.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "24dfd5a7cb774a9e46de4765efcacf76df880149f7a5614f64c754f8458875ee",
+ "format": 1
+ },
+ {
"name": "plugins/modules/zabbix_discovery_rule.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -886,7 +893,7 @@
"name": "plugins/modules/zabbix_host.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ce0879953bfeaac236d6329b08fd19f7573a9a172ef4fa777489d6f9f1fd6609",
+ "chksum_sha256": "0593dcc5f865688ab3ee51ab930d963bb688970807a0f4b3b67466bb58672481",
"format": 1
},
{
@@ -921,7 +928,7 @@
"name": "plugins/modules/zabbix_maintenance.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "baa73f10a75adbfc09a93d5624492aa9b2e174bf089641cfbd37e329865fe313",
+ "chksum_sha256": "ae2e78fa730c2954ad54c20aa7c98c3e09c077fc035f45d0f7ce906d4ce93b84",
"format": 1
},
{
@@ -935,7 +942,7 @@
"name": "plugins/modules/zabbix_mediatype.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "555d924fcf31e673c17917fc5f7abf1d6d8f1de17d87386f5a2626549cdab7f3",
+ "chksum_sha256": "d72dc3a2fc07e6ae4ddd344d3111a62098439a21d3e77f235f89783490db4644",
"format": 1
},
{
@@ -974,6 +981,13 @@
"format": 1
},
{
+ "name": "plugins/modules/zabbix_service_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5e011d9a0a3e1a15d2b1255c90989143c24be78e433351483afb0191ed7009fe",
+ "format": 1
+ },
+ {
"name": "plugins/modules/zabbix_settings.py",
"ftype": "file",
"chksum_type": "sha256",
@@ -984,7 +998,7 @@
"name": "plugins/modules/zabbix_template.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d08d3ff4e10193b5a69e3bb515c1ee00157526ab702dc4ffadca8b4adb1c2b1c",
+ "chksum_sha256": "9a95177cd5e385dc637bef839f94ddafbad1fd7c49b3d66f1a6a04734ef178ce",
"format": 1
},
{
@@ -998,7 +1012,7 @@
"name": "plugins/modules/zabbix_templategroup.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9c8ca31207e2894422502cf15cf3e3774ce2f944e4bc403c87ab5978f360b236",
+ "chksum_sha256": "1d908eaf6a6ef5f9269261f3c9be63180edd805736428b95365d2cffbd94785a",
"format": 1
},
{
@@ -1068,7 +1082,7 @@
"name": "roles/zabbix_agent/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "426cdb2833f6b41fae8e6d3eceb45e5d7e53bb64fda20238a4843e1f23ce6bc5",
+ "chksum_sha256": "d256f34122a50d20bf5d074df98558de74774e591bb2bc309e858ab0f2c7a7b8",
"format": 1
},
{
@@ -1082,7 +1096,7 @@
"name": "roles/zabbix_agent/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e86a6de88e4fb31fd47d9268557e10f71e42988e4dca09a6228497be99c1c225",
+ "chksum_sha256": "7465f741a1390bc62b1f30f3daf28f271ad94942c2f727fabfe576277fd4c1f3",
"format": 1
},
{
@@ -1208,7 +1222,7 @@
"name": "roles/zabbix_agent/molecule/with-server/prepare.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "091c8043ef580658ab2b4c93020888562cd5b3ca5a32d78f7c43892696e0f118",
+ "chksum_sha256": "00649fa33818851871f0305372c4d9c1205a77411b0b9b5deb1b5bfe4e09668d",
"format": 1
},
{
@@ -1229,7 +1243,7 @@
"name": "roles/zabbix_agent/tasks/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6d5e5886e18c5774d89567b311e2fbd2dc4aad0b1950af22bb88fafe152a3b78",
+ "chksum_sha256": "97c991dcccf9ab92bad90d36caf6e2d3bdd2b9eb9461aded42696b3e76c7b1ad",
"format": 1
},
{
@@ -1285,7 +1299,7 @@
"name": "roles/zabbix_agent/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "978ae5731bb64fc79a4c404185da1f915480550e0a79ab8cdcc94475dc0ff86e",
+ "chksum_sha256": "7ceb0be05f5fb90c9d007ae64a43ca66fa855c484410df95c46e41853a44f5bd",
"format": 1
},
{
@@ -1362,7 +1376,7 @@
"name": "roles/zabbix_agent/tasks/userparameter.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5248b27e7d45f14a3abdd5d93bf80e416f6e6f084f54f1cceeeba0f1ab08b9dd",
+ "chksum_sha256": "e2bb476b24d7e4997daa41e15959d1b70c538b8aa9eaf20d3b2e759c23534290",
"format": 1
},
{
@@ -1418,7 +1432,7 @@
"name": "roles/zabbix_agent/vars/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a5da93f0d2b1f52521b40c0434ebbb78c7c13dfd63b1948689e104e86fc81a6c",
+ "chksum_sha256": "b3fdab5e28c143947f965aa38b670a83726994f8e6fb37b7fac24350c9471a28",
"format": 1
},
{
@@ -1453,7 +1467,7 @@
"name": "roles/zabbix_javagateway/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "950880306b5d99f842830620bcb03e3a67d487ab62b60c650421027b620824c9",
+ "chksum_sha256": "168aae7236576e4baf77c7b056833d5c90527c99365d7c9487f05f7af4d7281a",
"format": 1
},
{
@@ -1467,7 +1481,7 @@
"name": "roles/zabbix_javagateway/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "72237d44a0cfac809b0432db46974f2bb48d1a61260d80491d1c7bde73f1bf47",
+ "chksum_sha256": "169d719e540777e49a40c86c1ad09d21f6f408ebd346efa9e6ab926b0e85321f",
"format": 1
},
{
@@ -1523,7 +1537,7 @@
"name": "roles/zabbix_javagateway/tasks/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1cf7aeabb650158552dcc993e72c3aee3dd54c9d160d95ac4e603eec39d3c763",
+ "chksum_sha256": "44f9adfe675690b1901bf67f5c60da034bbbc4448476f3a2d69993a180f9dedc",
"format": 1
},
{
@@ -1537,7 +1551,7 @@
"name": "roles/zabbix_javagateway/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "67e5a9cd03529caca8af75622431ec4fe54bc256b14ad7568bedaedfd0f9206a",
+ "chksum_sha256": "e8857dcc83a8336f5d9103cbc0af3035d298335a2a62bbf98de4a25edff44230",
"format": 1
},
{
@@ -1565,7 +1579,7 @@
"name": "roles/zabbix_javagateway/vars/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f6a87b8863fc8b0cf5dec159ecbe788b8cb1963c11d3dfcfddb6f64d3dfce77e",
+ "chksum_sha256": "be7796f9ccb7e43552833863142669694201bba88e396406f29f8881e28f381a",
"format": 1
},
{
@@ -1593,7 +1607,7 @@
"name": "roles/zabbix_proxy/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "137aa537b0643a8aba1e3b94965bd33d91a53a780a8873a398e07620a1c64ec4",
+ "chksum_sha256": "5fb7298372379197055d9221660fa37ec078d7b2c5aaa4545ed09a943daa7baf",
"format": 1
},
{
@@ -1607,7 +1621,7 @@
"name": "roles/zabbix_proxy/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f3cc7cde32ae9908078b20eb97d7f25baaccbbd2f0ea4678296ae36a3fb10087",
+ "chksum_sha256": "33dcb508919b88bf2ef0b1c6bc5b121a67392553e54a58b55bf572bf00ea5d53",
"format": 1
},
{
@@ -1663,7 +1677,7 @@
"name": "roles/zabbix_proxy/tasks/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "62d366a97ff9d7a6b6f5ec20bde13cb22b447b0271f7e2e432dcad6c9b771712",
+ "chksum_sha256": "92c82d7303b5ec4b9e688bdb8017e5f213993f9c66007ad95846b2db30cfb414",
"format": 1
},
{
@@ -1677,7 +1691,7 @@
"name": "roles/zabbix_proxy/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "45ee561d3bf7df8a5067ccb625a15546b2572e202f75614b57af7143766cf63a",
+ "chksum_sha256": "3751caa6aaa36f2f878f60bd81a53ff4fb6dc1e45c0e9ec6c8c195fc3da765a1",
"format": 1
},
{
@@ -1733,7 +1747,7 @@
"name": "roles/zabbix_proxy/vars/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "66a3826d949a04140ff1fda9f008f8ef657050cb854677b4cf5c07c69a546346",
+ "chksum_sha256": "0c3453870dcd59ed9f69f3fdac8a1b46bf683a87ab86e87cc69b28d3951cce43",
"format": 1
},
{
@@ -1768,7 +1782,7 @@
"name": "roles/zabbix_server/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "434d9e12ff1d20c7f2e1891e2518628eea9f8497502a5032a7f83ea488477665",
+ "chksum_sha256": "e7b83a2f01c4ef1388cba62476dbbe0596c483b345f4a79aabc2cd107cf16b61",
"format": 1
},
{
@@ -1782,7 +1796,7 @@
"name": "roles/zabbix_server/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "024b79ba5eb85cb58403e606c0914e5e606a26e085795e7e7bccbf4f57d8ff66",
+ "chksum_sha256": "e77fe177f086c46a5fbce843360203fcd6b0bd3cb70cbce6582b73e50fb4f1d8",
"format": 1
},
{
@@ -1838,35 +1852,35 @@
"name": "roles/zabbix_server/tasks/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c174231cd483409e026d4b82e987ce3f2e2b30405b71ab15dab333b7c37e2f7c",
+ "chksum_sha256": "efdf8a1e0875c14dc97e4984063a9f775047af3e324baff629963f59139eb646",
"format": 1
},
{
"name": "roles/zabbix_server/tasks/RedHat.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "99bc6623e1018b3c5565d97670385a0ff3b205d3b9dccc5da0d3082f05f6f305",
+ "chksum_sha256": "c843b63e5dc9c44dfa748b6f6b5524f796d1b7a7bbf6151f89e7726770c399ce",
"format": 1
},
{
- "name": "roles/zabbix_server/tasks/main.yml",
+ "name": "roles/zabbix_server/tasks/initialize-mysql.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a56f05203c959669058d2172d90f11dca5bd024c85651a75ecde52db2148f991",
+ "chksum_sha256": "f391750aff2b4e7c74c292036829fe7a44bb3fbfaed9bdb12393542b59132502",
"format": 1
},
{
- "name": "roles/zabbix_server/tasks/mysql.yml",
+ "name": "roles/zabbix_server/tasks/initialize-pgsql.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "aa11fd9cfc1662112ed5f321bd06ccde126f65ee7531267c4357f6e82cab540e",
+ "chksum_sha256": "df0005a12cc1d89f1a361f1d5f2764600a24527a567cce4b38f69490651f5541",
"format": 1
},
{
- "name": "roles/zabbix_server/tasks/postgresql.yml",
+ "name": "roles/zabbix_server/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "44146c8e7329cb92aa907a64d7c646700b8125b93dbcbbeb50716ad01f434c53",
+ "chksum_sha256": "ef880f7dbdcaf97b43f1c407334a0ca44304a1d6ae31089a4850f362f1bc1f04",
"format": 1
},
{
@@ -1880,7 +1894,7 @@
"name": "roles/zabbix_server/tasks/selinux.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b2d30030efe386cfb08fc3f45cd4a4c1efc17c41df031f31deaf9d683f4d6a27",
+ "chksum_sha256": "f82baa01937f5e3e29b02be6fefd51f7c6cafcefebd44e9a3cf2a8c22d9c5e8c",
"format": 1
},
{
@@ -1908,14 +1922,14 @@
"name": "roles/zabbix_server/vars/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "67cb0847a5e96afd2b05a9e4db7f8383d6d0376cc4f93db206dc80c7778310eb",
+ "chksum_sha256": "428c1f85055c5afdccf997e4c6ab8fd4b9999760f93517dcbea2f41c88f82cb5",
"format": 1
},
{
"name": "roles/zabbix_server/vars/RedHat.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c27f0472596d51fd438b8d6f1c9b3bb788d7865b0c818d58c1b1456b3ec62185",
+ "chksum_sha256": "2650cb0aa53bf8f07b1bc2604b18c31ba88ee8ac407b6f6bb2779b0532b81781",
"format": 1
},
{
@@ -1943,7 +1957,7 @@
"name": "roles/zabbix_web/README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "228030e059e30b229a82e7c31b609d5d122d710338557ebd74ee151eda79c0fb",
+ "chksum_sha256": "c52def2249d4416ac228eb03d6b57322578e2fb5c118967fb1e11634ff66f64f",
"format": 1
},
{
@@ -1957,7 +1971,7 @@
"name": "roles/zabbix_web/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "136689b650ad54e8046ca7f1f7f24cc8d528dfcde385b1027f2aa7b64ca3c26c",
+ "chksum_sha256": "49d8438ddfc81fa2d4c1ae65877229dbab7c2b010897013bfbb3f4486a7b96c4",
"format": 1
},
{
@@ -1999,14 +2013,14 @@
"name": "roles/zabbix_web/tasks/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7c7426b9d16b6868f72eea3aa28c390217c51f5ba9aaa9afcf41caffb8072808",
+ "chksum_sha256": "f79cf8bd5892511d4499e72876b8ad62ddbf651236bc74acb4bc25e8b66be8ad",
"format": 1
},
{
"name": "roles/zabbix_web/tasks/RedHat.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b2a875ae0deaf4facd16416db665771c03395e90879c3691e2430cf24e2f7331",
+ "chksum_sha256": "49891f2059325d2b9070af4c726a014e10a2120978bccaa651e47a8f27ee8a24",
"format": 1
},
{
@@ -2020,7 +2034,7 @@
"name": "roles/zabbix_web/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9961406bcd8733eb9a504a8a4d2766148fdcb43ca2d5e27d007e2c041cccc4a5",
+ "chksum_sha256": "08eea52bde9af3a33c1c1145aac963f754498862532bffedb2a146bc662c72d9",
"format": 1
},
{
@@ -2034,7 +2048,7 @@
"name": "roles/zabbix_web/tasks/selinux.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5b696169bbd552cba7f54fb7bc9f8fba7b885e0d2048cd4c56f2de57a3c560cd",
+ "chksum_sha256": "a88bf34858bebd60e78d8b56c0e2682e411285a56176d3165fe404937c5e3b04",
"format": 1
},
{
@@ -2055,7 +2069,7 @@
"name": "roles/zabbix_web/templates/nginx_vhost.conf.j2",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4b66f5e157d4d15419a4d3e5e8580b2f50d5413ed092f026902ebed50bb431f4",
+ "chksum_sha256": "67d34aee35ab5e67b2b0259cfda5e7164a60272349a18661b2ef9d2252f06dff",
"format": 1
},
{
@@ -2083,7 +2097,7 @@
"name": "roles/zabbix_web/vars/Debian.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "61d4c2a23a9261eeeb511a5ba6e3e9d2d46856c69a390a4ff9f8fbfaad57ec50",
+ "chksum_sha256": "42d65bb39698381f067773966ab6605f96b6b7ced0e5d63e217ac0877d7dc7ad",
"format": 1
},
{
@@ -2325,6 +2339,41 @@
"format": 1
},
{
+ "name": "tests/integration/targets/test_zabbix_correlation",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_correlation/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_correlation/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "63ae23343a8854777c0e014be5fdd33db6a6b78f96d22a889ad78556dc0ffa81",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_correlation/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_correlation/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "41ac61f463abbb2342d912d9b3f657105290a7ee7a6862f97cc2b395e0af9171",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/test_zabbix_discovery_rule",
"ftype": "dir",
"chksum_type": null,
@@ -2573,7 +2622,7 @@
"name": "tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "10fdc4850cbc5a8c135b6010af276b1f5384d617f746ee3ef001e2f34b3cf289",
+ "chksum_sha256": "8d869ea43ae5374a7d7442968f0f46e2b3ea9bba5889c55f6bfc2a1e068ed8c9",
"format": 1
},
{
@@ -2713,7 +2762,7 @@
"name": "tests/integration/targets/test_zabbix_maintenance/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1e3c539311dc4f4c55b85931338f0693121ff1814cbc4d199fe02a689c5d298b",
+ "chksum_sha256": "ccdc41dfc4c4c391a480458d08af8764c7bfd45e00a9efeb7a2162628c1579fd",
"format": 1
},
{
@@ -2748,7 +2797,7 @@
"name": "tests/integration/targets/test_zabbix_mediatype/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c7a4f5cecfef03f695f94a47e7c663a3acb582757df2951e8af77279b2a2e797",
+ "chksum_sha256": "4654f230520d7e2726c0bb1d246cb0cf6ae76120a33c4acdc0a8c4b6549c2b84",
"format": 1
},
{
@@ -2976,6 +3025,41 @@
"format": 1
},
{
+ "name": "tests/integration/targets/test_zabbix_service_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_service_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_service_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "63ae23343a8854777c0e014be5fdd33db6a6b78f96d22a889ad78556dc0ffa81",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_service_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_service_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "81993514162d631138154fdde2e0aa9dd1896609638bf01bf59f5d6a98df8009",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/test_zabbix_settings",
"ftype": "dir",
"chksum_type": null,
@@ -3081,6 +3165,27 @@
"format": 1
},
{
+ "name": "tests/integration/targets/test_zabbix_template/files/template4_60_higher.json",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "39a95f703429d1845a04e106d1a921990a78ce220c1fd4d1af7ed9b5bc90ee06",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_template/files/template4_60_higher.xml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e91a1052602222dc146a54bb7b59915c951a3b6f0762162fb2aa6682839f43bb",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/test_zabbix_template/files/template4_60_higher.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "371d417e80a1380977c9d9c13f5c42c09096fbc15ef48b76e2dfad5e44004baa",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/test_zabbix_template/meta",
"ftype": "dir",
"chksum_type": null,
@@ -3105,7 +3210,7 @@
"name": "tests/integration/targets/test_zabbix_template/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "235eb7982d8a11e0e6fd68b53693d49daa89db486f91230e74497f75a0f8d2dc",
+ "chksum_sha256": "f86eb77c3eac1f431f59fa5f94ce07a1c4035826f1898987e4045036b19c9bb3",
"format": 1
},
{
@@ -3434,7 +3539,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f963b76b08f69f8aac6b8daf732d95ce00e1670316f7e8f7bcb674f8d2e3aa6c",
+ "chksum_sha256": "841378afa489d7ab18a26f89a6c8a91949c1fb0c05c54b00ab5518157d83f3fa",
"format": 1
},
{
@@ -3476,7 +3581,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e47ca851f19b23497aa052424107b157400ef0d16cc745b1151fcff933ca2b86",
+ "chksum_sha256": "e78a31db573596c05c1b54e4da2ab59b53b57c8e19b41694e16fc8a600d366e8",
"format": 1
},
{
diff --git a/ansible_collections/community/zabbix/MANIFEST.json b/ansible_collections/community/zabbix/MANIFEST.json
index 37c48a609..803b2a538 100644
--- a/ansible_collections/community/zabbix/MANIFEST.json
+++ b/ansible_collections/community/zabbix/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "zabbix",
- "version": "2.3.1",
+ "version": "2.4.0",
"authors": [
"Dusan Matejka (@D3DeFi)",
"sky-joker (@sky-joker)",
@@ -35,7 +35,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ed1fe1d72e38eb5978be766233f7389e444c2dcaded74877d323c41ac9712a46",
+ "chksum_sha256": "48923f5d0d4edaa37a77a0dda92c0f41f762a24a9d7ab4bd04c816cf9f3bd73a",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/zabbix/README.md b/ansible_collections/community/zabbix/README.md
index be268fc4a..889645483 100644
--- a/ansible_collections/community/zabbix/README.md
+++ b/ansible_collections/community/zabbix/README.md
@@ -104,7 +104,7 @@ You can also include it in a `requirements.yml` file along with other required c
---
collections:
- name: community.zabbix
- version: 2.3.1
+ version: 2.4.0
- name: ansible.posix
version: 1.3.0
- name: community.general
diff --git a/ansible_collections/community/zabbix/changelogs/.plugin-cache.yaml b/ansible_collections/community/zabbix/changelogs/.plugin-cache.yaml
index 9ea52adc2..78da79cd3 100644
--- a/ansible_collections/community/zabbix/changelogs/.plugin-cache.yaml
+++ b/ansible_collections/community/zabbix/changelogs/.plugin-cache.yaml
@@ -1,12 +1,10 @@
-objects:
- role: {}
+objects: {}
plugins:
become: {}
cache: {}
callback: {}
cliconf: {}
connection: {}
- filter: {}
httpapi:
zabbix:
description: HttpApi Plugin for Zabbix
@@ -39,6 +37,11 @@ plugins:
name: zabbix_autoregister
namespace: ''
version_added: 1.6.0
+ zabbix_correlation:
+ description: Create/update/delete Zabbix correlation
+ name: zabbix_correlation
+ namespace: ''
+ version_added: 2.4.0
zabbix_discovery_rule:
description: Create/delete/update Zabbix discovery rules
name: zabbix_discovery_rule
@@ -129,6 +132,11 @@ plugins:
name: zabbix_service
namespace: ''
version_added: null
+ zabbix_service_info:
+ description: Gather information about Zabbix service
+ name: zabbix_service_info
+ namespace: ''
+ version_added: null
zabbix_settings:
description: Update Zabbix global settings.
name: zabbix_settings
@@ -187,6 +195,5 @@ plugins:
netconf: {}
shell: {}
strategy: {}
- test: {}
vars: {}
-version: 2.3.1
+version: 2.4.0
diff --git a/ansible_collections/community/zabbix/changelogs/changelog.yaml b/ansible_collections/community/zabbix/changelogs/changelog.yaml
index 600e0ab78..608160c0b 100644
--- a/ansible_collections/community/zabbix/changelogs/changelog.yaml
+++ b/ansible_collections/community/zabbix/changelogs/changelog.yaml
@@ -1092,3 +1092,61 @@ releases:
fragments:
- 1156-bugfix_zabbix_user_directory_dryrun.yml
release_date: '2024-01-10'
+ 2.4.0:
+ changes:
+ bugfixes:
+ - zabbix_agent - Fixed IPMI authentication algorithm default setting
+ - zabbix_agent - Fixed issue to where scripts can be deployed alongside userparameters
+ - zabbix_host - Don't reset IPMI setting when update inventory data of a host
+ - zabbix_host - Finish task with failed if host_group parameter is empty list
+ - zabbix_server - proper indentaion of become in selinux.yaml
+ - zabbix_web - Added missing semicolon to nginx vhost template.
+ - zabbix_web role, Add missing selinux.yml tasks.
+ minor_changes:
+ - Add slash at the end of the location directives, to prevent path traversal
+ attacks.
+ - Added active_since and active_till in zabbix_maintenance
+ - Added content_type for email in zabbix_mediatypes
+ - Introduce flag `enable_version_check` to allow installations on non-supported
+ platforms.
+ - agent, javagateway, proxy, server, and web role - added the http_proxy and
+ https_proxy environment variables to "Debian | Download gpg key" analog to
+ other tasks
+ - agent, javagateway, proxy, server, and web role - introduced default variable
+ zabbix_repo_deb_gpg_key_url with value http://repo.zabbix.com/zabbix-official-repo.key
+ - agent, javagateway, proxy, server, and web role - introduced default variable
+ zabbix_repo_deb_include_deb_src with value true
+ - agent, javagateway, proxy, server, and web role - removed superfluous slash
+ in zabbix_gpg_key of the Debian vars and renamed key to zabbix-repo instead
+ of zabbix-official-repo
+ - agent, javagateway, proxy, server, and web role - used variable zabbix_repo_deb_include_deb_src
+ in "Debian | Installing repository" to determine whether deb-src should be
+ added to /etc/apt/sources.list.d/zabbix.sources
+ - agent, javagateway, proxy, server, and web role - used zabbix_repo_deb_gpg_key_url
+ in "Debian | Download gpg key" instead of hardcoded url
+ - zabbix_correlation module added
+ - zabbix_service_info module added
+ - zabbix_template - Add template_yaml parameter.
+ - zabbix_web role, Refactored zabbix_selinux variable names to correlate with
+ selinux boolean names.
+ fragments:
+ - 1157-add_template_yaml.yml
+ - 1162-do_not_update_ipmi_options.yml
+ - 1165-indent-become.yml
+ - 1168-finish-task-with-failed-if-host_group-parameter-is-empty_list.yml
+ - 1169-add_zabbix_correlation.yml
+ - 1176-content_type-in-mediatype.yml
+ - 1180-active_since-in-maintenance.yml
+ - 1183-nginx-fix-against-path-traversal.yml
+ - 1186-custom_gpg_key_url.yml
+ - 1188-agent_ipmi_authtype_fix.yml
+ - 1205-fix-zabbix-agent-scripts.yml
+ - 1206-fix-nginx-template-ssl-params.yml
+ - 1210-add_zabbix_service_info.yml
+ - 1220-refactor_selinux_tasks_and_variable_names_role_zabbix_web.yml
+ - 1224-enable-version-check.yml
+ modules:
+ - description: Create/update/delete Zabbix correlation
+ name: zabbix_correlation
+ namespace: ''
+ release_date: '2024-05-13'
diff --git a/ansible_collections/community/zabbix/docs/ZABBIX_AGENT_ROLE.md b/ansible_collections/community/zabbix/docs/ZABBIX_AGENT_ROLE.md
index aa73fab3a..fe4a601b3 100644
--- a/ansible_collections/community/zabbix/docs/ZABBIX_AGENT_ROLE.md
+++ b/ansible_collections/community/zabbix/docs/ZABBIX_AGENT_ROLE.md
@@ -102,6 +102,7 @@ See the following list of supported Operating systems with the Zabbix releases:
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | V | V | V |
+You can bypass this matrix by setting `enable_version_check: false`
# Getting started
@@ -136,6 +137,8 @@ The following is an overview of all available configuration default for this rol
* `zabbix_agent_disable_repo`: A list of repos to disable during install. Default `epel`.
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_agent_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### SElinux
@@ -337,7 +340,7 @@ Keep in mind that using the Zabbix Agent in a Container requires changes to the
## IPMI variables
-* `zabbix_agent_ipmi_authtype`: IPMI authentication algorithm. Possible values are 1 (callback), 2 (user), 3 (operator), 4 (admin), 5 (OEM), with 2 being the API default.
+* `zabbix_agent_ipmi_authtype`: IPMI authentication algorithm. Possible values are -1 (default), 0 (none), 1 (MD2), 2 (MD5), 4 (straight), 5 (OEM), 6 (RMCP+), with -1 being the API default.
* `zabbix_agent_ipmi_password`: IPMI password.
* `zabbix_agent_ipmi_privilege`: IPMI privilege level. Possible values are 1 (callback), 2 (user), 3 (operator), 4 (admin), 5 (OEM), with 2 being the API default.
* `zabbix_agent_ipmi_username`: IPMI username.
diff --git a/ansible_collections/community/zabbix/docs/ZABBIX_JAVAGATEWAY_ROLE.md b/ansible_collections/community/zabbix/docs/ZABBIX_JAVAGATEWAY_ROLE.md
index 1761c7f8b..47092a6a0 100644
--- a/ansible_collections/community/zabbix/docs/ZABBIX_JAVAGATEWAY_ROLE.md
+++ b/ansible_collections/community/zabbix/docs/ZABBIX_JAVAGATEWAY_ROLE.md
@@ -46,6 +46,8 @@ See the following list of supported Operating systems with the Zabbix releases.
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | V | V | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Role Variables
## Main variables
@@ -62,6 +64,8 @@ The `zabbix_javagateway_version` is optional. The latest available major.minor v
* `zabbix_javagateway_conf_mode`: Default: `0644`. The "mode" for the Zabbix configuration file.
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_agent_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### Java Gatewaty
diff --git a/ansible_collections/community/zabbix/docs/ZABBIX_PROXY_ROLE.md b/ansible_collections/community/zabbix/docs/ZABBIX_PROXY_ROLE.md
index baec42155..ee558c8b7 100644
--- a/ansible_collections/community/zabbix/docs/ZABBIX_PROXY_ROLE.md
+++ b/ansible_collections/community/zabbix/docs/ZABBIX_PROXY_ROLE.md
@@ -89,6 +89,8 @@ See the following list of supported Operating systems with the Zabbix releases.
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | V | V | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Role Variables
## Main variables
@@ -133,6 +135,9 @@ The following is an overview of all available configuration default for this rol
* `*zabbix_proxy_package_state`: Default: `present`. Can be overridden to `latest` to update packages
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_proxy_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
+
### SElinux
* `zabbix_proxy_selinux`: Default: `False`. Enables an SELinux policy so that the Proxy will run.
diff --git a/ansible_collections/community/zabbix/docs/ZABBIX_SERVER_ROLE.md b/ansible_collections/community/zabbix/docs/ZABBIX_SERVER_ROLE.md
index f154f4951..9557281c3 100644
--- a/ansible_collections/community/zabbix/docs/ZABBIX_SERVER_ROLE.md
+++ b/ansible_collections/community/zabbix/docs/ZABBIX_SERVER_ROLE.md
@@ -86,6 +86,8 @@ See the following list of supported Operating systems with the Zabbix releases:
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | | | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Installation
Installing this role is very simple: `ansible-galaxy install community.zabbix.zabbix_server`
@@ -109,6 +111,8 @@ The following is an overview of all available configuration default for this rol
* `zabbix_service_enabled`: Default: `True` Can be overridden to `False` if needed
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_server_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### SElinux
diff --git a/ansible_collections/community/zabbix/docs/ZABBIX_WEB_ROLE.md b/ansible_collections/community/zabbix/docs/ZABBIX_WEB_ROLE.md
index 5904f8288..aac6f9dc2 100644
--- a/ansible_collections/community/zabbix/docs/ZABBIX_WEB_ROLE.md
+++ b/ansible_collections/community/zabbix/docs/ZABBIX_WEB_ROLE.md
@@ -16,6 +16,7 @@
- [Apache configuration](#apache-configuration)
- [Nginx configuration](#nginx-configuration)
- [PHP-FPM](#php-fpm)
+ - [SElinux](#selinux)
- [Zabbix Server](#zabbix-server)
* [proxy](#proxy)
- [Example Playbook](#example-playbook)
@@ -65,6 +66,8 @@ See the following list of supported Operating Systems with the Zabbix releases.
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | | | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Installation
Installing this role is very simple: `ansible-galaxy install community.zabbix.zabbix_web`
@@ -94,6 +97,8 @@ The following is an overview of all available configuration defaults for this ro
* `zabbix_web_conf_mode`: Default: `0644`. The "mode" for the Zabbix configuration file.
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_web_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### Zabbix Web specific
@@ -116,7 +121,6 @@ The following is an overview of all available configuration defaults for this ro
* `zabbix_web_vhost_port`: The port on which Zabbix HTTP vhost is running.
* `zabbix_web_vhost_tls_port`: The port on which Zabbix HTTPS vhost is running.
* `zabbix_web_vhost_listen_ip`: On which interface the Apache Virtual Host is available.
-* `zabbix_apache_can_connect_ldap`: Default: `false`. Set SELinux boolean to allow httpd to connect to LDAP.
* `zabbix_web_max_execution_time`: PHP max execution time
* `zabbix_web_memory_limit`: PHP memory limit
* `zabbix_web_post_max_size`: PHP maximum post size
@@ -151,6 +155,13 @@ The following properties are specific to Zabbix 5.0 and for the PHP(-FPM) config
* `zabbix_php_fpm_conf_group`: The group of the owner of the socket file (When `zabbix_php_fpm_listen` contains a patch to a socket file).
+### SElinux
+
+* `zabbix_web_selinux`: Default: `False`. Enables an SELinux policy so that the web will run.
+* `selinux_allow_httpd_can_connect_zabbix`: Default: `false`. Set SELinux boolean to allow httpd to connect to zabbix.
+* `selinux_allow_httpd_can_connect_ldap`: Default: `false`. Set SELinux boolean to allow httpd to connect to LDAP.
+* `selinux_allow_httpd_can_network_connect_db`: Default: `false` Set SELinux boolean to allow httpd to connect databases over the network.
+
### Zabbix Server
* `zabbix_server_name`: The name of the Zabbix Server.
diff --git a/ansible_collections/community/zabbix/molecule/requirements.txt b/ansible_collections/community/zabbix/molecule/requirements.txt
index b7cbb1138..9ccb5e157 100644
--- a/ansible_collections/community/zabbix/molecule/requirements.txt
+++ b/ansible_collections/community/zabbix/molecule/requirements.txt
@@ -3,9 +3,9 @@ ansible==7.0.0
ansible-compat==3.0.0
ansible-core==2.14.2
docker==6.1.3
-molecule==4.0.4
-molecule-docker==2.1.0
-netaddr==0.8.0
+molecule<5
+molecule-docker @ git+https://github.com/ansible-community/molecule-docker@main
+netaddr==1.2.1
pytest==7.2.1
pytest-testinfra==7.0.0
ipaddr==2.2.0
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_agent_tests/common/playbooks/prepare.yml b/ansible_collections/community/zabbix/molecule/zabbix_agent_tests/common/playbooks/prepare.yml
index cf1100aab..2ad8efa3f 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_agent_tests/common/playbooks/prepare.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_agent_tests/common/playbooks/prepare.yml
@@ -47,6 +47,7 @@
hosts: docker
tasks:
- name: "Download Docker CE repo file"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
url: https://download.docker.com/linux/centos/docker-ce.repo
dest: /etc/yum.repos.d/docker-ce.repo
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_javagateway/molecule.yml b/ansible_collections/community/zabbix/molecule/zabbix_javagateway/molecule.yml
index ee072707d..0c6de4172 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_javagateway/molecule.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_javagateway/molecule.yml
@@ -3,7 +3,7 @@ driver:
name: docker
platforms:
- - name: zabbix-server-${MY_MOLECULE_CONTAINER:-centos}
+ - name: zabbix-server-${MY_MOLECULE_VERSION:-v64}-${MY_MOLECULE_DATABASE:-mysql}-${MY_MOLECULE_CONTAINER:-rockylinux8}
image: geerlingguy/docker-${MY_MOLECULE_IMAGE:-rockylinux8}-ansible:latest
privileged: true
pre_build_image: true
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_proxy/destroy.yml b/ansible_collections/community/zabbix/molecule/zabbix_proxy/destroy.yml
index 54771a5a1..7ef374be5 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_proxy/destroy.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_proxy/destroy.yml
@@ -17,9 +17,7 @@
- name: Destroy 3rd party instance(s)
docker_container:
- name: '{{ item }}'
+ name: "{{ item.name }}-db"
state: absent
force_kill: true
- with_items:
- - mysql-host
- - postgresql-host
+ loop: "{{ molecule_yml.platforms }}"
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_proxy/molecule.yml b/ansible_collections/community/zabbix/molecule/zabbix_proxy/molecule.yml
index 4eb173acf..4eadd60ab 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_proxy/molecule.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_proxy/molecule.yml
@@ -2,7 +2,7 @@
driver:
name: docker
platforms:
- - name: zabbix-proxy-${MY_MOLECULE_CONTAINER:-centos}
+ - name: zabbix-proxy-${MY_MOLECULE_VERSION:-v64}-${MY_MOLECULE_DATABASE:-mysql}-${MY_MOLECULE_CONTAINER:-rockylinux8}
image: geerlingguy/docker-${MY_MOLECULE_IMAGE:-rockylinux8}-ansible:latest
privileged: true
pre_build_image: true
@@ -37,19 +37,19 @@ provisioner:
zabbix_proxy_dbuser: zabbix-dbuser
zabbix_proxy_database: mysql
zabbix_proxy_dbport: 3306
- zabbix_proxy_dbhost: mysql-host
+ zabbix_proxy_dbhost: "{{ inventory_hostname }}-db"
zabbix_proxy_dbhost_run_install: false
zabbix_proxy_privileged_host: "%"
- zabbix_proxy_mysql_login_host: mysql-host
+ zabbix_proxy_mysql_login_host: "{{ inventory_hostname }}-db"
zabbix_proxy_mysql_login_user: root
zabbix_proxy_mysql_login_password: changeme
zabbix_proxy_mysql_login_port: 3306
pgsql:
zabbix_proxy_database: pgsql
zabbix_proxy_dbport: 5432
- zabbix_proxy_dbhost: postgresql-host
+ zabbix_proxy_dbhost: "{{ inventory_hostname }}-db"
zabbix_proxy_dbhost_run_install: false
- zabbix_proxy_pgsql_login_host: postgresql-host
+ zabbix_proxy_pgsql_login_host: "{{ inventory_hostname }}-db"
zabbix_proxy_pgsql_login_user: postgres
zabbix_proxy_pgsql_login_password: changeme
zabbix_proxy_pgsql_login_port: 5432
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_proxy/prepare.yml b/ansible_collections/community/zabbix/molecule/zabbix_proxy/prepare.yml
index c5e3b9e45..1ff492d62 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_proxy/prepare.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_proxy/prepare.yml
@@ -5,7 +5,7 @@
pre_tasks:
- name: "Create MySQL Container"
docker_container:
- name: mysql-host
+ name: "{{ item.name }}-db"
image: mysql:8.0
state: started
recreate: true
@@ -20,7 +20,7 @@
- name: "Create postgresql Container"
docker_container:
- name: postgresql-host
+ name: "{{ item.name }}-db"
image: postgres:13
state: started
recreate: true
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_server/destroy.yml b/ansible_collections/community/zabbix/molecule/zabbix_server/destroy.yml
index 54771a5a1..7ef374be5 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_server/destroy.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_server/destroy.yml
@@ -17,9 +17,7 @@
- name: Destroy 3rd party instance(s)
docker_container:
- name: '{{ item }}'
+ name: "{{ item.name }}-db"
state: absent
force_kill: true
- with_items:
- - mysql-host
- - postgresql-host
+ loop: "{{ molecule_yml.platforms }}"
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_server/molecule.yml b/ansible_collections/community/zabbix/molecule/zabbix_server/molecule.yml
index 2424455f4..52df5ac4e 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_server/molecule.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_server/molecule.yml
@@ -2,7 +2,7 @@
driver:
name: docker
platforms:
- - name: zabbix-server-${MY_MOLECULE_CONTAINER:-centos}
+ - name: zabbix-server-${MY_MOLECULE_VERSION:-v64}-${MY_MOLECULE_DATABASE:-mysql}-${MY_MOLECULE_CONTAINER:-rockylinux8}
image: geerlingguy/docker-${MY_MOLECULE_IMAGE:-rockylinux8}-ansible:latest
privileged: true
pre_build_image: true
@@ -40,19 +40,19 @@ provisioner:
zabbix_server_dbuser: zabbix-dbuser
zabbix_server_database: mysql
zabbix_server_dbport: 3306
- zabbix_server_dbhost: mysql-host
+ zabbix_server_dbhost: "{{ inventory_hostname }}-db"
zabbix_server_dbhost_run_install: false
zabbix_server_privileged_host: "%"
- zabbix_server_mysql_login_host: mysql-host
+ zabbix_server_mysql_login_host: "{{ inventory_hostname }}-db"
zabbix_server_mysql_login_user: root
zabbix_server_mysql_login_password: changeme
zabbix_server_mysql_login_port: 3306
pgsql:
zabbix_server_database: pgsql
zabbix_server_dbport: 5432
- zabbix_server_dbhost: postgresql-host
+ zabbix_server_dbhost: "{{ inventory_hostname }}-db"
zabbix_server_dbhost_run_install: false
- zabbix_server_pgsql_login_host: postgresql-host
+ zabbix_server_pgsql_login_host: "{{ inventory_hostname }}-db"
zabbix_server_pgsql_login_user: postgres
zabbix_server_pgsql_login_password: changeme
zabbix_server_pgsql_login_port: 5432
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_server/prepare.yml b/ansible_collections/community/zabbix/molecule/zabbix_server/prepare.yml
index 922b33753..725e6d718 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_server/prepare.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_server/prepare.yml
@@ -5,7 +5,7 @@
pre_tasks:
- name: "Create MySQL Container"
docker_container:
- name: mysql-host
+ name: "{{ item.name }}-db"
image: mysql:8.0.32
state: started
recreate: true
@@ -20,7 +20,7 @@
- name: "Create postgresql Container"
docker_container:
- name: postgresql-host
+ name: "{{ item.name }}-db"
image: postgres:13
state: started
recreate: true
@@ -109,11 +109,3 @@
state: absent
when:
- ansible_os_family == 'RedHat'
-
- - name: PyMySQL
- ansible.builtin.pip:
- name: PyMySQL
- register: installation_dependencies
- until: installation_dependencies is succeeded
- when:
- - inventory_hostname in groups['mysql']
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_web/destroy.yml b/ansible_collections/community/zabbix/molecule/zabbix_web/destroy.yml
index 54771a5a1..7ef374be5 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_web/destroy.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_web/destroy.yml
@@ -17,9 +17,7 @@
- name: Destroy 3rd party instance(s)
docker_container:
- name: '{{ item }}'
+ name: "{{ item.name }}-db"
state: absent
force_kill: true
- with_items:
- - mysql-host
- - postgresql-host
+ loop: "{{ molecule_yml.platforms }}"
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_web/molecule.yml b/ansible_collections/community/zabbix/molecule/zabbix_web/molecule.yml
index 0aa3ab800..549b7ae16 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_web/molecule.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_web/molecule.yml
@@ -10,7 +10,7 @@ dependency:
driver:
name: docker
platforms:
- - name: zabbix-web-${MY_MOLECULE_CONTAINER:-centos}
+ - name: zabbix-web-${MY_MOLECULE_VERSION:-v64}-${MY_MOLECULE_DATABASE:-mysql}-${MY_MOLECULE_CONTAINER:-rockylinux8}
image: geerlingguy/docker-${MY_MOLECULE_IMAGE:-rockylinux8}-ansible:latest
privileged: true
pre_build_image: true
@@ -33,7 +33,7 @@ provisioner:
inventory:
group_vars:
all:
- zabbix_api_server_url: zabbix-web-${MY_MOLECULE_CONTAINER:-centos}
+ zabbix_api_server_url: zabbix-web-${MY_MOLECULE_VERSION:-v64}-${MY_MOLECULE_DATABASE:-mysql}-${MY_MOLECULE_CONTAINER:-rockylinux8}
python3:
ansible_python_interpreter: /usr/bin/python3
python:
@@ -50,19 +50,19 @@ provisioner:
mysql:
zabbix_server_database: mysql
zabbix_server_dbport: 3306
- zabbix_server_dbhost: mysql-host
+ zabbix_server_dbhost: "{{ inventory_hostname }}-db"
zabbix_server_dbhost_run_install: false
zabbix_server_privileged_host: "%"
- zabbix_server_mysql_login_host: mysql-host
+ zabbix_server_mysql_login_host: "{{ inventory_hostname }}-db"
zabbix_server_mysql_login_user: root
zabbix_server_mysql_login_password: changeme
zabbix_server_mysql_login_port: 3306
pgsql:
zabbix_server_database: pgsql
zabbix_server_dbport: 5432
- zabbix_server_dbhost: postgresql-host
+ zabbix_server_dbhost: "{{ inventory_hostname }}-db"
zabbix_server_dbhost_run_install: false
- zabbix_server_pgsql_login_host: postgresql-host
+ zabbix_server_pgsql_login_host: "{{ inventory_hostname }}-db"
zabbix_server_pgsql_login_user: postgres
zabbix_server_pgsql_login_password: changeme
zabbix_server_pgsql_login_port: 5432
diff --git a/ansible_collections/community/zabbix/molecule/zabbix_web/prepare.yml b/ansible_collections/community/zabbix/molecule/zabbix_web/prepare.yml
index 204eb8f56..d3dcc1ad0 100644
--- a/ansible_collections/community/zabbix/molecule/zabbix_web/prepare.yml
+++ b/ansible_collections/community/zabbix/molecule/zabbix_web/prepare.yml
@@ -5,7 +5,7 @@
pre_tasks:
- name: "Create MySQL Container"
docker_container:
- name: mysql-host
+ name: "{{ item.name }}-db"
image: mysql:8.0
state: started
recreate: true
@@ -20,7 +20,7 @@
- name: "Create postgresql Container"
docker_container:
- name: postgresql-host
+ name: "{{ item.name }}-db"
image: postgres:13
state: started
recreate: true
diff --git a/ansible_collections/community/zabbix/plugins/httpapi/zabbix.py b/ansible_collections/community/zabbix/plugins/httpapi/zabbix.py
index 56ba0356d..2a8d8a8ae 100644
--- a/ansible_collections/community/zabbix/plugins/httpapi/zabbix.py
+++ b/ansible_collections/community/zabbix/plugins/httpapi/zabbix.py
@@ -29,7 +29,8 @@ options:
zabbix_url_path:
type: str
description:
- - Specifies path portion in Zabbix WebUI URL, e.g. for https://myzabbixfarm.com/zabbixeu zabbix_url_path=zabbixeu
+ - Specifies path portion in Zabbix WebUI URL, e.g. for https://myzabbixfarm.com/zabbixeu zabbix_url_path=zabbixeu.
+ - "If Zabbix WebUI is running at the root, i.e. https://myzabbixfarm.com/, then assign empty string to this variable C(zabbix_url_path: '')."
default: zabbix
env:
- name: ANSIBLE_ZABBIX_URL_PATH
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_correlation.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_correlation.py
new file mode 100644
index 000000000..952ef49d0
--- /dev/null
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_correlation.py
@@ -0,0 +1,587 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright: (c) 2024, ONODERA Masaru <masaru-onodera@ieee.org>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+---
+module: zabbix_correlation
+
+short_description: Create/update/delete Zabbix correlation
+
+
+description:
+ - This module allows you to create, update and delete Zabbix correlation.
+
+author:
+ - ONODERA Masaru(@masa-orca)
+
+requirements:
+ - "python >= 3.9"
+
+version_added: 2.4.0
+
+options:
+ name:
+ description:
+ - Name of this correlation
+ type: str
+ required: true
+ description:
+ description:
+ - Description of this correlation
+ type: str
+ operations:
+ description:
+ - A operations.
+ type: list
+ elements: dict
+ suboptions:
+ type:
+ description:
+ - Type of the operation.
+ type: str
+ choices:
+ - close_old_events
+ - close_new_event
+ required: true
+ filter:
+ description:
+ - A filter.
+ type: dict
+ suboptions:
+ evaltype:
+ description:
+ - An evaluation method of the filter.
+ type: str
+ choices:
+ - and_or
+ - and
+ - or
+ - custom_expression
+ required: true
+ conditions:
+ description:
+ - A condition.
+ type: list
+ elements: dict
+ required: true
+ suboptions:
+ type:
+ description:
+ - Type of the condition.
+ type: str
+ choices:
+ - old_event_tag
+ - new_event_tag
+ - new_event_host_group
+ - event_tag_pair
+ - old_event_tag_value
+ - new_event_tag_value
+ required: true
+ tag:
+ description:
+ - Event tag (old or new).
+ - This parameter is required if value of I(type) of the condition is C(old_event_tag), C(new_event_tag),
+ C(old_event_tag_value) or C(new_event_tag_value).
+ type: str
+ hostgroup:
+ description:
+ - A name of hostgroup name
+ - This parameter is required if value of I(type) of the condition is C(new_event_host_group).
+ type: str
+ oldtag:
+ description:
+ - Old event tag.
+ - This parameter is required if value of I(type) of the condition is C(event_tag_pair).
+ type: str
+ newtag:
+ description:
+ - New event tag.
+ - This parameter is required if value of I(type) of the condition is C(event_tag_pair).
+ type: str
+ value:
+ description:
+ - Event tag (old or new) value.
+ - This parameter is required if value of I(type) of the condition is C(old_event_tag_value) or C(new_event_tag_value).
+ type: str
+ formulaid:
+ description:
+ - Arbitrary unique ID that is used to reference the condition from a custom expression.
+ - This parameter's value must be only contain capital-case letters.
+ - This parameter is required if value of I(evaltype) of the filter is C(custom_expression).
+ type: str
+ operator:
+ description:
+ - Condition operator.
+ - This parameter is required if value of I(type) of the condition is C(new_event_host_group),
+ C(old_event_tag_value) or C(new_event_tag_value).
+ - You can only select C(equal) or C(not_equal) if value of I(type) of the condition is C(new_event_host_group).
+ type: str
+ choices:
+ - equal
+ - not_equal
+ - like
+ - not_like
+ formula:
+ description:
+ - A custom expression for the filter.
+ - This parameter is required if value of I(evaltype) is C(custom_expression).
+ type: str
+ status:
+ description:
+ - Status of the correlation.
+ choices:
+ - enabled
+ - disabled
+ default: enabled
+ type: str
+ state:
+ description:
+ - State of the correlation.
+ type: str
+ choices:
+ - present
+ - absent
+ default: present
+
+extends_documentation_fragment:
+ - community.zabbix.zabbix
+
+"""
+
+EXAMPLES = """
+# If you want to use Username and Password to be authenticated by Zabbix Server
+- name: Set credentials to access Zabbix Server API
+ ansible.builtin.set_fact:
+ ansible_user: Admin
+ ansible_httpapi_pass: zabbix
+
+# If you want to use API token to be authenticated by Zabbix Server
+# https://www.zabbix.com/documentation/current/en/manual/web_interface/frontend_sections/administration/general#api-tokens
+- name: Set API token
+ ansible.builtin.set_fact:
+ ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895
+
+- name: Create correlation of 'New event tag correlation'
+ # set task level variables as we change ansible_connection plugin here
+ vars:
+ ansible_network_os: community.zabbix.zabbix
+ ansible_connection: httpapi
+ ansible_httpapi_port: 443
+ ansible_httpapi_use_ssl: true
+ ansible_httpapi_validate_certs: false
+ ansible_zabbix_url_path: 'zabbixeu' # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
+ ansible_host: zabbix-example-fqdn.org
+ community.zabbix.zabbix_correlation:
+ name: New event tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_tag
+ tag: ok
+ operations:
+ - type: close_old_events
+"""
+
+RETURN = """
+msg:
+ description: The result of the operation
+ returned: success
+ type: str
+ sample: 'Successfully created correlation'
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase
+import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils
+
+
+class Correlation(ZabbixBase):
+ def __init__(self, module, zbx=None, zapi_wrapper=None):
+ super(Correlation, self).__init__(module, zbx, zapi_wrapper)
+
+ def get_correlations(self, correlation_name):
+ try:
+ regexps = self._zapi.correlation.get(
+ {
+ "output": "extend",
+ "selectFilter": "extend",
+ "selectOperations": "extend",
+ "filter": {"name": correlation_name},
+ }
+ )
+ if len(regexps) >= 2:
+ self._module.fail_json("Too many correlations are matched.")
+ return regexps
+ except Exception as e:
+ self._module.fail_json(
+ msg="Failed to get correlation: %s" % e
+ )
+
+ def delete_correlation(self, correlation):
+ try:
+ parameter = [correlation["correlationid"]]
+ if self._module.check_mode:
+ self._module.exit_json(changed=True)
+ self._zapi.correlation.delete(parameter)
+ self._module.exit_json(
+ changed=True, msg="Successfully deleted correlation."
+ )
+ except Exception as e:
+ self._module.fail_json(
+ msg="Failed to delete correlation: %s" % e
+ )
+
+ def _convert_operations_to_json(self, operations):
+ operation_type_values = ["close_old_events", "close_new_event"]
+
+ operations_json = []
+ for operation in operations:
+ operation_json = {}
+ operation_type = zabbix_utils.helper_to_numeric_value(
+ operation_type_values, operation["type"]
+ )
+ operation_json["type"] = str(operation_type)
+ operations_json.append(operation_json)
+
+ return operations_json
+
+ def _get_groupid_from_name(self, hostgroup):
+ groupid = self._zapi.hostgroup.get({"filter": {"name": hostgroup}})
+ if not groupid or len(groupid) > 1:
+ self._module.fail_json("Host group '%s' cannot be found" % hostgroup)
+ return groupid[0]["groupid"]
+
+ def _convert_conditions_to_json(self, filter_parameter):
+ condition_type_values = [
+ "old_event_tag",
+ "new_event_tag",
+ "new_event_host_group",
+ "event_tag_pair",
+ "old_event_tag_value",
+ "new_event_tag_value"
+ ]
+
+ operator_values = [
+ "equal",
+ "not_equal",
+ "like",
+ "not_like"
+ ]
+
+ conditions_json = []
+ for condition in filter_parameter["conditions"]:
+ condition_json = {}
+
+ condition_type = zabbix_utils.helper_to_numeric_value(
+ condition_type_values, condition["type"]
+ )
+ condition_json["type"] = str(condition_type)
+
+ if condition["tag"] is not None:
+ condition_json["tag"] = condition["tag"]
+
+ if condition["hostgroup"] is not None:
+ condition_json["groupid"] = self._get_groupid_from_name(condition["hostgroup"])
+
+ if condition["oldtag"] is not None:
+ condition_json["oldtag"] = condition["oldtag"]
+
+ if condition["newtag"] is not None:
+ condition_json["newtag"] = condition["newtag"]
+
+ if condition["value"] is not None:
+ condition_json["value"] = condition["value"]
+
+ if filter_parameter["evaltype"] == "custom_expression":
+ if condition["formulaid"] is not None:
+ if not condition["formulaid"].isupper():
+ self._module.fail_json(
+ "A value of formulaid must be uppercase."
+ )
+ condition_json["formulaid"] = condition["formulaid"]
+ else:
+ self._module.fail_json(
+ "formulaid must be defined if evaltype is 'custom_expression'."
+ )
+ else:
+ if condition["formulaid"] is not None:
+ self._module.warn(
+ "A value of formulaid will be ignored because evaltype is not 'custom_expression'."
+ )
+
+ if condition["operator"] is not None:
+ if (condition["type"] == "new_event_host_group"
+ and (condition["operator"] == "like" or condition["operator"] == "not_like")):
+ self._module.fail_json(
+ "A value of operator must be equal or not_equal when condition's type is 'new_event_host_group'."
+ )
+ operator = zabbix_utils.helper_to_numeric_value(
+ operator_values, condition["operator"]
+ )
+ condition_json["operator"] = str(operator)
+
+ conditions_json.append(condition_json)
+ return conditions_json
+
+ def _convert_filter_parameter_to_json(self, filter_parameter):
+ evaltype_values = [
+ "and_or",
+ "and",
+ "or",
+ "custom_expression"
+ ]
+
+ filter_parameter_json = {}
+
+ evaltype = zabbix_utils.helper_to_numeric_value(
+ evaltype_values, filter_parameter["evaltype"]
+ )
+ filter_parameter_json["evaltype"] = str(evaltype)
+
+ filter_parameter_json["conditions"] = self._convert_conditions_to_json(filter_parameter)
+
+ if filter_parameter["formula"] is not None:
+ if filter_parameter["evaltype"] == "custom_expression":
+ filter_parameter_json["formula"] = filter_parameter["formula"]
+ else:
+ self._module.warn(
+ "A value of formula will be ignored because evaltype is not 'custom_expression'."
+ )
+
+ return filter_parameter_json
+
+ def create_correlation(self, name, description, operations, filter_parameter, status):
+ status_values = ["enabled", "disabled"]
+ status_json = zabbix_utils.helper_to_numeric_value(
+ status_values, status
+ )
+
+ try:
+ correlation_json = {}
+
+ correlation_json["name"] = name
+
+ if description is not None:
+ correlation_json["description"] = description
+
+ correlation_json["operations"] = self._convert_operations_to_json(operations)
+
+ correlation_json["filter"] = self._convert_filter_parameter_to_json(filter_parameter)
+
+ correlation_json["status"] = status_json
+
+ if self._module.check_mode:
+ self._module.exit_json(changed=True)
+ self._zapi.correlation.create(correlation_json)
+ self._module.exit_json(
+ changed=True, msg="Successfully created correlation"
+ )
+ except Exception as e:
+ self._module.fail_json(
+ msg="Failed to create correlation: %s" % e
+ )
+
+ def check_filter_properties(self, current_filter, future_filter):
+ changed = False
+
+ if (current_filter["evaltype"] != future_filter["evaltype"]):
+ changed = True
+
+ if "formula" in future_filter.keys():
+ if (current_filter["eval_formula"] != future_filter["formula"]):
+ changed = True
+
+ for condition in current_filter["conditions"]:
+ # 3 means custom expression.
+ if current_filter["evaltype"] != "3":
+ condition.pop("formulaid")
+ diff_conditions = []
+ zabbix_utils.helper_compare_lists(current_filter["conditions"], future_filter["conditions"], diff_conditions)
+ if len(diff_conditions) != 0:
+ changed = True
+
+ return changed
+
+ def update_correlation(self, current_correlation, description, operations, filter_parameter, status):
+ status_values = ["enabled", "disabled"]
+ status_json = zabbix_utils.helper_to_numeric_value(
+ status_values, status
+ )
+
+ try:
+ correlation_json = {}
+
+ if description is not None and description != current_correlation["description"]:
+ correlation_json["description"] = description
+
+ if operations is not None:
+ future_operations = self._convert_operations_to_json(operations)
+ diff_operations = []
+ zabbix_utils.helper_compare_lists(current_correlation["operations"], future_operations, diff_operations)
+ if len(diff_operations) != 0:
+ correlation_json["operations"] = future_operations
+
+ if filter_parameter is not None:
+ future_filter = self._convert_filter_parameter_to_json(filter_parameter)
+ if self.check_filter_properties(current_correlation["filter"], future_filter):
+ correlation_json["filter"] = future_filter
+
+ if str(status_json) != current_correlation["status"]:
+ correlation_json["status"] = str(status_json)
+
+ if len(correlation_json.keys()) == 0:
+ self._module.exit_json(changed=False)
+ else:
+ correlation_json["correlationid"] = current_correlation["correlationid"]
+ if self._module.check_mode:
+ self._module.exit_json(changed=True)
+ self._zapi.correlation.update(correlation_json)
+ self._module.exit_json(
+ changed=True, msg="Successfully updated correlation"
+ )
+ except Exception as e:
+ self._module.fail_json(
+ msg="Failed to update correlation: %s" % e
+ )
+
+
+def main():
+ """Main ansible module function"""
+
+ argument_spec = zabbix_utils.zabbix_common_argument_spec()
+ argument_spec.update(
+ dict(
+ name=dict(type="str", required=True),
+ description=dict(type="str"),
+ operations=dict(
+ type="list",
+ elements="dict",
+ options=dict(
+ type=dict(
+ choices=["close_old_events", "close_new_event"],
+ required=True
+ )
+ )
+ ),
+ filter=dict(
+ type="dict",
+ options=dict(
+ evaltype=dict(
+ type="str",
+ required=True,
+ choices=[
+ "and_or",
+ "and",
+ "or",
+ "custom_expression"
+ ]
+ ),
+ conditions=dict(
+ required=True,
+ type="list",
+ elements="dict",
+ options=dict(
+ type=dict(
+ type="str",
+ required=True,
+ choices=[
+ "old_event_tag",
+ "new_event_tag",
+ "new_event_host_group",
+ "event_tag_pair",
+ "old_event_tag_value",
+ "new_event_tag_value"
+ ]
+ ),
+ tag=dict(type="str"),
+ hostgroup=dict(type="str"),
+ oldtag=dict(type="str"),
+ newtag=dict(type="str"),
+ value=dict(type="str"),
+ formulaid=dict(type="str"),
+ operator=dict(
+ type="str",
+ choices=[
+ "equal",
+ "not_equal",
+ "like",
+ "not_like"
+ ]
+ ),
+ ),
+ required_if=[
+ ["type", "old_event_tag", ["tag"]],
+ ["type", "new_event_tag", ["tag"]],
+ ["type", "new_event_host_group", ["hostgroup", "operator"]],
+ ["type", "event_tag_pair", ["oldtag", "newtag"]],
+ ["type", "old_event_tag_value", ["tag", "value", "operator"]],
+ ["type", "new_event_tag_value", ["tag", "value", "operator"]]
+ ],
+ mutually_exclusive=[
+ ("tag", "hostgroup", "oldtag")
+ ],
+ required_together=[
+ ('oldtag', 'newtag')
+ ]
+ ),
+ formula=dict(type="str"),
+ ),
+ required_if=[
+ ["evaltype", "custom_expression", ["formula"]],
+ ]
+ ),
+ status=dict(
+ type="str",
+ required=False,
+ default="enabled",
+ choices=["enabled", "disabled"],
+ ),
+ state=dict(
+ type="str",
+ required=False,
+ default="present",
+ choices=["present", "absent"],
+ )
+ )
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ )
+
+ name = module.params["name"]
+ description = module.params["description"]
+ operations = module.params["operations"]
+ filter_parameter = module.params["filter"]
+ status = module.params["status"]
+ state = module.params["state"]
+
+ correlation_class_obj = Correlation(module)
+ correlations = correlation_class_obj.get_correlations(name)
+
+ if state == "absent":
+ if len(correlations) == 1:
+ correlation_class_obj.delete_correlation(correlations[0])
+ else:
+ module.exit_json(changed=False)
+ else:
+ if len(correlations) == 1:
+ correlation_class_obj.update_correlation(correlations[0], description, operations, filter_parameter, status)
+ else:
+ correlation_class_obj.create_correlation(name, description, operations, filter_parameter, status)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_host.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_host.py
index 22e14d17d..00c04c221 100644
--- a/ansible_collections/community/zabbix/plugins/modules/zabbix_host.py
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_host.py
@@ -513,7 +513,7 @@ class Host(ZabbixBase):
def update_host(self, host_name, group_ids, status, host_id, interfaces, exist_interface_list, proxy_id,
visible_name, description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer,
- tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host):
+ tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host, zabbix_host_obj):
try:
if self._module.check_mode:
self._module.exit_json(changed=True)
@@ -523,31 +523,31 @@ class Host(ZabbixBase):
else:
# A "plain" host
parameters = {"hostid": host_id, "groups": group_ids, "status": status}
- if proxy_id >= 0:
+ if (proxy_id >= 0 and proxy_id != zabbix_host_obj["proxy_hostid"]):
parameters["proxy_hostid"] = proxy_id
- if visible_name:
+ if (visible_name is not None and visible_name != zabbix_host_obj["name"]):
parameters["name"] = visible_name
- if tls_connect:
+ if (tls_connect is not None and tls_connect != zabbix_host_obj["tls_connect"]):
parameters["tls_connect"] = tls_connect
- if tls_accept:
+ if (tls_accept is not None and tls_accept != zabbix_host_obj["tls_accept"]):
parameters["tls_accept"] = tls_accept
if tls_psk_identity:
parameters["tls_psk_identity"] = tls_psk_identity
if tls_psk:
parameters["tls_psk"] = tls_psk
- if tls_issuer:
+ if (tls_issuer is not None and tls_issuer != zabbix_host_obj["tls_issuer"]):
parameters["tls_issuer"] = tls_issuer
- if tls_subject:
+ if (tls_subject is not None and tls_subject != zabbix_host_obj["tls_subject"]):
parameters["tls_subject"] = tls_subject
- if description:
+ if (description is not None and description != zabbix_host_obj["description"]):
parameters["description"] = description
- if ipmi_authtype:
+ if (ipmi_authtype is not None and ipmi_authtype != zabbix_host_obj["ipmi_authtype"]):
parameters["ipmi_authtype"] = ipmi_authtype
- if ipmi_privilege:
+ if (ipmi_privilege is not None and ipmi_privilege != zabbix_host_obj["ipmi_privilege"]):
parameters["ipmi_privilege"] = ipmi_privilege
- if ipmi_username:
+ if (ipmi_username is not None and ipmi_username != zabbix_host_obj["ipmi_username"]):
parameters["ipmi_username"] = ipmi_username
- if ipmi_password:
+ if (ipmi_password is not None and ipmi_password != zabbix_host_obj["ipmi_password"]):
parameters["ipmi_password"] = ipmi_password
if interfaces:
parameters["interfaces"] = interfaces
@@ -809,8 +809,7 @@ class Host(ZabbixBase):
return False
# link or clear template of the host
- def link_or_clear_template(self, host_id, template_id_list, tls_connect, tls_accept, tls_psk_identity, tls_psk,
- tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, discovered_host):
+ def link_or_clear_template(self, host_id, template_id_list):
# get host's exist template ids
exist_template_id_list = self.get_host_templates_by_host_id(host_id)
@@ -821,25 +820,7 @@ class Host(ZabbixBase):
# get unlink and clear templates
templates_clear = exist_template_ids.difference(template_ids)
templates_clear_list = list(templates_clear)
- if discovered_host:
- # The host was discovered via Discovery Rule
- request_str = {"hostid": host_id, "templates": template_id_list, "templates_clear": templates_clear_list}
- else:
- # A "plain" host
- request_str = {"hostid": host_id, "templates": template_id_list, "templates_clear": templates_clear_list,
- "ipmi_authtype": ipmi_authtype, "ipmi_privilege": ipmi_privilege, "ipmi_username": ipmi_username, "ipmi_password": ipmi_password}
- if tls_connect:
- request_str["tls_connect"] = tls_connect
- if tls_accept:
- request_str["tls_accept"] = tls_accept
- if tls_psk_identity is not None:
- request_str["tls_psk_identity"] = tls_psk_identity
- if tls_psk is not None:
- request_str["tls_psk"] = tls_psk
- if tls_issuer is not None:
- request_str["tls_issuer"] = tls_issuer
- if tls_subject is not None:
- request_str["tls_subject"] = tls_subject
+ request_str = {"hostid": host_id, "templates": template_id_list, "templates_clear": templates_clear_list}
try:
if self._module.check_mode:
self._module.exit_json(changed=True)
@@ -1057,8 +1038,11 @@ def main():
group_ids = []
- if host_groups:
- group_ids = host.get_group_ids_by_group_names(host_groups)
+ if host_groups is not None:
+ if len(host_groups) >= 1:
+ group_ids = host.get_group_ids_by_group_names(host_groups)
+ else:
+ module.fail_json(msg="host_groups must be not empty list.")
interfaces, ip = host.construct_host_interfaces(interfaces)
@@ -1204,11 +1188,9 @@ def main():
host.update_host(
host_name, group_ids, status, host_id, interfaces, exist_interfaces, proxy_id, visible_name,
description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject,
- ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host)
+ ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host, zabbix_host_obj)
- host.link_or_clear_template(
- host_id, template_ids, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer,
- tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, discovered_host)
+ host.link_or_clear_template(host_id, template_ids)
host.update_inventory_mode(host_id, inventory_mode)
host.update_inventory_zabbix(host_id, inventory_zabbix)
@@ -1235,9 +1217,7 @@ def main():
tls_psk_identity, tls_psk, tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username,
ipmi_password, macros, tags)
- host.link_or_clear_template(
- host_id, template_ids, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject,
- ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, discovered_host)
+ host.link_or_clear_template(host_id, template_ids)
host.update_inventory_mode(host_id, inventory_mode)
host.update_inventory_zabbix(host_id, inventory_zabbix)
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_maintenance.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_maintenance.py
index a2c635eb0..ce10815df 100644
--- a/ansible_collections/community/zabbix/plugins/modules/zabbix_maintenance.py
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_maintenance.py
@@ -64,6 +64,20 @@ options:
- I(visible_name=yes) to search by visible name, I(visible_name=no) to search by technical name.
type: bool
default: "yes"
+ active_since:
+ description:
+ - Time when the maintenance becomes active.
+ - The given value will be rounded down to minutes.
+ - Uses `datetime.datetime.now(`) if not specified.
+ type: "str"
+ default: ""
+ active_till:
+ description:
+ - Time when the maintenance stops being active.
+ - The given value will be rounded down to minutes.
+ - Gets calculated from I(minutes) if not specified.
+ type: "str"
+ default: ""
tags:
description:
- List of tags to assign to the hosts in maintenance.
@@ -187,6 +201,24 @@ EXAMPLES = r"""
community.zabbix.zabbix_maintenance:
name: Test1
state: absent
+
+- name: Create maintenance window by date
+ # set task level variables as we change ansible_connection plugin here
+ vars:
+ ansible_network_os: community.zabbix.zabbix
+ ansible_connection: httpapi
+ ansible_httpapi_port: 443
+ ansible_httpapi_use_ssl: true
+ ansible_httpapi_validate_certs: false
+ ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
+ ansible_host: zabbix-example-fqdn.org
+ community.zabbix.zabbix_maintenance:
+ name: TestDate
+ state: present
+ host_names:
+ - host.example.org
+ active_since: "1979-09-19 09:00"
+ active_till: "1979-09-19 17:00"
"""
import datetime
@@ -342,6 +374,8 @@ def main():
desc=dict(type="str", required=False, default="Created by Ansible"),
collect_data=dict(type="bool", required=False, default=True),
visible_name=dict(type="bool", required=False, default=True),
+ active_since=dict(type="str", required=False, default=""),
+ active_till=dict(type="str", required=False, default=""),
tags=dict(
type="list",
elements="dict",
@@ -368,6 +402,8 @@ def main():
desc = module.params["desc"]
collect_data = module.params["collect_data"]
visible_name = module.params["visible_name"]
+ active_since = module.params["active_since"]
+ active_till = module.params["active_till"]
tags = module.params["tags"]
if collect_data:
@@ -389,9 +425,9 @@ def main():
module.fail_json(
msg="At least one host_name or host_group must be defined for each created maintenance.")
- now = datetime.datetime.now().replace(second=0)
+ now = datetime.datetime.fromisoformat(active_since) if active_since != "" else datetime.datetime.now().replace(second=0)
start_time = int(time.mktime(now.timetuple()))
- period = 60 * int(minutes) # N * 60 seconds
+ period = int((datetime.datetime.fromisoformat(active_till) - now).total_seconds()) if active_till != "" else 60 * int(minutes) # N * 60 seconds
if host_groups:
(rc, group_ids, error) = maint.get_group_ids(host_groups)
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_mediatype.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_mediatype.py
index 1e2514bf3..34bb1db82 100644
--- a/ansible_collections/community/zabbix/plugins/modules/zabbix_mediatype.py
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_mediatype.py
@@ -155,6 +155,15 @@ options:
- SSL verify peer for SMTP.
- Can be specified when I(smtp_security=STARTTLS) or I(smtp_security=SSL/TLS)
default: false
+ content_type:
+ type: "str"
+ description:
+ - Can be used when I(type=email).
+ - Message format.
+ choices:
+ - plaintext
+ - html
+ default: html
message_text_limit:
type: "str"
description:
@@ -525,6 +534,7 @@ class MediaTypeModule(ZabbixBase):
smtp_authentication=truths.get(str(self._module.params["smtp_authentication"])),
smtp_verify_host=truths.get(str(self._module.params["smtp_verify_host"])),
smtp_verify_peer=truths.get(str(self._module.params["smtp_verify_peer"])),
+ content_type={"plaintext": "0", "html": "1"}.get(str(self._module.params["content_type"])),
username=self._module.params["username"],
passwd=self._module.params["password"]
))
@@ -693,6 +703,7 @@ def main():
smtp_authentication=dict(type="bool", default=False, required=False),
smtp_verify_host=dict(type="bool", default=False, required=False),
smtp_verify_peer=dict(type="bool", default=False, required=False),
+ content_type=dict(type="str", choices=["plaintext", "html"], default="html", required=False),
# EZ Text
message_text_limit=dict(type="str", required=False, choices=["USA", "Canada"]),
# Webhook
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_service_info.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_service_info.py
new file mode 100644
index 000000000..1984777d3
--- /dev/null
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_service_info.py
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2021, D3DeFi
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: zabbix_service_info
+short_description: Gather information about Zabbix service
+author:
+ - Kanstantsin Maksimau (@us3241)
+description:
+ - This module allows you to obtain detailed information about configured zabbix service.
+requirements:
+ - "python >= 3.9"
+options:
+ service_name:
+ description:
+ - Name of the Zabbix service.
+ required: true
+ type: str
+extends_documentation_fragment:
+- community.zabbix.zabbix
+
+"""
+
+EXAMPLES = """
+# If you want to use Username and Password to be authenticated by Zabbix Server
+- name: Set credentials to access Zabbix Server API
+ ansible.builtin.set_fact:
+ ansible_user: Admin
+ ansible_httpapi_pass: zabbix
+
+# If you want to use API token to be authenticated by Zabbix Server
+# https://www.zabbix.com/documentation/current/en/manual/web_interface/frontend_sections/administration/general#api-tokens
+- name: Set API token
+ ansible.builtin.set_fact:
+ ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895
+
+- name: Get zabbix service info
+ # set task level variables as we change ansible_connection plugin here
+ vars:
+ ansible_network_os: community.zabbix.zabbix
+ ansible_connection: httpapi
+ ansible_httpapi_port: 443
+ ansible_httpapi_use_ssl: true
+ ansible_httpapi_validate_certs: false
+ ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
+ ansible_host: zabbix-example-fqdn.org
+ community.zabbix.zabbix_service_info:
+ service_name: zbx01.example.com
+"""
+
+RETURN = """
+zabbix_service:
+ description: example
+ returned: always
+ type: dict
+ sample: {
+ "algorithm": "2",
+ "children": [
+ {
+ "algorithm": "0",
+ "created_at": "1712743194",
+ "description": "",
+ "name": "example children",
+ "propagation_rule": "0",
+ "propagation_value": "0",
+ "readonly": false,
+ "serviceid": "81",
+ "sortorder": "0",
+ "status": "-1",
+ "uuid": "ce6e1a3784a547b48ee6707f6e061102",
+ "weight": "0"
+ }
+ ],
+ "created_at": "1709717864",
+ "description": "",
+ "name": "example service",
+ "parents": [],
+ "problem_tags": [],
+ "propagation_rule": "0",
+ "propagation_value": "0",
+ "readonly": false,
+ "serviceid": "51",
+ "sortorder": "0",
+ "status": "-1",
+ "status_rules": [],
+ "tags": [],
+ "uuid": "420e48b363fe473c95288c817031447f",
+ "weight": "0"
+ }
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase
+import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils
+
+
+class Service(ZabbixBase):
+
+ def get_service(self, name):
+ result = {}
+ params = {
+ "filter": {
+ "name": name
+ },
+ "output": "extend",
+ "selectParents": "extend",
+ "selectTags": "extend",
+ "selectProblemTags": "extend",
+ "selectChildren": "extend",
+ "selectStatusRules": "extend"
+ }
+
+ try:
+ result = self._zapi.service.get(params)
+ except Exception as e:
+ self._module.fail_json(msg="Failed to get service information: %s" % e)
+
+ return result[0] if result else {}
+
+
+def main():
+ argument_spec = zabbix_utils.zabbix_common_argument_spec()
+ argument_spec.update(dict(
+ service_name=dict(type="str", required=True),
+ ))
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True
+ )
+
+ name = module.params["service_name"]
+
+ service = Service(module)
+ result = service.get_service(name)
+ module.exit_json(changed=False, zabbix_service=result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_template.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_template.py
index a773790aa..f2c19c33c 100644
--- a/ansible_collections/community/zabbix/plugins/modules/zabbix_template.py
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_template.py
@@ -33,17 +33,21 @@ options:
description:
- JSON dump of templates to import.
- Multiple templates can be imported this way.
- - Mutually exclusive with I(template_name) and I(template_xml).
+ - Mutually exclusive with I(template_name) and I(template_xml) and I(template_yaml).
required: false
type: json
template_xml:
description:
- XML dump of templates to import.
- Multiple templates can be imported this way.
- - You are advised to pass XML structure matching the structure used by your version of Zabbix server.
- - Custom XML structure can be imported as long as it is valid, but may not yield consistent idempotent
- results on subsequent runs.
- - Mutually exclusive with I(template_name) and I(template_json).
+ - Mutually exclusive with I(template_name) and I(template_json) and I(template_yaml).
+ required: false
+ type: str
+ template_yaml:
+ description:
+ - Context of exported templates file to import.
+ - Multiple templates can be imported this way.
+ - Mutually exclusive with I(template_name) and I(template_json) and I(template_xml).
required: false
type: str
template_groups:
@@ -288,7 +292,6 @@ RETURN = r"""
import json
import traceback
import re
-import xml.etree.ElementTree as ET
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
@@ -342,35 +345,84 @@ class Template(ZabbixBase):
self._zapi.template.create(new_template)
- def check_template_changed(self, template_ids, template_groups, link_templates, clear_templates,
- template_macros, template_tags, template_content, template_type):
- """Compares template parameters to already existing values if any are found.
+ def import_compare(self, template_content, template_type):
+ """template_content has same structure as Zabbix uses (e.g. it was optimally exported via Zabbix GUI or API)"""
- template_json - JSON structures are compared as deep sorted dictionaries,
- template_xml - XML structures are compared as strings, but filtered and formatted first,
- If none above is used, all the other arguments are compared to their existing counterparts
- retrieved from Zabbix API."""
changed = False
- # Compare filtered and formatted XMLs strings for any changes. It is expected that provided
- # XML has same structure as Zabbix uses (e.g. it was optimally exported via Zabbix GUI or API)
- if template_content is not None and template_type == "xml":
- existing_template = self.dump_template(template_ids, template_type="xml")
-
- if self.filter_xml_template(template_content) != self.filter_xml_template(existing_template):
- changed = True
+ if template_content is not None:
+ update_rules = {
+ "discoveryRules": {
+ "createMissing": True,
+ "updateExisting": True,
+ "deleteMissing": True
+ },
+ "graphs": {
+ "createMissing": True,
+ "updateExisting": True,
+ "deleteMissing": True
+ },
+ "host_groups": {
+ "createMissing": True
+ },
+ "httptests": {
+ "createMissing": True,
+ "updateExisting": True,
+ "deleteMissing": True
+ },
+ "items": {
+ "createMissing": True,
+ "updateExisting": True,
+ "deleteMissing": True
+ },
+ "templates": {
+ "createMissing": True,
+ "updateExisting": True
+ },
+ "template_groups": {
+ "createMissing": True
+ },
+ "templateLinkage": {
+ "createMissing": True
+ },
+ "templateScreens": {
+ "createMissing": True,
+ "updateExisting": True,
+ "deleteMissing": True
+ },
+ "triggers": {
+ "createMissing": True,
+ "updateExisting": True,
+ "deleteMissing": True
+ },
+ "valueMaps": {
+ "createMissing": True,
+ "updateExisting": True
+ }
+ }
- return changed
+ try:
+ update_rules["templateLinkage"]["deleteMissing"] = True
+ update_rules["templateDashboards"] = update_rules.pop("templateScreens")
+
+ # before Zabbix 6.2 host_groups and template_group are joined into groups parameter
+ if LooseVersion(self._zbx_api_version) < LooseVersion("6.2"):
+ update_rules["groups"] = {"createMissing": True}
+ update_rules.pop("host_groups", None)
+ update_rules.pop("template_groups", None)
+ importcompare = {"format": template_type, "source": template_content, "rules": update_rules}
+ compare_result = self._zapi.configuration.importcompare(importcompare)
+ if len(compare_result) != 0:
+ changed = True
+ return changed
+ except Exception as e:
+ self._module.fail_json(msg="Unable to compare template", details=to_native(e),
+ exception=traceback.format_exc())
+ def check_template_changed(self, template_ids, template_groups, link_templates, clear_templates,
+ template_macros, template_tags):
+ """Compare template with user provided all parameters via module options"""
+ changed = False
existing_template = self.dump_template(template_ids, template_type="json")
- # Compare JSON objects as deep sorted python dictionaries
- if template_content is not None and template_type == "json":
- parsed_template_json = self.load_json_template(template_content)
- if self.diff_template(parsed_template_json, existing_template):
- changed = True
-
- return changed
-
- # If neither template_json or template_xml were used, user provided all parameters via module options
if template_groups is not None:
if LooseVersion(self._zbx_api_version) >= LooseVersion("6.2"):
existing_groups = [g["name"] for g in existing_template["zabbix_export"]["template_groups"]]
@@ -451,81 +503,15 @@ class Template(ZabbixBase):
templateids_list = [t.get("templateid") for t in templateids]
self._zapi.template.delete(templateids_list)
- def ordered_json(self, obj):
- # Deep sort json dicts for comparison
- if isinstance(obj, dict):
- return sorted((k, self.ordered_json(v)) for k, v in obj.items())
- if isinstance(obj, list):
- return sorted(self.ordered_json(x) for x in obj)
- else:
- return obj
-
def dump_template(self, template_ids, template_type="json"):
template_ids_list = [t.get("templateid") for t in template_ids]
try:
dump = self._zapi.configuration.export({"format": template_type, "options": {"templates": template_ids_list}})
- if template_type == "xml":
- xmlroot = ET.fromstring(dump.encode("utf-8"))
- if PY2:
- return str(ET.tostring(xmlroot, encoding="utf-8"))
- else:
- return str(ET.tostring(xmlroot, encoding="utf-8").decode("utf-8"))
- else:
- return self.load_json_template(dump)
+ return self.load_json_template(dump)
except Exception as e:
self._module.fail_json(msg="Unable to export template: %s" % e)
- def diff_template(self, template_json_a, template_json_b):
- # Compare 2 zabbix templates and return True if they differ.
- template_json_a = self.filter_template(template_json_a)
- template_json_b = self.filter_template(template_json_b)
- if self.ordered_json(template_json_a) == self.ordered_json(template_json_b):
- return False
- return True
-
- def filter_template(self, template_json):
- # Filter the template json to contain only the keys we will update
- keep_keys = set(["graphs", "templates", "triggers", "value_maps"])
- unwanted_keys = set(template_json["zabbix_export"]) - keep_keys
- for unwanted_key in unwanted_keys:
- del template_json["zabbix_export"][unwanted_key]
-
- # Versions older than 2.4 do not support description field within template
- desc_not_supported = False
-
- # Filter empty attributes from template object to allow accurate comparison
- for template in template_json["zabbix_export"]["templates"]:
- for key in list(template.keys()):
- if not template[key] or (key == "description" and desc_not_supported):
- template.pop(key)
-
- return template_json
-
- def filter_xml_template(self, template_xml):
- """Filters out keys from XML template that may wary between exports (e.g date or version) and
- keys that are not imported via this module.
-
- It is advised that provided XML template exactly matches XML structure used by Zabbix"""
- # Strip last new line and convert string to ElementTree
- parsed_xml_root = self.load_xml_template(template_xml.strip())
- keep_keys = ["graphs", "templates", "triggers", "value_maps"]
-
- # Remove unwanted XML nodes
- for node in list(parsed_xml_root):
- if node.tag not in keep_keys:
- parsed_xml_root.remove(node)
-
- # Filter empty attributes from template objects to allow accurate comparison
- for template in list(parsed_xml_root.find("templates")):
- for element in list(template):
- if element.text is None and len(list(element)) == 0:
- template.remove(element)
-
- # Filter new lines and indentation
- xml_root_text = list(line.strip() for line in ET.tostring(parsed_xml_root, encoding="utf8", method="xml").decode().split("\n"))
- return "".join(xml_root_text)
-
def load_json_template(self, template_json):
try:
jsondoc = json.loads(template_json)
@@ -533,12 +519,6 @@ class Template(ZabbixBase):
except ValueError as e:
self._module.fail_json(msg="Invalid JSON provided", details=to_native(e), exception=traceback.format_exc())
- def load_xml_template(self, template_xml):
- try:
- return ET.fromstring(template_xml)
- except ET.ParseError as e:
- self._module.fail_json(msg="Invalid XML provided", details=to_native(e), exception=traceback.format_exc())
-
def import_template(self, template_content, template_type="json"):
if self._module.check_mode:
self._module.exit_json(changed=True)
@@ -624,6 +604,7 @@ def main():
template_name=dict(type="str", required=False),
template_json=dict(type="json", required=False),
template_xml=dict(type="str", required=False),
+ template_yaml=dict(type="str", required=False),
template_groups=dict(type="list", required=False, elements="str"),
link_templates=dict(type="list", required=False, elements="str"),
clear_templates=dict(type="list", required=False, elements="str"),
@@ -648,10 +629,10 @@ def main():
module = AnsibleModule(
argument_spec=argument_spec,
required_one_of=[
- ["template_name", "template_json", "template_xml"]
+ ["template_name", "template_json", "template_xml", "template_yaml"]
],
mutually_exclusive=[
- ["template_name", "template_json", "template_xml"]
+ ["template_name", "template_json", "template_xml", "template_yaml"]
],
required_if=[
["state", "absent", ["template_name"]]
@@ -662,6 +643,7 @@ def main():
template_name = module.params["template_name"]
template_json = module.params["template_json"]
template_xml = module.params["template_xml"]
+ template_yaml = module.params["template_yaml"]
template_groups = module.params["template_groups"]
link_templates = module.params["link_templates"]
clear_templates = module.params["clear_templates"]
@@ -673,23 +655,23 @@ def main():
# Identify template names for IDs retrieval
# Template names are expected to reside in ["zabbix_export"]["templates"][*]["template"] for both data types
- template_content, template_type = None, None
+ template_content, template_type, template_ids = None, None, None
+
if template_json is not None:
template_type = "json"
template_content = template_json
- json_parsed = template.load_json_template(template_content)
- template_names = list(t["template"] for t in json_parsed["zabbix_export"]["templates"])
elif template_xml is not None:
template_type = "xml"
template_content = template_xml
- xml_parsed = template.load_xml_template(template_content)
- template_names = list(t.find("template").text for t in list(xml_parsed.find("templates")))
+
+ elif template_yaml is not None:
+ template_type = "yaml"
+ template_content = template_yaml
else:
template_names = [template_name]
-
- template_ids = template.get_template_ids(template_names)
+ template_ids = template.get_template_ids(template_names)
if state == "absent":
if not template_ids:
@@ -699,58 +681,63 @@ def main():
module.exit_json(changed=True, result="Successfully deleted template %s" % template_name)
elif state == "present":
- # Load all subelements for template that were provided by user
- group_ids = None
- if template_groups is not None:
- group_ids = template.get_group_ids_by_group_names(template_groups)
-
- link_template_ids = None
- if link_templates is not None:
- link_template_ids = template.get_template_ids(link_templates)
-
- clear_template_ids = None
- if clear_templates is not None:
- clear_template_ids = template.get_template_ids(clear_templates)
-
- if template_macros is not None:
- # Zabbix configuration.export does not differentiate python types (numbers are returned as strings)
- for macroitem in template_macros:
- for key in macroitem:
- macroitem[key] = str(macroitem[key])
-
- if template_tags is not None:
- for tagitem in template_tags:
- for key in tagitem:
- tagitem[key] = str(tagitem[key])
-
- if not template_ids:
- # Assume new templates are being added when no ID"s were found
- if template_content is not None:
- template.import_template(template_content, template_type)
- module.exit_json(changed=True, result="Template import successful")
-
+ if template_content is not None:
+ changed = template.import_compare(template_content, template_type)
+ if not changed:
+ module.exit_json(changed=changed, result="Template is up-to date")
else:
+ if module.check_mode:
+ module.exit_json(changed=changed)
+ template.import_template(template_content, template_type)
+ module.exit_json(changed=changed, result="Template import successful")
+ else:
+ # Load all subelements for template that were provided by user
+ group_ids = None
+ if template_groups is not None:
+ group_ids = template.get_group_ids_by_group_names(template_groups)
+
+ link_template_ids = None
+ if link_templates is not None:
+ link_template_ids = template.get_template_ids(link_templates)
+
+ clear_template_ids = None
+ if clear_templates is not None:
+ clear_template_ids = template.get_template_ids(clear_templates)
+
+ if template_macros is not None:
+ # Zabbix configuration.export does not differentiate python types (numbers are returned as strings)
+ for macroitem in template_macros:
+ for key in macroitem:
+ macroitem[key] = str(macroitem[key])
+
+ if template_tags is not None:
+ for tagitem in template_tags:
+ for key in tagitem:
+ tagitem[key] = str(tagitem[key])
+
+ if not template_ids:
+ # Assume new templates are being added when no ID"s were found
if group_ids is None:
module.fail_json(msg="template_groups are required when creating a new Zabbix template")
template.add_template(template_name, group_ids, link_template_ids, template_macros, template_tags)
module.exit_json(changed=True, result="Successfully added template: %s" % template_name)
- else:
- changed = template.check_template_changed(template_ids, template_groups, link_templates, clear_templates,
- template_macros, template_tags, template_content, template_type)
+ else:
+ changed = template.check_template_changed(template_ids, template_groups, link_templates, clear_templates,
+ template_macros, template_tags)
- if module.check_mode:
- module.exit_json(changed=changed)
+ if module.check_mode:
+ module.exit_json(changed=changed)
- if changed:
- if template_type is not None:
- template.import_template(template_content, template_type)
- else:
- template.update_template(template_ids, group_ids, link_template_ids, clear_template_ids,
- template_macros, template_tags)
+ if changed:
+ if template_type is not None:
+ template.import_template(template_content, template_type)
+ else:
+ template.update_template(template_ids, group_ids, link_template_ids, clear_template_ids,
+ template_macros, template_tags)
- module.exit_json(changed=changed, result="Template successfully updated")
+ module.exit_json(changed=changed, result="Template successfully updated")
if __name__ == "__main__":
diff --git a/ansible_collections/community/zabbix/plugins/modules/zabbix_templategroup.py b/ansible_collections/community/zabbix/plugins/modules/zabbix_templategroup.py
index 7ab39d8fc..a7050f226 100644
--- a/ansible_collections/community/zabbix/plugins/modules/zabbix_templategroup.py
+++ b/ansible_collections/community/zabbix/plugins/modules/zabbix_templategroup.py
@@ -67,7 +67,7 @@ EXAMPLES = r'''
ansible_httpapi_validate_certs: false
ansible_zabbix_url_path: 'zabbixeu' # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
ansible_host: zabbix-example-fqdn.org
- community.zabbix.zabbix_group:
+ community.zabbix.zabbix_templategroup:
state: present
template_groups:
- Example group1
@@ -84,7 +84,7 @@ EXAMPLES = r'''
ansible_httpapi_validate_certs: false
ansible_zabbix_url_path: 'zabbixeu' # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
ansible_host: zabbix-example-fqdn.org
- community.zabbix.zabbix_group:
+ community.zabbix.zabbix_templategroup:
state: present
template_groups:
- Example group1
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/README.md b/ansible_collections/community/zabbix/roles/zabbix_agent/README.md
index aa73fab3a..fe4a601b3 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/README.md
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/README.md
@@ -102,6 +102,7 @@ See the following list of supported Operating systems with the Zabbix releases:
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | V | V | V |
+You can bypass this matrix by setting `enable_version_check: false`
# Getting started
@@ -136,6 +137,8 @@ The following is an overview of all available configuration default for this rol
* `zabbix_agent_disable_repo`: A list of repos to disable during install. Default `epel`.
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_agent_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### SElinux
@@ -337,7 +340,7 @@ Keep in mind that using the Zabbix Agent in a Container requires changes to the
## IPMI variables
-* `zabbix_agent_ipmi_authtype`: IPMI authentication algorithm. Possible values are 1 (callback), 2 (user), 3 (operator), 4 (admin), 5 (OEM), with 2 being the API default.
+* `zabbix_agent_ipmi_authtype`: IPMI authentication algorithm. Possible values are -1 (default), 0 (none), 1 (MD2), 2 (MD5), 4 (straight), 5 (OEM), 6 (RMCP+), with -1 being the API default.
* `zabbix_agent_ipmi_password`: IPMI password.
* `zabbix_agent_ipmi_privilege`: IPMI privilege level. Possible values are 1 (callback), 2 (user), 3 (operator), 4 (admin), 5 (OEM), with 2 being the API default.
* `zabbix_agent_ipmi_username`: IPMI username.
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/defaults/main.yml b/ansible_collections/community/zabbix/roles/zabbix_agent/defaults/main.yml
index dbd5db5db..12424a6da 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/defaults/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/defaults/main.yml
@@ -26,6 +26,9 @@ zabbix_agent2_deny_key: "{{ zabbix_agent_deny_key }}"
# Selinux related vars
selinux_allow_zabbix_run_sudo: false
+zabbix_repo_deb_gpg_key_url: http://repo.zabbix.com/zabbix-official-repo.key
+zabbix_repo_deb_include_deb_src: true
+
zabbix_agent_install_agent_only: false
zabbix_agent_packages:
- "{{ zabbix_agent_package }}"
@@ -66,6 +69,7 @@ zabbix_repo_yum:
gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX
state: present
+zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_agent_version }}/{{ ansible_facts.lsb.id | default(ansible_facts['distribution']) | lower }}{% if ansible_facts['architecture'] == 'aarch64' and ansible_facts.lsb.id | default(ansible_facts['distribution']) in ['Debian', 'Ubuntu'] %}-arm64{% endif %}"
zabbix_repo_deb_component: main
# Zabbix API stuff
@@ -165,7 +169,7 @@ zabbix_agent_tls_config:
cert: "4"
# IPMI settings
-zabbix_agent_ipmi_authtype: 2
+zabbix_agent_ipmi_authtype: -1
zabbix_agent_ipmi_password:
zabbix_agent_ipmi_privilege: 2
zabbix_agent_ipmi_username:
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/molecule/with-server/prepare.yml b/ansible_collections/community/zabbix/roles/zabbix_agent/molecule/with-server/prepare.yml
index 582006d4e..e95cc9ad7 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/molecule/with-server/prepare.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/molecule/with-server/prepare.yml
@@ -75,6 +75,7 @@
hosts: docker
tasks:
- name: "Download Docker CE repo file"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
url: https://download.docker.com/linux/centos/docker-ce.repo
dest: /etc/yum.repos.d/docker-ce.repo
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/Debian.yml
index 6ded0ba03..92d56b179 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/Debian.yml
@@ -8,33 +8,6 @@
tags:
- always
-- name: "Debian | Installing lsb-release"
- ansible.builtin.apt:
- pkg: lsb-release
- update_cache: true
- cache_valid_time: 3600
- force: true
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- become: true
- tags:
- - install
-
-- name: "Debian | Update ansible_lsb fact"
- ansible.builtin.setup:
- gather_subset:
- - lsb
-
-- name: "Debian | Repo URL"
- ansible.builtin.set_fact:
- zabbix_repo_deb_url: "{{ _zabbix_repo_deb_url }}/{{ ansible_lsb.id.lower() }}{{ '-arm64' if ansible_machine == 'aarch64' and ansible_lsb.id == 'debian' else ''}}"
- when:
- - zabbix_repo_deb_url is undefined
- tags:
- - always
-
- name: "Debian | Installing gnupg"
ansible.builtin.apt:
pkg: gnupg
@@ -65,8 +38,9 @@
(ansible_distribution == "Debian" and ansible_distribution_major_version < "12")
- name: "Debian | Download gpg key"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
- url: http://repo.zabbix.com/zabbix-official-repo.key
+ url: "{{ zabbix_repo_deb_gpg_key_url }}"
dest: "{{ zabbix_gpg_key }}"
mode: "0644"
force: true
@@ -84,7 +58,7 @@
group: root
mode: 0644
content: |
- Types: deb deb-src
+ Types: deb{{ ' deb-src' if zabbix_repo_deb_include_deb_src }}
Enabled: yes
URIs: {{ zabbix_repo_deb_url }}
Suites: {{ ansible_distribution_release }}
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/main.yml b/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/main.yml
index f5f87d18f..c5fd06480 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/main.yml
@@ -12,16 +12,12 @@
tags:
- always
-- name: Set More Variables
- ansible.builtin.set_fact:
- zabbix_valid_version: "{{ zabbix_agent_version|float in zabbix_valid_agent_versions[ansible_distribution_major_version] }}"
- tags:
- - always
-
-- name: Stopping Install of Invalid Version
- ansible.builtin.fail:
- msg: Zabbix version {{ zabbix_agent_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
- when: not zabbix_valid_version
+- name: Check that version is supported
+ when: enable_version_check | default(true) | bool
+ ansible.builtin.assert:
+ that:
+ - "{{ zabbix_agent_version|float in zabbix_valid_agent_versions[ansible_distribution_major_version] }}"
+ fail_msg: Zabbix version {{ zabbix_agent_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
tags:
- always
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/userparameter.yml b/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/userparameter.yml
index a80be1736..d61e3899f 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/userparameter.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/tasks/userparameter.yml
@@ -7,6 +7,7 @@
notify:
- restart win zabbix agent
with_items: "{{ zabbix_agent_userparameters }}"
+ when: item.scripts_dir is not defined
- name: "Windows | Installing user-defined scripts"
ansible.windows.win_copy:
@@ -33,6 +34,7 @@
- restart mac zabbix agent
become: true
with_items: "{{ zabbix_agent_userparameters }}"
+ when: item.scripts_dir is not defined
- name: "Installing user-defined scripts"
ansible.builtin.copy:
@@ -66,6 +68,7 @@
- restart mac zabbix agent
become: true
with_items: "{{ zabbix_agent_userparameters }}"
+ when: item.scripts_dir is not defined
- name: "Installing user-defined scripts"
ansible.builtin.copy:
diff --git a/ansible_collections/community/zabbix/roles/zabbix_agent/vars/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_agent/vars/Debian.yml
index 4a65dfbeb..4a88411f1 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_agent/vars/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_agent/vars/Debian.yml
@@ -44,5 +44,4 @@ zabbix_valid_agent_versions:
- 6.0
debian_keyring_path: /etc/apt/keyrings/
-zabbix_gpg_key: "{{ debian_keyring_path }}/zabbix-official-repo.asc"
-_zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_agent_version }}"
+zabbix_gpg_key: "{{ debian_keyring_path }}zabbix-repo.asc"
diff --git a/ansible_collections/community/zabbix/roles/zabbix_javagateway/README.md b/ansible_collections/community/zabbix/roles/zabbix_javagateway/README.md
index 1761c7f8b..47092a6a0 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_javagateway/README.md
+++ b/ansible_collections/community/zabbix/roles/zabbix_javagateway/README.md
@@ -46,6 +46,8 @@ See the following list of supported Operating systems with the Zabbix releases.
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | V | V | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Role Variables
## Main variables
@@ -62,6 +64,8 @@ The `zabbix_javagateway_version` is optional. The latest available major.minor v
* `zabbix_javagateway_conf_mode`: Default: `0644`. The "mode" for the Zabbix configuration file.
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_agent_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### Java Gatewaty
diff --git a/ansible_collections/community/zabbix/roles/zabbix_javagateway/defaults/main.yml b/ansible_collections/community/zabbix/roles/zabbix_javagateway/defaults/main.yml
index 4356f61a4..d7f659648 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_javagateway/defaults/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_javagateway/defaults/main.yml
@@ -25,9 +25,13 @@ zabbix_repo_yum:
gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX
state: present
+zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_javagateway_version }}/{{ ansible_facts.lsb.id | default(ansible_facts['distribution']) | lower }}{% if ansible_facts['architecture'] == 'aarch64' and ansible_facts.lsb.id | default(ansible_facts['distribution']) in ['Debian', 'Ubuntu'] %}-arm64{% endif %}"
zabbix_repo_deb_component: main
zabbix_javagateway_pidfile: /run/zabbix/zabbix_java_gateway.pid
zabbix_javagateway_listenip: 0.0.0.0
zabbix_javagateway_listenport: 10052
zabbix_javagateway_startpollers: 5
+
+zabbix_repo_deb_gpg_key_url: http://repo.zabbix.com/zabbix-official-repo.key
+zabbix_repo_deb_include_deb_src: true
diff --git a/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/Debian.yml
index 4c4cff06d..ad762aa3b 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/Debian.yml
@@ -5,33 +5,6 @@
tags:
- always
-- name: "Debian | Installing lsb-release"
- ansible.builtin.apt:
- pkg: lsb-release
- update_cache: true
- cache_valid_time: 3600
- force: true
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- become: true
- tags:
- - install
-
-- name: "Debian | Update ansible_lsb fact"
- ansible.builtin.setup:
- gather_subset:
- - lsb
-
-- name: "Debian | Repo URL"
- ansible.builtin.set_fact:
- zabbix_repo_deb_url: "{{ _zabbix_repo_deb_url }}/{{ ansible_lsb.id.lower() }}{{ '-arm64' if ansible_machine == 'aarch64' and ansible_lsb.id == 'debian' else ''}}"
- when:
- - zabbix_repo_deb_url is undefined
- tags:
- - always
-
# In releases older than Debian 12 and Ubuntu 22.04, /etc/apt/keyrings does not exist by default.
# It SHOULD be created with permissions 0755 if it is needed and does not already exist.
# See: https://wiki.debian.org/DebianRepository/UseThirdParty
@@ -46,11 +19,15 @@
(ansible_distribution == "Debian" and ansible_distribution_major_version < "12")
- name: "Debian | Download gpg key"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
- url: http://repo.zabbix.com/zabbix-official-repo.key
+ url: "{{ zabbix_repo_deb_gpg_key_url }}"
dest: "{{ zabbix_gpg_key }}"
mode: "0644"
force: true
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
become: true
tags:
- install
@@ -62,7 +39,7 @@
group: root
mode: 0644
content: |
- Types: deb deb-src
+ Types: deb{{ ' deb-src' if zabbix_repo_deb_include_deb_src }}
Enabled: yes
URIs: {{ zabbix_repo_deb_url }}
Suites: {{ ansible_distribution_release }}
diff --git a/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/main.yml b/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/main.yml
index 6b56d43d3..aeeecbc8f 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_javagateway/tasks/main.yml
@@ -13,16 +13,12 @@
tags:
- always
-- name: Set More Variables
- ansible.builtin.set_fact:
- zabbix_valid_version: "{{ zabbix_javagateway_version|float in zabbix_valid_javagateway_versions[ansible_distribution_major_version] }}"
- tags:
- - always
-
-- name: Stopping Install of Invalid Version
- ansible.builtin.fail:
- msg: Zabbix version {{ zabbix_javagateway_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
- when: not zabbix_valid_version
+- name: Check that version is supported
+ when: enable_version_check | default(true) | bool
+ ansible.builtin.assert:
+ that:
+ - "{{ zabbix_javagateway_version|float in zabbix_valid_javagateway_versions[ansible_distribution_major_version] }}"
+ fail_msg: Zabbix version {{ zabbix_javagateway_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
tags:
- always
diff --git a/ansible_collections/community/zabbix/roles/zabbix_javagateway/vars/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_javagateway/vars/Debian.yml
index 2253f5b7b..7c36d2d3a 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_javagateway/vars/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_javagateway/vars/Debian.yml
@@ -26,5 +26,4 @@ zabbix_valid_javagateway_versions:
- 6.0
debian_keyring_path: /etc/apt/keyrings/
-zabbix_gpg_key: "{{ debian_keyring_path }}/zabbix-official-repo.asc"
-_zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_javagateway_version }}"
+zabbix_gpg_key: "{{ debian_keyring_path }}zabbix-repo.asc"
diff --git a/ansible_collections/community/zabbix/roles/zabbix_proxy/README.md b/ansible_collections/community/zabbix/roles/zabbix_proxy/README.md
index baec42155..ee558c8b7 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_proxy/README.md
+++ b/ansible_collections/community/zabbix/roles/zabbix_proxy/README.md
@@ -89,6 +89,8 @@ See the following list of supported Operating systems with the Zabbix releases.
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | V | V | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Role Variables
## Main variables
@@ -133,6 +135,9 @@ The following is an overview of all available configuration default for this rol
* `*zabbix_proxy_package_state`: Default: `present`. Can be overridden to `latest` to update packages
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_proxy_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
+
### SElinux
* `zabbix_proxy_selinux`: Default: `False`. Enables an SELinux policy so that the Proxy will run.
diff --git a/ansible_collections/community/zabbix/roles/zabbix_proxy/defaults/main.yml b/ansible_collections/community/zabbix/roles/zabbix_proxy/defaults/main.yml
index f46c9c64e..b2b74ebec 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_proxy/defaults/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_proxy/defaults/main.yml
@@ -41,6 +41,7 @@ zabbix_proxy_version_minor: "*"
# Yum/APT Variables
zabbix_repo_yum_schema: https
zabbix_repo_yum_gpgcheck: 0
+zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_proxy_version }}/{{ ansible_facts.lsb.id | default(ansible_facts['distribution']) | lower }}{% if ansible_facts['architecture'] == 'aarch64' and ansible_facts.lsb.id | default(ansible_facts['distribution']) in ['Debian', 'Ubuntu'] %}-arm64{% endif %}"
zabbix_repo_deb_component: main
zabbix_proxy_disable_repo:
- epel
@@ -61,6 +62,8 @@ zabbix_repo_yum:
state: present
zabbix_proxy_apt_priority:
zabbix_proxy_package_state: present
+zabbix_repo_deb_gpg_key_url: http://repo.zabbix.com/zabbix-official-repo.key
+zabbix_repo_deb_include_deb_src: true
# Proxy Configuration Variables (Only ones with role provided defaults)
zabbix_proxy_allowroot: 0
diff --git a/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/Debian.yml
index 8e27e7d27..bef68b27a 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/Debian.yml
@@ -7,33 +7,6 @@
tags:
- always
-- name: "Debian | Installing lsb-release"
- ansible.builtin.apt:
- pkg: lsb-release
- update_cache: true
- cache_valid_time: 3600
- force: true
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- become: true
- tags:
- - install
-
-- name: "Debian | Update ansible_lsb fact"
- ansible.builtin.setup:
- gather_subset:
- - lsb
-
-- name: "Debian | Repo URL"
- ansible.builtin.set_fact:
- zabbix_repo_deb_url: "{{ _zabbix_repo_deb_url }}/{{ ansible_lsb.id.lower() }}{{ '-arm64' if ansible_machine == 'aarch64' and ansible_lsb.id == 'debian' else ''}}"
- when:
- - zabbix_repo_deb_url is undefined
- tags:
- - always
-
- name: "Debian | Set some facts for Zabbix"
ansible.builtin.set_fact:
datafiles_path: /usr/share/doc/zabbix-sql-scripts/{{ zabbix_proxy_db_long }}
@@ -71,11 +44,15 @@
(ansible_distribution == "Debian" and ansible_distribution_major_version < "12")
- name: "Debian | Download gpg key"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
- url: http://repo.zabbix.com/zabbix-official-repo.key
+ url: "{{ zabbix_repo_deb_gpg_key_url }}"
dest: "{{ zabbix_gpg_key }}"
mode: "0644"
force: true
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
register: are_zabbix_proxy_dependency_packages_installed
until: are_zabbix_proxy_dependency_packages_installed is succeeded
become: true
@@ -89,7 +66,7 @@
group: root
mode: 0644
content: |
- Types: deb deb-src
+ Types: deb{{ ' deb-src' if zabbix_repo_deb_include_deb_src }}
Enabled: yes
URIs: {{ zabbix_repo_deb_url }}
Suites: {{ ansible_distribution_release }}
diff --git a/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/main.yml b/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/main.yml
index f564635b1..1e8831c35 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_proxy/tasks/main.yml
@@ -15,17 +15,18 @@
- name: Set More Variables
ansible.builtin.set_fact:
zabbix_proxy_db_long: "{{ 'postgresql' if zabbix_proxy_database == 'pgsql' else zabbix_proxy_database }}"
- zabbix_valid_version: "{{ zabbix_proxy_version|float in zabbix_valid_proxy_versions[ansible_distribution_major_version] }}"
zabbix_short_version: "{{ zabbix_proxy_version | regex_replace('\\.', '') }}"
zabbix_proxy_fpinglocation: "{{ zabbix_proxy_fpinglocation if zabbix_proxy_fpinglocation is defined else _zabbix_proxy_fpinglocation}}"
zabbix_proxy_fping6location: "{{ zabbix_proxy_fping6location if zabbix_proxy_fping6location is defined else _zabbix_proxy_fping6location}}"
tags:
- always
-- name: Stopping Install of Invalid Version
- ansible.builtin.fail:
- msg: Zabbix version {{ zabbix_proxy_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
- when: not zabbix_valid_version
+- name: Check that version is supported
+ when: enable_version_check | default(true) | bool
+ ansible.builtin.assert:
+ that:
+ - "{{ zabbix_proxy_version|float in zabbix_valid_proxy_versions[ ansible_facts['distribution_major_version'] ] }}"
+ fail_msg: Zabbix version {{ zabbix_proxy_version }} is not supported on {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_major_version'] }}
tags:
- always
diff --git a/ansible_collections/community/zabbix/roles/zabbix_proxy/vars/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_proxy/vars/Debian.yml
index cd9527eb2..1362e557e 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_proxy/vars/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_proxy/vars/Debian.yml
@@ -51,7 +51,6 @@ mysql_plugin:
"10": mysql_native_password
debian_keyring_path: /etc/apt/keyrings/
-zabbix_gpg_key: "{{ debian_keyring_path }}/zabbix-official-repo.asc"
-_zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_proxy_version }}"
+zabbix_gpg_key: "{{ debian_keyring_path }}zabbix-repo.asc"
_zabbix_proxy_fping6location: /usr/bin/fping6
_zabbix_proxy_fpinglocation: /usr/bin/fping
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/README.md b/ansible_collections/community/zabbix/roles/zabbix_server/README.md
index f154f4951..9557281c3 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/README.md
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/README.md
@@ -86,6 +86,8 @@ See the following list of supported Operating systems with the Zabbix releases:
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | | | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Installation
Installing this role is very simple: `ansible-galaxy install community.zabbix.zabbix_server`
@@ -109,6 +111,8 @@ The following is an overview of all available configuration default for this rol
* `zabbix_service_enabled`: Default: `True` Can be overridden to `False` if needed
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_server_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### SElinux
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/defaults/main.yml b/ansible_collections/community/zabbix/roles/zabbix_server/defaults/main.yml
index 6aec202dd..933e0339a 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/defaults/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/defaults/main.yml
@@ -40,9 +40,8 @@ zabbix_server_version_minor: "*"
zabbix_server_package_state: present
zabbix_repo_yum_gpgcheck: 0
zabbix_repo_yum_schema: https
+zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_server_version }}/{{ ansible_facts.lsb.id | default(ansible_facts['distribution']) | lower }}{% if ansible_facts['architecture'] == 'aarch64' and ansible_facts.lsb.id | default(ansible_facts['distribution']) in ['Debian', 'Ubuntu'] %}-arm64{% endif %}"
zabbix_repo_deb_component: main
-zabbix_server_disable_repo:
- - epel
zabbix_repo_yum:
- name: zabbix
description: Zabbix Official Repository - $basearch
@@ -59,8 +58,9 @@ zabbix_repo_yum:
gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX
state: present
zabbix_server_apt_priority:
-zabbix_server_install_recommends: true
zabbix_server_conf_mode: 0640
+zabbix_repo_deb_gpg_key_url: http://repo.zabbix.com/zabbix-official-repo.key
+zabbix_repo_deb_include_deb_src: true
# Server Configuration Variables (Only ones with role provided defaults)
zabbix_server_alertscriptspath: /usr/lib/zabbix/alertscripts
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/Debian.yml
index ccfe6f121..c7b106614 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/Debian.yml
@@ -3,40 +3,6 @@
ansible.builtin.set_fact:
zabbix_short_version: "{{ zabbix_server_version | regex_replace('\\.', '') }}"
zabbix_underscore_version: "{{ zabbix_server_version | regex_replace('\\.', '_') }}"
- zabbix_python_prefix: "python{% if ansible_python_version is version('3', '>=') %}3{% endif %}"
- tags:
- - always
-
-- name: "Debian | Installing lsb-release"
- ansible.builtin.apt:
- pkg: lsb-release
- update_cache: true
- cache_valid_time: 3600
- force: true
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- become: true
- tags:
- - install
-
-- name: "Debian | Update ansible_lsb fact"
- ansible.builtin.setup:
- gather_subset:
- - lsb
-
-- name: "Debian | Repo URL"
- ansible.builtin.set_fact:
- zabbix_repo_deb_url: "{{ _zabbix_repo_deb_url }}/{{ ansible_lsb.id.lower() }}{{ '-arm64' if ansible_machine == 'aarch64' and ansible_lsb.id == 'debian' else ''}}"
- when:
- - zabbix_repo_deb_url is undefined
- tags:
- - always
-
-- name: "Debian | Set some facts for Zabbix"
- ansible.builtin.set_fact:
- datafiles_path: /usr/share/zabbix-sql-scripts/{{ 'postgresql' if zabbix_server_database == 'pgsql' else 'mysql' }}
tags:
- always
@@ -70,11 +36,15 @@
(ansible_distribution == "Debian" and ansible_distribution_major_version < "12")
- name: "Debian | Download gpg key"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
- url: http://repo.zabbix.com/zabbix-official-repo.key
+ url: "{{ zabbix_repo_deb_gpg_key_url }}"
dest: "{{ zabbix_gpg_key }}"
mode: "0644"
force: true
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
register: zabbix_server_repo_files_installed
until: zabbix_server_repo_files_installed is succeeded
become: true
@@ -88,7 +58,7 @@
group: root
mode: 0644
content: |
- Types: deb deb-src
+ Types: deb{{ ' deb-src' if zabbix_repo_deb_include_deb_src }}
Enabled: yes
URIs: {{ zabbix_repo_deb_url }}
Suites: {{ ansible_distribution_release }}
@@ -124,117 +94,3 @@
become: true
tags:
- install
-
-# On certain 18.04 images, such as docker or lxc, dpkg is configured not to
-# install files into paths /usr/share/doc/*
-# Since this is where Zabbix installs its database schemas, we need to allow
-# files to be installed to /usr/share/doc/zabbix*
-- name: "Debian | Check for the dpkg exclude line"
- ansible.builtin.command: grep -F 'path-exclude=/usr/share/doc/*' /etc/dpkg/dpkg.cfg.d/excludes
- register: dpkg_exclude_line
- failed_when: false
- changed_when: false
- check_mode: false
- become: true
- tags:
- - install
-
-- name: "Debian | Allow Zabbix dpkg installs to /usr/share/doc/zabbix*"
- ansible.builtin.lineinfile:
- path: /etc/dpkg/dpkg.cfg.d/excludes
- line: "path-include=/usr/share/doc/zabbix*"
- become: true
- when:
- - dpkg_exclude_line.rc == 0
- tags:
- - install
-
-- name: "Debian | Installing zabbix-server-{{ zabbix_server_database }}"
- ansible.builtin.apt:
- pkg: zabbix-server-{{ zabbix_server_database }}
- state: "{{ zabbix_server_package_state }}"
- update_cache: true
- cache_valid_time: 0
- install_recommends: "{{ zabbix_server_install_recommends }}"
- default_release: "{{ ansible_distribution_release }}"
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_package_installed
- until: zabbix_server_package_installed is succeeded
- become: true
- tags:
- - install
-
-- name: "Debian | Installing zabbix-sql-scripts"
- ansible.builtin.apt:
- pkg: zabbix-sql-scripts
- state: "{{ zabbix_server_package_state }}"
- update_cache: true
- cache_valid_time: 0
- install_recommends: "{{ zabbix_server_install_recommends }}"
- default_release: "{{ ansible_distribution_release }}"
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_package_sql_installed
- until: zabbix_server_package_sql_installed is succeeded
- when:
- - zabbix_server_version is version('5.4', '>=')
- become: true
- tags:
- - install
-
-- name: "Debian | Install Database Client Package"
- block:
- - name: "Debian | Install Mysql Client package"
- ansible.builtin.apt:
- name:
- - default-mysql-client
- - "{{ zabbix_python_prefix }}-mysqldb"
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_dependencies_installed
- until: zabbix_server_dependencies_installed is succeeded
- become: true
- when:
- - zabbix_server_database == 'mysql'
- - ansible_distribution_release != "buster"
-
- - name: "Debian 10 | Install Mysql Client package"
- ansible.builtin.apt:
- name:
- - mariadb-client
- - "{{ zabbix_python_prefix }}-mysqldb"
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_dependencies_installed
- until: zabbix_server_dependencies_installed is succeeded
- become: true
- when:
- - zabbix_server_database == 'mysql'
- - ansible_distribution_release == "buster"
-
- - name: "Debian | Install PostgreSQL Client package"
- ansible.builtin.apt:
- name:
- - postgresql-client
- - "{{ zabbix_python_prefix }}-psycopg2"
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_dependencies_installed
- until: zabbix_server_dependencies_installed is succeeded
- become: true
- when:
- - zabbix_server_database == 'pgsql'
- when: zabbix_server_install_database_client
- tags:
- - install
- - database
- - dependencies
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/RedHat.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/RedHat.yml
index fefd7e86c..77fb7cd8a 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/RedHat.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/RedHat.yml
@@ -7,18 +7,6 @@
tags:
- always
-- name: "RedHat | Use Zabbix package name"
- ansible.builtin.set_fact:
- zabbix_server_package: "zabbix-server-{{ zabbix_server_database }}"
- tags:
- - always
-
-- name: "RedHat | Set facts for Zabbix"
- ansible.builtin.set_fact:
- datafiles_path: "/usr/share/zabbix-sql-scripts/{{ 'postgresql' if zabbix_server_database == 'pgsql' else 'mysql' }}"
- tags:
- - always
-
- name: "RedHat | Make sure old file is absent"
ansible.builtin.file:
path: /etc/yum.repos.d/zabbix-supported.repo
@@ -46,86 +34,6 @@
tags:
- install
-- name: "RedHat | Installing zabbix-server-{{ zabbix_server_database }}"
- ansible.builtin.package:
- pkg: "{{ zabbix_server_package }}-{{ zabbix_server_version }}.{{ zabbix_server_version_minor }}"
- state: "{{ zabbix_server_package_state }}"
- disablerepo: "{{ zabbix_server_disable_repo | default(omit) }}"
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_package_installed
- until: zabbix_server_package_installed is succeeded
- become: true
- tags:
- - install
-
-- name: "RedHat | Installing zabbix-sql-scripts"
- ansible.builtin.package:
- pkg: "zabbix-sql-scripts-{{ zabbix_server_version }}.{{ zabbix_server_version_minor }}"
- state: "{{ zabbix_server_package_state }}"
- disablerepo: "{{ zabbix_server_disable_repo | default(omit) }}"
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_sql_package_installed
- until: zabbix_server_sql_package_installed is succeeded
- when:
- - zabbix_server_version is version('6.0', '>=')
- become: true
- tags:
- - install
-
-- name: "RedHat | Install Ansible module dependencies"
- ansible.builtin.yum:
- name: "{{ pgsql_depenencies[ansible_distribution_major_version] }}"
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_dependencies_installed
- until: zabbix_server_dependencies_installed is succeeded
- become: true
- when:
- - zabbix_server_database_creation
- - zabbix_server_database == 'pgsql'
- tags:
- - install
- - dependencies
-
-- name: RedHat | Install Database Client Package
- block:
- - name: "RedHat | Install Mysql Client packages"
- ansible.builtin.yum:
- name: "{{ mysql_client_pkgs[ansible_distribution_major_version] }}"
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_dependencies_installed
- until: zabbix_server_dependencies_installed is succeeded
- become: true
- when:
- - zabbix_server_database == 'mysql'
-
- - name: "RedHat | Install PostgreSQL client package"
- ansible.builtin.yum:
- name: postgresql
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- register: zabbix_server_dependencies_installed
- until: zabbix_server_dependencies_installed is succeeded
- become: true
- when:
- - zabbix_server_database == 'pgsql'
- when: zabbix_server_install_database_client
- tags:
- - install
- - dependencies
- - database
-
- name: "RedHat | Configure SELinux when enabled"
ansible.builtin.include_tasks: selinux.yml
when:
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-mysql.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-mysql.yml
new file mode 100644
index 000000000..c3fd67c6d
--- /dev/null
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-mysql.yml
@@ -0,0 +1,155 @@
+---
+# task file for mysql
+- name: "Install MySQL dependencies"
+ ansible.builtin.package:
+ name: "{{ _zabbix_server_mysql_dependencies | select | list }}"
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
+ register: _zabbix_server_dependencies_installed
+ until: _zabbix_server_dependencies_installed is succeeded
+ become: true
+ tags:
+ - install
+ - database
+ - dependencies
+
+# NOTE: Upgrading system-packages with pip is generally a bad idea, but
+# ubuntu-18.04 comes with pymysql==0.8.0, which seems to have a problem with
+# versions 8 and above of mysql.
+- name: Upgrade pymysql
+ when:
+ - ansible_facts['distribution'] == 'Ubuntu'
+ - ansible_facts['distribution_release'] == 'bionic'
+ ansible.builtin.pip:
+ name: "pymysql>=0.10.0,<0.11.0"
+ state: latest
+
+- name: "MySQL Database prep"
+ when: zabbix_server_database_creation
+ delegate_to: "{{ zabbix_server_real_dbhost | default(zabbix_server_dbhost_run_install | ternary(delegated_dbhost, inventory_hostname)) }}"
+ vars:
+ delegated_dbhost: "{{ (zabbix_server_dbhost == 'localhost') | ternary(inventory_hostname, zabbix_server_dbhost) }}"
+ tags:
+ - database
+ block:
+ - name: "MySQL | Create database"
+ community.mysql.mysql_db:
+ login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
+ login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
+ login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
+ login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
+ name: "{{ zabbix_server_dbname }}"
+ encoding: "{{ zabbix_server_dbencoding }}"
+ collation: "{{ zabbix_server_dbcollation }}"
+ state: present
+ register: zabbix_database_created
+
+ - name: "MySQL | Create database user"
+ community.mysql.mysql_user:
+ login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
+ login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
+ login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
+ login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
+ name: "{{ zabbix_server_dbuser }}"
+ password: "{{ zabbix_server_dbpassword }}"
+ host: "{{ zabbix_server_privileged_host }}"
+ plugin: "{{ 'mysql_native_password' if (ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7') else omit }}"
+ priv: "{{ zabbix_server_dbname }}.*:ALL"
+ state: present
+
+- name: "MySQL verify or create schema"
+ when: zabbix_server_database_sqlload | bool
+ vars:
+ delegated_dbhost: "{{ (zabbix_server_dbhost == 'localhost') | ternary(inventory_hostname, zabbix_server_dbhost) }}"
+ tags:
+ - database
+ block:
+ # If this check fails, then there's no dbversion table in the database,
+ # hence it has not been populated, and we'll create it, below.
+ # Otherwise, the module will succees and we could
+ # access the database version, for example 5000000 for Zabbix 5.0.
+ - name: "MySQL | Get current database version"
+ community.mysql.mysql_query:
+ login_user: "{{ zabbix_server_dbuser }}"
+ login_password: "{{ zabbix_server_dbpassword }}"
+ login_host: "{{ zabbix_server_dbhost }}"
+ login_port: "{{ zabbix_server_dbport }}"
+ login_db: "{{ zabbix_server_dbname }}"
+ query: 'SELECT mandatory FROM dbversion'
+ rescue:
+ - name: "MySQL | Get and set schema import overrides"
+ delegate_to: "{{ zabbix_server_real_dbhost | default(zabbix_server_dbhost_run_install | ternary(delegated_dbhost, inventory_hostname)) }}"
+ block:
+ - name: "MySQL | Get current value for variables"
+ community.mysql.mysql_variables:
+ variable: "{{ name }}"
+ login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
+ login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
+ login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
+ login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
+ loop:
+ - innodb_default_row_format
+ - log_bin_trust_function_creators
+ loop_control:
+ loop_var: name
+ register: _mysql_variable_defaults
+
+ - name: "MySQL | Set variable overrides for schema import"
+ community.mysql.mysql_variables:
+ variable: "{{ item.name }}"
+ value: "{{ _mysql_schema_import_overrides[item.name] }}"
+ login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
+ login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
+ login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
+ login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
+ when: item.msg != _mysql_schema_import_overrides[item.name]
+ loop: "{{ _mysql_variable_defaults.results }}"
+ loop_control:
+ label: "{{ item.name }}: {{ _mysql_schema_import_overrides[item.name] }}"
+ vars:
+ _mysql_schema_import_overrides:
+ innodb_default_row_format: "dynamic"
+ log_bin_trust_function_creators: "ON"
+
+ - name: "MySQL | Disable InnoDB Strict Mode"
+ when: ansible_facts['distribution_release'] == "buster"
+ community.mysql.mysql_variables:
+ variable: innodb_strict_mode
+ value: 0
+ login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
+ login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
+ login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
+ login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
+
+ - name: "MySQL | Import schema"
+ community.mysql.mysql_db:
+ login_user: "{{ zabbix_server_dbuser }}"
+ login_password: "{{ zabbix_server_dbpassword }}"
+ login_host: "{{ zabbix_server_dbhost }}"
+ login_port: "{{ zabbix_server_dbport }}"
+ name: "{{ zabbix_server_dbname }}"
+ encoding: "{{ zabbix_server_dbencoding }}"
+ collation: "{{ zabbix_server_dbcollation }}"
+ state: import
+ target: /usr/share/zabbix-sql-scripts/mysql/server.sql.gz
+
+ always:
+ - name: "MySQL | Revert variable overrides for schema import"
+ delegate_to: "{{ zabbix_server_real_dbhost | default(zabbix_server_dbhost_run_install | ternary(delegated_dbhost, inventory_hostname)) }}"
+ community.mysql.mysql_variables:
+ variable: "{{ item.name }}"
+ value: "{{ item.msg }}"
+ login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
+ login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
+ login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
+ login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
+ loop: "{{ _mysql_variable_defaults.results | default([]) }}"
+ loop_control:
+ label: "{{ item.name }}: {{ item.msg }}"
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/postgresql.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-pgsql.yml
index 5177a55be..65bd0beec 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/postgresql.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/initialize-pgsql.yml
@@ -1,126 +1,92 @@
---
# task file for postgresql
-
-- name: "PostgreSQL | Set the correct delegated_dbhost (to support postgres db deployment on a remote dbhost)"
- ansible.builtin.set_fact:
- delegated_dbhost: "{{ zabbix_server_dbhost if (zabbix_server_dbhost != 'localhost') else inventory_hostname }}"
- when:
- - zabbix_server_dbhost_run_install
- tags:
- - database
-
-- name: "PostgreSQL | Set the correct delegated_dbhost (to support postgres db deployment on a remote dbhost)"
- ansible.builtin.set_fact:
- delegated_dbhost: "{{ inventory_hostname }}"
- when:
- - not zabbix_server_dbhost_run_install
+- name: "Install PostgreSQL dependencies"
+ ansible.builtin.package:
+ name: "{{ _zabbix_server_pgsql_dependencies | select | list }}"
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
+ register: _zabbix_server_dependencies_installed
+ until: _zabbix_server_dependencies_installed is succeeded
+ become: true
tags:
+ - install
- database
+ - dependencies
-- name: "PostgreSQL | Delegated"
- block:
- - name: "PostgreSQL | Delegated | Create database"
- community.postgresql.postgresql_db:
- name: "{{ zabbix_server_dbname }}"
- port: "{{ zabbix_server_dbport }}"
- state: present
-
- - name: "PostgreSQL | Delegated | Create database user"
- community.postgresql.postgresql_user:
- db: "{{ zabbix_server_dbname }}"
- name: "{{ zabbix_server_dbuser }}"
- password: "{{ ('md5' + (zabbix_server_dbpassword + zabbix_server_dbuser)|hash('md5')) if zabbix_server_dbpassword_hash_method == 'md5' else zabbix_server_dbpassword }}"
- port: "{{ zabbix_server_dbport }}"
- priv: ALL
- state: present
- encrypted: true
-
- - name: "PostgreSQL | Delegated | Create timescaledb extension"
- community.postgresql.postgresql_ext:
- db: "{{ zabbix_server_dbname }}"
- name: timescaledb
- when: zabbix_server_database_timescaledb
- become: true
+- name: "PostgreSQL Database prep"
+ when: zabbix_server_database_creation
+ become: "{{ zabbix_server_dbhost_run_install }}"
become_user: postgres
- delegate_to: "{{ delegated_dbhost }}"
- when:
- - zabbix_server_database_creation
- - zabbix_server_pgsql_login_host is not defined
+ delegate_to: "{{ zabbix_server_dbhost_run_install | ternary(delegated_dbhost, inventory_hostname) }}"
+ vars:
+ delegated_dbhost: "{{ (zabbix_server_dbhost == 'localhost') | ternary(inventory_hostname, zabbix_server_dbhost) }}"
tags:
- database
-
-- name: "PostgreSQL | Remote"
block:
- - name: "PostgreSQL | Remote | Create database"
+ - name: "PostgreSQL | Create database"
community.postgresql.postgresql_db:
- login_host: "{{ zabbix_server_pgsql_login_host | default(omit) }}"
login_user: "{{ zabbix_server_pgsql_login_user | default(omit) }}"
login_password: "{{ zabbix_server_pgsql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_pgsql_login_host | default(omit) }}"
+ port: "{{ zabbix_server_dbport }}"
login_unix_socket: "{{ zabbix_server_pgsql_login_unix_socket | default(omit) }}"
name: "{{ zabbix_server_dbname }}"
- port: "{{ zabbix_server_dbport }}"
state: present
- - name: "PostgreSQL | Remote | Create database user"
+ - name: "PostgreSQL | Create database user"
community.postgresql.postgresql_user:
- login_host: "{{ zabbix_server_pgsql_login_host | default(omit) }}"
login_user: "{{ zabbix_server_pgsql_login_user | default(omit) }}"
login_password: "{{ zabbix_server_pgsql_login_password | default(omit) }}"
- db: "{{ zabbix_server_dbname }}"
+ login_host: "{{ zabbix_server_pgsql_login_host | default(omit) }}"
+ port: "{{ zabbix_server_dbport }}"
+ login_unix_socket: "{{ zabbix_server_pgsql_login_unix_socket | default(omit) }}"
name: "{{ zabbix_server_dbuser }}"
password: "{{ ('md5' + (zabbix_server_dbpassword + zabbix_server_dbuser)|hash('md5')) if zabbix_server_dbpassword_hash_method == 'md5' else zabbix_server_dbpassword }}"
- port: "{{ zabbix_server_dbport }}"
+ db: "{{ zabbix_server_dbname }}"
priv: ALL
state: present
encrypted: true
- - name: "PostgreSQL | Remote | Create timescaledb extension"
+ - name: "PostgreSQL | Create timescaledb extension"
+ when: zabbix_server_database_timescaledb
community.postgresql.postgresql_ext:
- login_host: "{{ zabbix_server_pgsql_login_host | default(omit) }}"
login_user: "{{ zabbix_server_pgsql_login_user | default(omit) }}"
login_password: "{{ zabbix_server_pgsql_login_password | default(omit) }}"
+ login_host: "{{ zabbix_server_pgsql_login_host | default(omit) }}"
+ port: "{{ zabbix_server_dbport }}"
login_unix_socket: "{{ zabbix_server_pgsql_login_unix_socket | default(omit) }}"
db: "{{ zabbix_server_dbname }}"
name: timescaledb
- when: zabbix_server_database_timescaledb
- when:
- - zabbix_server_database_creation
- - zabbix_server_pgsql_login_host is defined
- tags:
- - database
-- name: "PostgreSQL | Create schema"
- ansible.builtin.shell: |
- set -euxo pipefail
- FILE={{ 'create.sql' if zabbix_server_version is version('6.0', '<') else 'server.sql' }}
- cd {{ datafiles_path }}
- if [ -f ${FILE}.gz ]
- then zcat ${FILE}.gz > /tmp/create.sql
- else
- cp ${FILE} /tmp/create.sql
- fi
- cat /tmp/create.sql | psql -h '{{ zabbix_server_dbhost }}' \
- -U '{{ zabbix_server_dbuser }}' \
- -d '{{ zabbix_server_dbname }}' \
- -p '{{ zabbix_server_dbport }}'
- touch /etc/zabbix/schema.done
- rm -f /tmp/create.sql
- args:
- creates: /etc/zabbix/schema.done
- executable: /bin/bash
- warn: "{{ produce_warn | default(omit) }}"
- environment:
- PGPASSWORD: "{{ zabbix_server_dbpassword }}"
- become: true
- when:
- - zabbix_server_database_sqlload
+- name: "PostgreSQL verify or create schema"
+ when: zabbix_server_database_sqlload
tags:
- database
+ block:
+ - name: "PostgreSQL | Get current database version"
+ community.postgresql.postgresql_query:
+ login_user: "{{ zabbix_server_dbuser }}"
+ login_password: "{{ zabbix_server_dbpassword }}"
+ login_host: "{{ zabbix_server_dbhost }}"
+ port: "{{ zabbix_server_dbport }}"
+ db: "{{ zabbix_server_dbname }}"
+ query: 'SELECT mandatory FROM dbversion'
+ rescue:
+ - name: "PostgreSQL | Import schema"
+ community.postgresql.postgresql_db:
+ login_user: "{{ zabbix_server_dbuser }}"
+ login_password: "{{ zabbix_server_dbpassword }}"
+ login_host: "{{ zabbix_server_dbhost }}"
+ port: "{{ zabbix_server_dbport }}"
+ db: "{{ zabbix_server_dbname }}"
+ state: restore
+ target: /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz
- name: "PostgreSQL | Create TimescaleDB hypertables"
ansible.builtin.shell: |
set -euxo pipefail
- cd {{ datafiles_path }} &&
+ cd /usr/share/zabbix-sql-scripts/postgresql &&
if [ -f timescaledb.sql.gz ]; then zcat timescaledb.sql.gz > /etc/timescaledb.sql ; else cp -p timescaledb.sql /etc/timescaledb.sql ; fi
cat /etc/timescaledb.sql | psql -h '{{ zabbix_server_dbhost }}' \
-U '{{ zabbix_server_dbuser }}' \
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/main.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/main.yml
index 62674a7ff..356403e0b 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/main.yml
@@ -13,25 +13,41 @@
- name: Set More Variables
ansible.builtin.set_fact:
- zabbix_db_type_long: "{{ 'postgresql' if zabbix_server_database == 'pgsql' else 'mysql' }}"
- zabbix_valid_version: "{{ zabbix_server_version|float in zabbix_valid_server_versions[ansible_distribution_major_version] }}"
zabbix_server_fpinglocation: "{{ zabbix_server_fpinglocation if zabbix_server_fpinglocation is defined else _zabbix_server_fpinglocation}}"
zabbix_server_fping6location: "{{ zabbix_server_fping6location if zabbix_server_fping6location is defined else _zabbix_server_fping6location}}"
tags:
- always
-- name: Stopping Install of Invalid Version
- ansible.builtin.fail:
- msg: Zabbix version {{ zabbix_server_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
- when: not zabbix_valid_version
+- name: Check that version is supported
+ when: enable_version_check | default(true) | bool
+ ansible.builtin.assert:
+ that:
+ - "{{ zabbix_server_version|float in zabbix_valid_server_versions[ ansible_facts['distribution_major_version'] ] }}"
+ fail_msg: Zabbix version {{ zabbix_server_version }} is not supported on {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_major_version'] }}
tags:
- always
- name: Install the correct repository
ansible.builtin.include_tasks: "{{ ansible_os_family }}.yml"
-- name: Installing the {{ zabbix_db_type_long }} database
- ansible.builtin.include_tasks: "{{ zabbix_db_type_long }}.yml"
+- name: Install zabbix-server packages
+ ansible.builtin.package:
+ name: "{{ _zabbix_server_packages }}"
+ state: "{{ zabbix_server_package_state }}"
+ update_cache: true
+ disablerepo: "{{ zabbix_server_disable_repo | default(_zabbix_server_disable_repo | default(omit)) }}"
+ install_recommends: "{{ zabbix_server_install_recommends | default(_zabbix_server_install_recommends | default(omit)) }}"
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
+ register: _zabbix_server_package_installed
+ until: _zabbix_server_package_installed is succeeded
+ become: true
+ tags:
+ - install
+
+- name: "Initialize the database"
+ ansible.builtin.include_tasks: "initialize-{{ zabbix_server_database }}.yml"
- name: "Configure zabbix-server"
ansible.builtin.template:
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/mysql.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/mysql.yml
deleted file mode 100644
index aad009816..000000000
--- a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/mysql.yml
+++ /dev/null
@@ -1,213 +0,0 @@
----
-# task file for mysql
-
-- name: "MySQL | Set the correct delegated_dbhost (to support MySQL db deployment on a remote dbhost)"
- ansible.builtin.set_fact:
- delegated_dbhost: "{{ zabbix_server_dbhost if (zabbix_server_dbhost != 'localhost') else inventory_hostname }}"
- when:
- - zabbix_server_dbhost_run_install
- tags:
- - database
-
-- name: "MySQL | Set the correct delegated_dbhost (to support MySQL db deployment on a remote dbhost)"
- ansible.builtin.set_fact:
- delegated_dbhost: "{{ inventory_hostname }}"
- when:
- - not zabbix_server_dbhost_run_install
- tags:
- - database
-
-- name: "MySQL | Override delegated_dbhost with real dbhost when dbhost is behind loadbalancer"
- ansible.builtin.set_fact:
- delegated_dbhost: "{{ zabbix_server_real_dbhost }}"
- when: zabbix_server_real_dbhost | default(false)
- tags:
- - database
-
-- name: "MySQL | Create database"
- community.mysql.mysql_db:
- name: "{{ zabbix_server_dbname }}"
- encoding: "{{ zabbix_server_dbencoding }}"
- collation: "{{ zabbix_server_dbcollation }}"
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
- login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- state: present
- when: zabbix_server_database_creation
- register: zabbix_database_created
- delegate_to: "{{ delegated_dbhost }}"
- tags:
- - database
- - skip_ansible_lint
-
-- name: "MySQL | Create database user"
- community.mysql.mysql_user:
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
- login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- name: "{{ zabbix_server_dbuser }}"
- password: "{{ zabbix_server_dbpassword }}"
- plugin: "{{ 'mysql_native_password' if (ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7') else omit }}"
- priv: "{{ zabbix_server_dbname }}.*:ALL"
- host: "{{ zabbix_server_privileged_host }}"
- state: present
- when: zabbix_server_database_creation
- delegate_to: "{{ delegated_dbhost }}"
- tags:
- - database
-
-- name: "MySQL | Get the file for create.sql"
- ansible.builtin.shell: ls -1 {{ datafiles_path }}/{{ 'create' if zabbix_server_version is version('6.0', '<') else 'server' }}.sq*
- changed_when: false
- become: true
- when:
- - zabbix_server_database_sqlload | bool
- register: ls_output_create
- tags:
- - database
-
-- name: MySQL | Get current database version
- ansible.builtin.shell: |
- mysql -h {{ zabbix_server_dbhost }} -u{{ zabbix_server_dbuser }} \
- -p'{{ zabbix_server_dbpassword }}' -D '{{ zabbix_server_dbname }}' \
- -e 'SELECT mandatory FROM dbversion;'
- register: mysql_db_version
- become: true
- changed_when: false
- ignore_errors: true
- tags:
- - database
-
-# If the above check failed, then there was no dbversion table in the database.
-# We'll create it, below. Otherwise, we can access the database version in
-# `mysql_db_version["stdout_lines"][1]`, for example 5000000 for Zabbix 5.0.
-- name: MySQL | Check if database needs to be populated
- ansible.builtin.set_fact:
- mysql_schema_empty: "{{ mysql_db_version is failed }}"
-
-- name: "MySQL | Get current value for innodb_default_row_format"
- community.mysql.mysql_variables:
- variable: innodb_default_row_format
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
- login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- delegate_to: "{{ delegated_dbhost }}"
- register: mysql_innodb_default_row_format
- tags:
- - database
-
-- name: "MySQL | Set innodb_default_row_format to dynamic"
- community.mysql.mysql_variables:
- variable: innodb_default_row_format
- value: dynamic
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
- login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- when:
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- - mysql_innodb_default_row_format.msg != 'dynamic'
- delegate_to: "{{ delegated_dbhost }}"
- tags:
- - database
-
-- name: "MySQL | Disable InnoDB Strict Mode"
- community.mysql.mysql_variables:
- variable: innodb_strict_mode
- value: 0
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
- login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- when:
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- - ansible_distribution_release == "buster"
- delegate_to: "{{ delegated_dbhost }}"
- tags:
- - database
-
-- name: "MySQL | Fetch sql create file"
- fetch:
- src: "{{ ls_output_create.stdout }}"
- dest: /tmp/{{ role_name }}/
- flat: true
- become: true
- when:
- - delegated_dbhost != inventory_hostname
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- tags:
- - database
-
-- name: "MySQL | Copy sql create file"
- ansible.builtin.copy:
- src: /tmp/{{ role_name }}/
- dest: "{{ ls_output_create.stdout | dirname }}"
- mode: "0640"
- delegate_to: "{{ delegated_dbhost }}"
- become: true
- when:
- - delegated_dbhost != inventory_hostname
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- tags:
- - database
-
-- name: "MySQL | Create database and import file"
- community.mysql.mysql_db:
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_dbuser if (ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7') else zabbix_server_mysql_login_user }}"
- login_password: "{{ zabbix_server_dbpassword if (ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7') else zabbix_server_mysql_login_password }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- name: "{{ zabbix_server_dbname }}"
- encoding: "{{ zabbix_server_dbencoding }}"
- collation: "{{ zabbix_server_dbcollation }}"
- state: import
- target: "{{ ls_output_create.stdout }}"
- use_shell: "{{ true if zabbix_server_version is version('5.0', '==') else false }}"
- when:
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- delegate_to: "{{ delegated_dbhost }}"
- tags:
- - database
-
-- name: "MySQL | Revert innodb_default_row_format to previous value"
- community.mysql.mysql_variables:
- variable: innodb_default_row_format
- value: "{{ mysql_innodb_default_row_format.msg }}"
- login_host: "{{ zabbix_server_mysql_login_host | default(omit) }}"
- login_user: "{{ zabbix_server_mysql_login_user | default(omit) }}"
- login_password: "{{ zabbix_server_mysql_login_password | default(omit) }}"
- login_port: "{{ zabbix_server_mysql_login_port | default(omit) }}"
- login_unix_socket: "{{ zabbix_server_mysql_login_unix_socket | default(omit) }}"
- when:
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- - mysql_innodb_default_row_format.msg != 'dynamic'
- delegate_to: "{{ delegated_dbhost }}"
- tags:
- - database
-
-- name: "MySQL | Check if we have sql_done files"
- ansible.builtin.file:
- path: /etc/zabbix/create.done
- state: touch
- mode: "0644"
- become: true
- when:
- - zabbix_server_database_sqlload | bool
- - mysql_schema_empty
- tags:
- - database
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/selinux.yml b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/selinux.yml
index fe203aed1..cd13dbbfd 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/tasks/selinux.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/tasks/selinux.yml
@@ -126,6 +126,6 @@
cmd: files/install_semodule.bsx
args:
creates: /etc/selinux/targeted/active/modules/400/zabbix_server_add/cil
- become: true
+ become: true
tags:
- config
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/vars/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_server/vars/Debian.yml
index 4074869e6..75f3751c2 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/vars/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/vars/Debian.yml
@@ -29,7 +29,20 @@ zabbix_valid_server_versions:
- 6.0
debian_keyring_path: /etc/apt/keyrings/
-zabbix_gpg_key: "{{ debian_keyring_path }}/zabbix-official-repo.asc"
-_zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_server_version }}"
+zabbix_gpg_key: "{{ debian_keyring_path }}zabbix-repo.asc"
+
+_zabbix_server_pgsql_dependencies:
+ - "{{ zabbix_server_install_database_client | ternary('postgresql-client', '') }}"
+ - python3-psycopg2
+
+_zabbix_server_mysql_dependencies:
+ - "{{ zabbix_server_install_database_client | ternary('default-mysql-client', '') }}"
+ - python3-pymysql
+
_zabbix_server_fping6location: /usr/bin/fping6
_zabbix_server_fpinglocation: /usr/bin/fping
+
+_zabbix_server_packages:
+ - "zabbix-server-{{ zabbix_server_database }}"
+ - "zabbix-sql-scripts"
+_zabbix_server_install_recommends: true
diff --git a/ansible_collections/community/zabbix/roles/zabbix_server/vars/RedHat.yml b/ansible_collections/community/zabbix/roles/zabbix_server/vars/RedHat.yml
index c2e0f14f3..fb20631f8 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_server/vars/RedHat.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_server/vars/RedHat.yml
@@ -18,19 +18,19 @@ zabbix_valid_server_versions:
- 6.2
- 6.0
-pgsql_depenencies:
- "9":
- - python3-psycopg2
- "8":
- - python3-psycopg2
+_zabbix_server_pgsql_dependencies:
+ - "{{ zabbix_server_install_database_client | ternary('postgresql', '') }}"
+ - python3-psycopg2
-mysql_client_pkgs:
- "9":
- - mysql
- - python3-PyMySQL
- "8":
- - mysql
- - python3-PyMySQL
+_zabbix_server_mysql_dependencies:
+ - "{{ zabbix_server_install_database_client | ternary('mysql', '') }}"
+ - python3-PyMySQL
_zabbix_server_fping6location: /usr/sbin/fping6
_zabbix_server_fpinglocation: /usr/sbin/fping
+
+_zabbix_server_packages:
+ - "zabbix-server-{{ zabbix_server_database }}-{{ zabbix_server_version }}.{{ zabbix_server_version_minor }}"
+ - "zabbix-sql-scripts-{{ zabbix_server_version }}.{{ zabbix_server_version_minor }}"
+_zabbix_server_disable_repo:
+ - epel
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/README.md b/ansible_collections/community/zabbix/roles/zabbix_web/README.md
index 5904f8288..aac6f9dc2 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/README.md
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/README.md
@@ -16,6 +16,7 @@
- [Apache configuration](#apache-configuration)
- [Nginx configuration](#nginx-configuration)
- [PHP-FPM](#php-fpm)
+ - [SElinux](#selinux)
- [Zabbix Server](#zabbix-server)
* [proxy](#proxy)
- [Example Playbook](#example-playbook)
@@ -65,6 +66,8 @@ See the following list of supported Operating Systems with the Zabbix releases.
| Debian 11 bullseye | V | V | V |
| Debian 10 buster | | | V |
+You can bypass this matrix by setting `enable_version_check: false`
+
# Installation
Installing this role is very simple: `ansible-galaxy install community.zabbix.zabbix_web`
@@ -94,6 +97,8 @@ The following is an overview of all available configuration defaults for this ro
* `zabbix_web_conf_mode`: Default: `0644`. The "mode" for the Zabbix configuration file.
* `zabbix_repo_deb_url`: The URL to the Zabbix repository. Default `http://repo.zabbix.com/zabbix/{{ zabbix_web_version }}/{{ ansible_distribution.lower() }}`
* `zabbix_repo_deb_component`: The repository component for Debian installs. Default `main`.
+* `zabbix_repo_deb_gpg_key_url`: The URL to download the Zabbix GPG key from. Default `http://repo.zabbix.com/zabbix-official-repo.key`.
+* `zabbix_repo_deb_include_deb_src`: True, if deb-src should be included in the zabbix.sources entry. Default `true`.
### Zabbix Web specific
@@ -116,7 +121,6 @@ The following is an overview of all available configuration defaults for this ro
* `zabbix_web_vhost_port`: The port on which Zabbix HTTP vhost is running.
* `zabbix_web_vhost_tls_port`: The port on which Zabbix HTTPS vhost is running.
* `zabbix_web_vhost_listen_ip`: On which interface the Apache Virtual Host is available.
-* `zabbix_apache_can_connect_ldap`: Default: `false`. Set SELinux boolean to allow httpd to connect to LDAP.
* `zabbix_web_max_execution_time`: PHP max execution time
* `zabbix_web_memory_limit`: PHP memory limit
* `zabbix_web_post_max_size`: PHP maximum post size
@@ -151,6 +155,13 @@ The following properties are specific to Zabbix 5.0 and for the PHP(-FPM) config
* `zabbix_php_fpm_conf_group`: The group of the owner of the socket file (When `zabbix_php_fpm_listen` contains a patch to a socket file).
+### SElinux
+
+* `zabbix_web_selinux`: Default: `False`. Enables an SELinux policy so that the web will run.
+* `selinux_allow_httpd_can_connect_zabbix`: Default: `false`. Set SELinux boolean to allow httpd to connect to zabbix.
+* `selinux_allow_httpd_can_connect_ldap`: Default: `false`. Set SELinux boolean to allow httpd to connect to LDAP.
+* `selinux_allow_httpd_can_network_connect_db`: Default: `false` Set SELinux boolean to allow httpd to connect databases over the network.
+
### Zabbix Server
* `zabbix_server_name`: The name of the Zabbix Server.
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/defaults/main.yml b/ansible_collections/community/zabbix/roles/zabbix_web/defaults/main.yml
index f37bb07da..53744bab9 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/defaults/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/defaults/main.yml
@@ -53,6 +53,7 @@ zabbix_web_apt_priority:
zabbix_web_version_minor: "*"
zabbix_repo_yum_gpgcheck: 0
zabbix_repo_yum_schema: https
+zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_web_version }}/{{ ansible_facts.lsb.id | default(ansible_facts['distribution']) | lower }}{% if ansible_facts['architecture'] == 'aarch64' and ansible_facts.lsb.id | default(ansible_facts['distribution']) in ['Debian', 'Ubuntu'] %}-arm64{% endif %}"
zabbix_repo_deb_component: main
zabbix_web_disable_repo:
- epel
@@ -86,9 +87,14 @@ zabbix_server_history_types:
- "uint"
- "dbl"
-zabbix_selinux: false
-# selinux_allow_zabbix_can_network: false
-# zabbix_apache_can_connect_ldap: false
+# SELinux specific
+zabbix_web_selinux: false
+selinux_allow_httpd_can_connect_ldap: false
+selinux_allow_httpd_can_network_connect_db: false
+selinux_allow_httpd_can_connect_zabbix: false
+
+zabbix_repo_deb_gpg_key_url: http://repo.zabbix.com/zabbix-official-repo.key
+zabbix_repo_deb_include_deb_src: true
# SAML certificates
# zabbix_saml_idp_crt:
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/Debian.yml
index ae1c7de26..d3c12fdac 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/Debian.yml
@@ -13,33 +13,6 @@
tags:
- always
-- name: "Debian | Update ansible_lsb fact"
- ansible.builtin.setup:
- gather_subset:
- - lsb
-
-- name: "Debian | Installing lsb-release"
- ansible.builtin.apt:
- pkg: lsb-release
- update_cache: true
- cache_valid_time: 3600
- force: true
- state: present
- environment:
- http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
- https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
- become: true
- tags:
- - install
-
-- name: "Debian | Repo URL"
- ansible.builtin.set_fact:
- zabbix_repo_deb_url: "{{ _zabbix_repo_deb_url }}/{{ ansible_lsb.id.lower() }}{{ '-arm64' if ansible_machine == 'aarch64' and ansible_lsb.id == 'debian' else ''}}"
- when:
- - zabbix_repo_deb_url is undefined
- tags:
- - always
-
- name: "Debian | Install PHP Dependencies"
ansible.builtin.apt:
pkg: "{{ zabbix_web_php_dependencies }}"
@@ -88,11 +61,15 @@
(ansible_distribution == "Debian" and ansible_distribution_major_version < "12")
- name: "Debian | Download gpg key"
+ when: not ansible_check_mode # Because get_url always has changed status in check_mode.
ansible.builtin.get_url:
- url: http://repo.zabbix.com/zabbix-official-repo.key
+ url: "{{ zabbix_repo_deb_gpg_key_url }}"
dest: "{{ zabbix_gpg_key }}"
mode: "0644"
force: true
+ environment:
+ http_proxy: "{{ zabbix_http_proxy | default(None) | default(omit) }}"
+ https_proxy: "{{ zabbix_https_proxy | default(None) | default(omit) }}"
become: true
tags:
- install
@@ -104,7 +81,7 @@
group: root
mode: 0644
content: |
- Types: deb deb-src
+ Types: deb{{ ' deb-src' if zabbix_repo_deb_include_deb_src }}
Enabled: yes
URIs: {{ zabbix_repo_deb_url }}
Suites: {{ ansible_distribution_release }}
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/RedHat.yml b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/RedHat.yml
index 30871017e..8dfb2e113 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/RedHat.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/RedHat.yml
@@ -57,3 +57,8 @@
- ansible_distribution_major_version == '9'
tags:
- install
+
+- name: "Configure SELinux when enabled"
+ ansible.builtin.include_tasks: selinux.yml
+ when:
+ - zabbix_web_selinux | bool
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/main.yml b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/main.yml
index b82d8486b..54a313a1c 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/main.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/main.yml
@@ -13,15 +13,16 @@
- name: Set More Variables
ansible.builtin.set_fact:
- zabbix_valid_version: "{{ zabbix_web_version|float in zabbix_valid_web_versions[ansible_distribution_major_version] }}"
zabbix_db_type_long: "{{ 'postgresql' if zabbix_server_database == 'pgsql' else 'mysql' }}"
tags:
- always
-- name: Stopping Install of Invalid Version
- ansible.builtin.fail:
- msg: Zabbix version {{ zabbix_web_version }} is not supported on {{ ansible_distribution }} {{ ansible_distribution_major_version }}
- when: not zabbix_valid_version
+- name: Check that version is supported
+ when: enable_version_check | default(true) | bool
+ ansible.builtin.assert:
+ that:
+ - "{{ zabbix_web_version|float in zabbix_valid_web_versions[ ansible_facts['distribution_major_version'] ] }}"
+ fail_msg: Zabbix version {{ zabbix_web_version }} is not supported on {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_major_version'] }}
tags:
- always
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/selinux.yml b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/selinux.yml
index 56e2ae05e..df5d388db 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/tasks/selinux.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/tasks/selinux.yml
@@ -12,7 +12,7 @@
become: true
when:
- ansible_os_family == "RedHat"
- - selinux_allow_zabbix_can_network
+ - ansible_selinux.status == "enabled"
- ansible_distribution_major_version == "7" or ansible_distribution_major_version == "6"
tags:
- install
@@ -30,23 +30,11 @@
become: true
when:
- ansible_os_family == "RedHat"
- - selinux_allow_zabbix_can_network
+ - ansible_selinux.status == "enabled"
- ansible_distribution_major_version|int >= 8
tags:
- install
-- name: "SELinux | RedHat | Enable zabbix_can_network SELinux boolean"
- ansible.posix.seboolean:
- name: zabbix_can_network
- state: true
- persistent: true
- become: true
- when:
- - ansible_os_family == "RedHat"
- - selinux_allow_zabbix_can_network
- tags:
- - config
-
- name: "SELinux | Allow httpd to connect to db (SELinux)"
ansible.posix.seboolean:
name: httpd_can_network_connect_db
@@ -55,7 +43,7 @@
become: true
when:
- ansible_selinux.status == "enabled"
- - selinux_allow_zabbix_can_network
+ - selinux_allow_httpd_can_network_connect_db | bool
tags:
- config
@@ -67,7 +55,7 @@
become: true
when:
- ansible_selinux.status == "enabled"
- - selinux_allow_zabbix_can_network
+ - selinux_allow_httpd_can_connect_zabbix | bool
tags:
- config
@@ -79,6 +67,6 @@
become: true
when:
- ansible_selinux.status == "enabled"
- - zabbix_apache_can_connect_ldap | bool
+ - selinux_allow_httpd_can_connect_ldap | bool
tags:
- config
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/templates/nginx_vhost.conf.j2 b/ansible_collections/community/zabbix/roles/zabbix_web/templates/nginx_vhost.conf.j2
index 7854b83ce..c04a0712c 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/templates/nginx_vhost.conf.j2
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/templates/nginx_vhost.conf.j2
@@ -20,7 +20,7 @@ server {
try_files $uri $uri/ =404;
}
- location /assets {
+ location /assets/ {
access_log off;
expires 10d;
}
@@ -70,9 +70,9 @@ server {
ssl_certificate {{ zabbix_web_tls_crt }};
ssl_certificate_key {{ zabbix_web_tls_key }};
- {{ (zabbix_web_ssl_cipher_suite is defined and zabbix_web_ssl_cipher_suite is not none) | ternary('', '# ') }}ssl_ciphers {{ zabbix_web_ssl_cipher_suite | default('') }}
- {{ (zabbix_web_SSLSessionCache is defined and zabbix_web_SSLSessionCache is not none) | ternary('', '# ') }}ssl_session_cache {{ zabbix_web_SSLSessionCache | default('') }}
- {{ (zabbix_web_SSLSessionCacheTimeout is defined and zabbix_web_SSLSessionCacheTimeout is not none) | ternary('', '# ') }}ssl_session_timeout {{ zabbix_web_SSLSessionCacheTimeout | default('') }}
+ {{ (zabbix_web_ssl_cipher_suite is defined and zabbix_web_ssl_cipher_suite is not none) | ternary('', '# ') }}ssl_ciphers {{ zabbix_web_ssl_cipher_suite | default('') }};
+ {{ (zabbix_web_SSLSessionCache is defined and zabbix_web_SSLSessionCache is not none) | ternary('', '# ') }}ssl_session_cache {{ zabbix_web_SSLSessionCache | default('') }};
+ {{ (zabbix_web_SSLSessionCacheTimeout is defined and zabbix_web_SSLSessionCacheTimeout is not none) | ternary('', '# ') }}ssl_session_timeout {{ zabbix_web_SSLSessionCacheTimeout | default('') }};
root /usr/share/zabbix;
index index.php;
@@ -85,7 +85,7 @@ server {
try_files $uri $uri/ =404;
}
- location /assets {
+ location /assets/ {
access_log off;
expires 10d;
}
diff --git a/ansible_collections/community/zabbix/roles/zabbix_web/vars/Debian.yml b/ansible_collections/community/zabbix/roles/zabbix_web/vars/Debian.yml
index 7b60c70bd..f49b27155 100644
--- a/ansible_collections/community/zabbix/roles/zabbix_web/vars/Debian.yml
+++ b/ansible_collections/community/zabbix/roles/zabbix_web/vars/Debian.yml
@@ -47,5 +47,4 @@ zabbix_valid_web_versions:
- 6.0
debian_keyring_path: /etc/apt/keyrings/
-zabbix_gpg_key: "{{ debian_keyring_path }}/zabbix-official-repo.asc"
-_zabbix_repo_deb_url: "http://repo.zabbix.com/zabbix/{{ zabbix_web_version }}"
+zabbix_gpg_key: "{{ debian_keyring_path }}zabbix-repo.asc"
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/meta/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/meta/main.yml
new file mode 100644
index 000000000..acdb704c8
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - setup_zabbix
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/tasks/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/tasks/main.yml
new file mode 100644
index 000000000..d893cbc34
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_correlation/tasks/main.yml
@@ -0,0 +1,328 @@
+---
+- name: test - create simple correlation
+ community.zabbix.zabbix_correlation:
+ name: new event tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_tag
+ tag: ok
+ operations:
+ - type: close_old_events
+ register: zbxcorrelation_create
+
+- name: assert that correlation was created
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create.changed is sameas True
+
+- name: test - update simple correlation (without changes)
+ community.zabbix.zabbix_correlation:
+ name: new event tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_tag
+ tag: ok
+ operations:
+ - type: close_old_events
+ register: zbxcorrelation_create
+
+- name: assert that correlation was not updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create.changed is sameas False
+
+- name: test - update simple correlation
+ community.zabbix.zabbix_correlation:
+ name: new event tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_tag
+ tag: ng
+ operations:
+ - type: close_old_events
+ register: zbxcorrelation_create
+
+- name: assert that correlation was updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create.changed is sameas True
+
+- name: test - delete simple correlation
+ community.zabbix.zabbix_correlation:
+ name: new event tag correlation
+ state: absent
+ register: zbxcorrelation_delete
+
+- name: assert that correlation was deleted
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_delete.changed is sameas True
+
+- name: prepare - create hostgroup
+ community.zabbix.zabbix_group:
+ host_groups:
+ - correlation_group_A
+ - correlation_group_B
+ state: present
+ register: zbxgroup_create
+
+- name: test - create custom_expression correlation
+ community.zabbix.zabbix_correlation:
+ name: new host group correlation
+ description: a custom description
+ filter:
+ evaltype: custom_expression
+ formula: A or B
+ conditions:
+ - type: new_event_host_group
+ hostgroup: correlation_group_A
+ operator: not_equal
+ formulaid: A
+ - type: new_event_host_group
+ hostgroup: correlation_group_B
+ operator: not_equal
+ formulaid: B
+ operations:
+ - type: close_old_events
+ register: zbxcorrelation_create
+
+- name: assert that correlation was created
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create.changed is sameas True
+
+- name: test - create custom_expression correlation (again)
+ community.zabbix.zabbix_correlation:
+ name: new host group correlation
+ description: a custom description
+ filter:
+ evaltype: custom_expression
+ formula: A or B
+ conditions:
+ - type: new_event_host_group
+ hostgroup: correlation_group_A
+ operator: not_equal
+ formulaid: A
+ - type: new_event_host_group
+ hostgroup: correlation_group_B
+ operator: not_equal
+ formulaid: B
+ operations:
+ - type: close_old_events
+ register: zbxcorrelation_create
+
+- name: assert that correlation was not updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create.changed is sameas False
+
+- name: test - delete custom_expression correlation
+ community.zabbix.zabbix_correlation:
+ name: new host group correlation
+ state: absent
+ register: zbxcorrelation_delete
+
+- name: assert that correlation was deleted
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_delete.changed is sameas True
+
+- name: cleanup - delete hostgroup
+ community.zabbix.zabbix_group:
+ host_groups:
+ - correlation_group_A
+ - correlation_group_B
+ state: absent
+ register: zbxgroup_delete
+
+- name: test - create correlation with old_event_tag condition
+ community.zabbix.zabbix_correlation:
+ name: tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: old_event_tag
+ tag: old_tag
+ operations:
+ - type: close_old_events
+ - type: close_new_event
+ register: zbxcorrelation_create
+
+- name: assert that correlation was created
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create.changed is sameas True
+
+- name: test - update correlation with new_event_tag condition
+ community.zabbix.zabbix_correlation:
+ name: tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_tag
+ tag: new_tag
+ operations:
+ - type: close_old_events
+ - type: close_new_event
+ register: zbxcorrelation_update
+
+- name: assert that correlation was updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_update.changed is sameas True
+
+- name: test - update correlation with event_tag_pair condition
+ community.zabbix.zabbix_correlation:
+ name: tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: event_tag_pair
+ oldtag: oldtag_pair
+ newtag: newtag_pair
+ operations:
+ - type: close_old_events
+ - type: close_new_event
+ register: zbxcorrelation_update
+
+- name: assert that correlation was updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_update.changed is sameas True
+
+- name: test - update correlation with old_event_tag_value condition
+ community.zabbix.zabbix_correlation:
+ name: tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: old_event_tag_value
+ tag: old_tag_value
+ value: old
+ operator: equal
+ operations:
+ - type: close_old_events
+ - type: close_new_event
+ register: zbxcorrelation_update
+
+- name: assert that correlation was updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_update.changed is sameas True
+
+- name: test - update correlation with new_event_tag_value condition
+ community.zabbix.zabbix_correlation:
+ name: tag correlation
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_tag_value
+ tag: new_tag_value
+ value: new
+ operator: equal
+ operations:
+ - type: close_old_events
+ - type: close_new_event
+ register: zbxcorrelation_update
+
+- name: assert that correlation was updated
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_update.changed is sameas True
+
+- name: test - delete tag correlation
+ community.zabbix.zabbix_correlation:
+ name: tag correlation
+ state: absent
+ register: zbxcorrelation_delete
+
+- name: assert that correlation was deleted
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_delete.changed is sameas True
+
+- name: prepare - create hostgroup
+ community.zabbix.zabbix_group:
+ host_groups:
+ - correlation_group
+ state: present
+ register: zbxgroup_create
+
+- name: test - create host group correlation with wrong operator (like)
+ community.zabbix.zabbix_correlation:
+ name: new host group correlation
+ description: a custom description
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_host_group
+ hostgroup: correlation_group
+ operator: like
+ operations:
+ - type: close_old_events
+ ignore_errors: yes
+ register: zbxcorrelation_create
+
+- name: assert that correlation was failed
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create is failed
+
+- name: test - create host group correlation with wrong operator (not_like)
+ community.zabbix.zabbix_correlation:
+ name: new host group correlation
+ description: a custom description
+ filter:
+ evaltype: and_or
+ conditions:
+ - type: new_event_host_group
+ hostgroup: correlation_group
+ operator: not_like
+ operations:
+ - type: close_old_events
+ ignore_errors: yes
+ register: zbxcorrelation_create
+
+- name: assert that correlation was failed
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create is failed
+
+- name: prepare - delete hostgroup
+ community.zabbix.zabbix_group:
+ host_groups:
+ - correlation_group
+ state: absent
+ register: zbxgroup_delete
+
+- name: test - create tag correlation with wrong formulaid
+ community.zabbix.zabbix_correlation:
+ name: new tag correlation
+ description: a custom description
+ filter:
+ evaltype: custom_expression
+ formula: a
+ conditions:
+ - type: new_event_tag_value
+ tag: new_tag_value
+ value: new
+ operator: equal
+ formulaid: a
+ operations:
+ - type: close_old_events
+ ignore_errors: yes
+ register: zbxcorrelation_create
+
+- name: assert that correlation was failed
+ ansible.builtin.assert:
+ that:
+ - zbxcorrelation_create is failed
+
+- name: test - delete custom_expression correlation
+ community.zabbix.zabbix_correlation:
+ name: new tag correlation
+ state: absent
+ register: zbxcorrelation_delete
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml
index a4829a051..20246a16b 100644
--- a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml
@@ -1348,6 +1348,78 @@
ansible.builtin.assert:
that: zbx_host_create_interfaceless is not changed
+- name: "test: attempt to delete host created earlier"
+ community.zabbix.zabbix_host:
+ host_name: ExampleHost
+ state: absent
+ register: zabbix_host1
+
+- name: deleting a host is a change, right?
+ ansible.builtin.assert:
+ that:
+ - "zabbix_host1 is changed"
+
+- name: "test: create host with IPMI values"
+ community.zabbix.zabbix_host:
+ host_name: ExampleHost
+ host_groups:
+ - Linux servers
+ - Zabbix servers
+ ipmi_authtype: 1
+ ipmi_privilege: 1
+ ipmi_username: "test"
+ ipmi_password: "test"
+ register: zabbix_ipmi_host
+
+- name: expect to succeed and that things have changed
+ ansible.builtin.assert:
+ that:
+ - "zabbix_ipmi_host is changed"
+
+- name: "test: update inventory of the created host"
+ community.zabbix.zabbix_host:
+ host_name: ExampleHost
+ inventory_mode: manual
+ inventory_zabbix:
+ notes: "Update inventory"
+ register: zabbix_ipmi_host
+
+- name: expect to succeed and that things have changed
+ ansible.builtin.assert:
+ that:
+ - "zabbix_ipmi_host is changed"
+
+- name: "test: create host with IPMI values without changes"
+ community.zabbix.zabbix_host:
+ host_name: ExampleHost
+ ipmi_authtype: 1
+ ipmi_privilege: 1
+ ipmi_username: "test"
+ ipmi_password: "test"
+ register: zabbix_ipmi_host
+
+- name: expect to succeed and that things have not changed
+ ansible.builtin.assert:
+ that:
+ - "zabbix_ipmi_host is not changed"
+
+- name: "test: create host with host group(empty list)"
+ community.zabbix.zabbix_host:
+ host_name: ExampleHost
+ visible_name: ExampleName
+ description: My ExampleHost Description
+ host_groups: []
+ status: disabled
+ state: present
+ ignore_errors: true
+ register: zbx_host_create_hostgroup_empty_list
+
+- name: expect to fail updating
+ ansible.builtin.assert:
+ that:
+ - zbx_host_create_hostgroup_empty_list is failed
+ - zbx_host_create_hostgroup_empty_list.msg == "host_groups must be not empty list."
+
- name: "cleanup"
community.zabbix.zabbix_host:
host_name: ExampleHost
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_maintenance/tasks/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_maintenance/tasks/main.yml
index 1b9c6f6bd..86d511d36 100644
--- a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_maintenance/tasks/main.yml
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_maintenance/tasks/main.yml
@@ -273,6 +273,56 @@
# that:
# - update_maintenance_host_tags.changed is sameas false
+- name: "test - Create maintenance with an active_since param"
+ community.zabbix.zabbix_maintenance:
+ name: maintenance
+ host_name: example
+ active_since: "1979-09-19"
+ state: present
+ register: create_maintenance_active_since_result
+
+- ansible.builtin.assert:
+ that:
+ - create_maintenance_active_since_result.changed is sameas true
+
+- name: "test - Create maintenance with a active_since param(again - expectations: false change will occur)"
+ community.zabbix.zabbix_maintenance:
+ name: maintenance
+ host_name: example
+ active_since: "1979-09-19"
+ state: present
+ register: create_maintenance_active_since_again_result
+
+- ansible.builtin.assert:
+ that:
+ - create_maintenance_active_since_again_result.changed is sameas false
+
+- name: "test - Create maintenance with an active_till param"
+ community.zabbix.zabbix_maintenance:
+ name: maintenance
+ host_name: example
+ active_since: "1979-09-19 00:00"
+ active_till: "1979-09-19 23:59"
+ state: present
+ register: create_maintenance_active_till_result
+
+- ansible.builtin.assert:
+ that:
+ - create_maintenance_active_till_result.changed is sameas true
+
+- name: "test - Create maintenance with a active_till param(again - expectations: false change will occur)"
+ community.zabbix.zabbix_maintenance:
+ name: maintenance
+ host_name: example
+ active_since: "1979-09-19 00:00"
+ active_till: "1979-09-19 23:59"
+ state: present
+ register: create_maintenance_active_till_again_result
+
+- ansible.builtin.assert:
+ that:
+ - create_maintenance_active_till_again_result.changed is sameas false
+
- name: "test - Delete maintenance"
community.zabbix.zabbix_maintenance:
name: maintenance
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_mediatype/tasks/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_mediatype/tasks/main.yml
index a49166d37..1ba2f6669 100644
--- a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_mediatype/tasks/main.yml
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_mediatype/tasks/main.yml
@@ -114,6 +114,29 @@
- ansible.builtin.assert:
that: zbxmediatype_reset.changed is sameas True
+ - name: test - check email mediatype content_type for html default
+ community.zabbix.zabbix_mediatype:
+ content_type: "html"
+ register: zbxmediatype_verif
+
+ - ansible.builtin.assert:
+ that: zbxmediatype_verif.changed is sameas False
+
+ - name: test - update email mediatype content_type to plaintext
+ community.zabbix.zabbix_mediatype:
+ content_type: "plaintext"
+ register: zbxmediatype_verif
+
+ - ansible.builtin.assert:
+ that: zbxmediatype_verif.changed is sameas True
+
+ - name: test - reset email mediatype content_type to default
+ community.zabbix.zabbix_mediatype:
+ register: zbxmediatype_reset
+
+ - ansible.builtin.assert:
+ that: zbxmediatype_reset.changed is sameas True
+
- name: test - update email mediatype concurrent settings
community.zabbix.zabbix_mediatype:
max_sessions: 99
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/meta/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/meta/main.yml
new file mode 100644
index 000000000..acdb704c8
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - setup_zabbix
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/tasks/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/tasks/main.yml
new file mode 100644
index 000000000..77c244df8
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_service_info/tasks/main.yml
@@ -0,0 +1,57 @@
+---
+- name: test - Create new Zabbix service
+ community.zabbix.zabbix_service:
+ name: ExampleService
+ description: ExampleService
+ sortorder: 0
+ propagation_rule: as_is
+ propagation_value: not_classified
+ algorithm: most_crit_of_child_serv
+ register: create_service_result
+
+- ansible.builtin.assert:
+ that:
+ - create_service_result.changed is sameas true
+
+- name: test - Create new Zabbix child service
+ community.zabbix.zabbix_service:
+ name: ExampleChildService
+ description: ExampleChildService
+ sortorder: 0
+ propagation_rule: as_is
+ propagation_value: not_classified
+ parents: ExampleService
+ problem_tags:
+ - tag: testtag
+ value: test
+ register: create_child_result
+
+- ansible.builtin.assert:
+ that:
+ - create_child_result.changed is sameas true
+
+- name: test - Get zabbix service information
+ community.zabbix.zabbix_service_info:
+ service_name: ExampleService
+ register: get_service_info_result
+
+- ansible.builtin.assert:
+ that:
+ - get_service_info_result["zabbix_service"].name == "ExampleService"
+ - get_service_info_result["zabbix_service"].children | length > 0
+ - get_service_info_result["zabbix_service"].children[0].name == "ExampleChildService"
+ - get_service_info_result["zabbix_service"].propagation_rule == "0"
+ - get_service_info_result["zabbix_service"].propagation_value == "0"
+ - get_service_info_result["zabbix_service"].sortorder == "0"
+
+- name: test - cleanup test Zabbix child service
+ community.zabbix.zabbix_service:
+ state: absent
+ sortorder: 0
+ name: ExampleChildService
+
+- name: test - cleanup test Zabbix service
+ community.zabbix.zabbix_service:
+ state: absent
+ sortorder: 0
+ name: ExampleService
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.json b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.json
new file mode 100644
index 000000000..7d4c37a52
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.json
@@ -0,0 +1,49 @@
+{
+ "zabbix_export": {
+ "version": "6.0",
+ "date": "2024-01-04T18:26:37Z",
+ "groups": [
+ {
+ "uuid": "7df96b18c230490a9a0a9e2307226338",
+ "name": "Templates"
+ },
+ {
+ "uuid": "a571c0d144b14fd4a87a9d9b2aa9fcd6",
+ "name": "Templates/Applications"
+ }
+ ],
+ "templates": [
+ {
+ "uuid": "cd837ef0edb14e4e875f409bc90af546",
+ "template": "ExampleTemplate",
+ "name": "ExampleTemplate",
+ "templates": [
+ {
+ "name": "FTP Service"
+ },
+ {
+ "name": "Zabbix proxy health"
+ }
+ ],
+ "groups": [
+ {
+ "name": "Templates"
+ },
+ {
+ "name": "Templates/Applications"
+ }
+ ],
+ "macros": [
+ {
+ "macro": "{$EXAMPLE_MACRO1}",
+ "value": "1000"
+ },
+ {
+ "macro": "{$EXAMPLE_MACRO2}",
+ "value": "text"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.xml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.xml
new file mode 100644
index 000000000..3d423c692
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<zabbix_export>
+ <version>6.0</version>
+ <date>2024-01-04T18:26:29Z</date>
+ <groups>
+ <group>
+ <uuid>7df96b18c230490a9a0a9e2307226338</uuid>
+ <name>Templates</name>
+ </group>
+ <group>
+ <uuid>a571c0d144b14fd4a87a9d9b2aa9fcd6</uuid>
+ <name>Templates/Applications</name>
+ </group>
+ </groups>
+ <templates>
+ <template>
+ <uuid>cd837ef0edb14e4e875f409bc90af546</uuid>
+ <template>ExampleTemplate</template>
+ <name>ExampleTemplate</name>
+ <templates>
+ <template>
+ <name>FTP Service</name>
+ </template>
+ <template>
+ <name>Zabbix proxy health</name>
+ </template>
+ </templates>
+ <groups>
+ <group>
+ <name>Templates</name>
+ </group>
+ <group>
+ <name>Templates/Applications</name>
+ </group>
+ </groups>
+ <macros>
+ <macro>
+ <macro>{$EXAMPLE_MACRO1}</macro>
+ <value>1000</value>
+ </macro>
+ <macro>
+ <macro>{$EXAMPLE_MACRO2}</macro>
+ <value>text</value>
+ </macro>
+ </macros>
+ </template>
+ </templates>
+</zabbix_export>
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.yaml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.yaml
new file mode 100644
index 000000000..0112b1fc7
--- /dev/null
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/files/template4_60_higher.yaml
@@ -0,0 +1,23 @@
+zabbix_export:
+ version: '6.0'
+ date: '2024-01-04T18:26:17Z'
+ groups:
+ - uuid: 7df96b18c230490a9a0a9e2307226338
+ name: Templates
+ - uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6
+ name: Templates/Applications
+ templates:
+ - uuid: cd837ef0edb14e4e875f409bc90af546
+ template: ExampleTemplate
+ name: ExampleTemplate
+ templates:
+ - name: 'FTP Service'
+ - name: 'Zabbix proxy health'
+ groups:
+ - name: Templates
+ - name: Templates/Applications
+ macros:
+ - macro: '{$EXAMPLE_MACRO1}'
+ value: '1000'
+ - macro: '{$EXAMPLE_MACRO2}'
+ value: text
diff --git a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/tasks/main.yml b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/tasks/main.yml
index 69aabe6b0..ce02916ee 100644
--- a/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/tasks/main.yml
+++ b/ansible_collections/community/zabbix/tests/integration/targets/test_zabbix_template/tasks/main.yml
@@ -370,6 +370,83 @@
- delete_zabbix_template_result.changed is sameas false
#
+# template_file_context parameter
+#
+
+- name: Import Zabbix template from a file using configuration.importcompare api
+ block:
+ - name: Import Zabbix template from YAML file.
+ community.zabbix.zabbix_template:
+ template_yaml: "{{ lookup('file', 'template4_60_higher.yaml') }}"
+ state: present
+ register: import_template_yaml
+
+ - ansible.builtin.assert:
+ that:
+ - import_template_xml.changed is sameas true
+
+ - name: Import Zabbix same template from XML file.
+ community.zabbix.zabbix_template:
+ template_xml: "{{ lookup('file', 'template4_60_higher.xml') }}"
+ state: present
+ register: import_same_template_xml
+
+ - ansible.builtin.assert:
+ that:
+ - import_same_template_xml.changed is sameas false
+
+ - name: Delete Zabbix template.
+ community.zabbix.zabbix_template:
+ template_name: ExampleTemplate
+ state: absent
+ register: delete_zabbix_template_result
+
+ - ansible.builtin.assert:
+ that:
+ - delete_zabbix_template_result.changed is sameas true
+
+ - name: Import Zabbix same template from XML file (after deleting template).
+ community.zabbix.zabbix_template:
+ template_xml: "{{ lookup('file', 'template4_60_higher.xml') }}"
+ state: present
+ register: import_same_template_xml
+
+ - ansible.builtin.assert:
+ that:
+ - import_same_template_xml.changed is sameas true
+
+ - name: Import Zabbix same template from JSON file.
+ community.zabbix.zabbix_template:
+ template_json: "{{ lookup('file', 'template4_60_higher.json') }}"
+ state: present
+ register: import_same_template_json
+
+ - ansible.builtin.assert:
+ that:
+ - import_same_template_json.changed is sameas false
+
+ - name: Delete Zabbix template.
+ community.zabbix.zabbix_template:
+ template_name: ExampleTemplate
+ state: absent
+ register: delete_zabbix_template_result
+
+ - ansible.builtin.assert:
+ that:
+ - delete_zabbix_template_result.changed is sameas true
+
+ - name: Delete Zabbix template (idempotency check).
+ community.zabbix.zabbix_template:
+ template_name: ExampleTemplate
+ state: absent
+ register: delete_zabbix_template_result
+
+ - ansible.builtin.assert:
+ that:
+ - delete_zabbix_template_result.changed is sameas false
+
+
+#
# Unicode stuff
#