diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-26 04:06:02 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-26 04:06:02 +0000 |
commit | e3eb94c23206603103f3c4faec6c227f59a1544c (patch) | |
tree | f2639459807ba88f55fc9c54d745bd7075d7f15c /ansible_collections/community | |
parent | Releasing progress-linux version 9.4.0+dfsg-1~progress7.99u1. (diff) | |
download | ansible-e3eb94c23206603103f3c4faec6c227f59a1544c.tar.xz ansible-e3eb94c23206603103f3c4faec6c227f59a1544c.zip |
Merging upstream version 9.5.1+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/community')
370 files changed, 9088 insertions, 5571 deletions
diff --git a/ansible_collections/community/aws/CHANGELOG.rst b/ansible_collections/community/aws/CHANGELOG.rst index 651b7c763..b47d79fe4 100644 --- a/ansible_collections/community/aws/CHANGELOG.rst +++ b/ansible_collections/community/aws/CHANGELOG.rst @@ -4,6 +4,29 @@ community.aws Release Notes .. contents:: Topics +v7.2.0 +====== + +Release Summary +--------------- + +This release includes a new module ``dynamodb_table_info``, new features for the ``glue_job`` and ``msk_cluster`` modules, and a bugfix for the ``aws_ssm`` connection plugin. + +Minor Changes +------------- + +- glue_job - add support for 2 new instance types which are G.4X and G.8X (https://github.com/ansible-collections/community.aws/pull/2048). +- msk_cluster - Support for additional ``m5`` and ``m7g`` types of MSK clusters (https://github.com/ansible-collections/community.aws/pull/1947). + +Bugfixes +-------- + +- ssm(connection) - fix bucket region logic when region is ``us-east-1`` (https://github.com/ansible-collections/community.aws/pull/1908). + +New Modules +----------- + +- dynamodb_table_info - Returns information about a Dynamo DB table v7.1.0 ====== @@ -23,7 +46,7 @@ Minor Changes Bugfixes -------- -- aws_ssm - disable `enable-bracketed-paste` to fix issue with amazon linux 2023 and other OSes (https://github.com/ansible-collections/community.aws/issues/1756) +- aws_ssm - disable ``enable-bracketed-paste`` to fix issue with amazon linux 2023 and other OSes (https://github.com/ansible-collections/community.aws/issues/1756) v7.0.0 ====== @@ -134,7 +157,6 @@ This release brings some new plugins and features. Several bugfixes, breaking ch The community.aws collection has dropped support for ``botocore<1.25.0`` and ``boto3<1.22.0``. Support for Python 3.6 has also been dropped. - Minor Changes ------------- @@ -207,7 +229,6 @@ Release Summary This release contains a number of bugfixes for various modules, as well as new features for the ``ec2_launch_template`` and ``msk_cluster`` modules. This is the last planned minor release prior to the release of version 6.0.0. - Minor Changes ------------- @@ -303,7 +324,6 @@ modules. As well as improvements to the ``ecs_cluster``, ``ec2_ecr``, ``ecs_service``, ``iam_role`` and ``ssm_parameter`` plugins. - Minor Changes ------------- @@ -369,7 +389,6 @@ Support for ``ansible-core<2.11`` has also been dropped. This release also brings some new features, bugfixes, breaking changes and deprecated features. - Minor Changes ------------- @@ -531,7 +550,6 @@ Release Summary This release contains a minor bugfix for the ``sns_topic`` module as well as corrections to the documentation for various modules. This is the last planned release of the 4.x series. - Bugfixes -------- @@ -889,7 +907,6 @@ Release Summary Following the release of community.aws 5.0.0, 3.6.0 is a bugfix release and the final planned release for the 3.x series. - Minor Changes ------------- diff --git a/ansible_collections/community/aws/FILES.json b/ansible_collections/community/aws/FILES.json index 6bc607963..58ea3a1a7 100644 --- a/ansible_collections/community/aws/FILES.json +++ b/ansible_collections/community/aws/FILES.json @@ -179,7 +179,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "71507aa348f024b04b28a249ccb60a22d09d95eaf0e2f503add687640fc648e9", + "chksum_sha256": "a4a404a462b4858f815f4cdd2b1651a4301a2cc2f868ac9f1ca14bfcec74d313", "format": 1 }, { @@ -214,7 +214,7 @@ "name": "docs/docsite/rst/CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5c20e11dfc1704180b5d197a68107a5a6092c324a99739646c42bb0e1a0dc8a4", + "chksum_sha256": "56d5b1f84c1fe53d65c7450a967427dd1e64a5ae6f5029e786b617686a98eb69", "format": 1 }, { @@ -242,7 +242,7 @@ "name": "meta/runtime.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6195942600514b3a6fd22586eaba89cccdc9bc09265aff576f7a2de8346c4a6c", + "chksum_sha256": "73da55c9ac6fc4170daa33c7085e944bb0c61bfa045bd8f0794f66c27bacfb36", "format": 1 }, { @@ -270,7 +270,7 @@ "name": "plugins/connection/aws_ssm.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "72738ace4fc3fabddcee868e0ad6f01ae82976b1aed13319bdbe5ddef1c8e6c6", + "chksum_sha256": "dc7e2bc595289e435c5ed3b4dd3de07d8bed518d67cdfe52ab465aee341bfc6c", "format": 1 }, { @@ -305,7 +305,7 @@ "name": "plugins/module_utils/common.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9ae9caf904353f2952d5257bea7cb0b4a4e96668dcc9871c82809cd0b4f38f4f", + "chksum_sha256": "0f464ad15f459dc646c9596544ec189cf67ff07225c4a22fdba46b0daae73cdc", "format": 1 }, { @@ -687,6 +687,13 @@ "format": 1 }, { + "name": "plugins/modules/dynamodb_table_info.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d77ba73e2bf62068b6ffeb53e04b797b4c79cc1fa8f4cf613df7ab5be0536b6d", + "format": 1 + }, + { "name": "plugins/modules/dynamodb_ttl.py", "ftype": "file", "chksum_type": "sha256", @@ -1068,7 +1075,7 @@ "name": "plugins/modules/glue_job.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b9d5d95b21a49c62e1f86bd8f5e30ab45a9ec0bc81dc680a5f3233e712833108", + "chksum_sha256": "5bc96be59165bee14b0e1186072eace1039229420bae41ea50d4cfa9caed560d", "format": 1 }, { @@ -1166,7 +1173,7 @@ "name": "plugins/modules/msk_cluster.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c4211d04238671d5f57b0214e55d12e541c9619b6275c120868019fd3eaf56b4", + "chksum_sha256": "b78414661d661838a4e31182c127c40867669efca69d283a4202ec70da7676b7", "format": 1 }, { @@ -3609,14 +3616,14 @@ "name": "tests/integration/targets/dynamodb_table/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "564f5d43b5e448142ce041267325d9149d1743af5027a7875064248ba656ce22", + "chksum_sha256": "94cd8b7ef587ffd1abc1b33950c1dbfa69f559040c3c02b55932cfb1b9601598", "format": 1 }, { "name": "tests/integration/targets/dynamodb_table/tasks/test_pay_per_request.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "45cf53627344eb31b7bb79bddca9d6e53d9a04a84136c5c2118e4ffd5b3e3694", + "chksum_sha256": "fb8ba194bb9558e1ac5b4f204546b6c3e39c722a74cb8f0627657a7dea463b45", "format": 1 }, { @@ -5408,7 +5415,7 @@ "name": "tests/integration/targets/elb_target/tasks/lambda_target.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3e8f8a7ad8f8d4395ec5529c296ec4297050541026ee8fcbbaa46cb0c0a78640", + "chksum_sha256": "a17e3f3cbd23a65e7aec0ffb1da5e15ea7241d33d5a0ea2323ec9eccd15c349c", "format": 1 }, { @@ -7256,7 +7263,7 @@ "name": "tests/integration/targets/s3_bucket_notification/tasks/test_lambda_notifications.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d401f6906f366e920d10516f37ad5b53b4748e7063b0272ee84e84e09c0477fd", + "chksum_sha256": "f6a147ffee70552754175c3f75247106b13911eee09f39fe7649f642af25100d", "format": 1 }, { @@ -7620,7 +7627,7 @@ "name": "tests/integration/targets/secretsmanager_secret/tasks/rotation.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "01d2a81ec50be52c30ed22608cc917025834e709a3e43ded577e7676c34e5e57", + "chksum_sha256": "e4b8e9c86cd550dc3c11a0e6d8838bbf37c7da0bee0f8b46c57666dd9fa94b9c", "format": 1 }, { @@ -8425,7 +8432,7 @@ "name": "tests/integration/targets/sns_topic/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "00bff28386d44b4c5681c9ab8852075291b3999c2bd8490798605ad84d8d4154", + "chksum_sha256": "c9f6e39100c348ee75fb0de739f853d58c86b7b1050dc3e94ca3a391dbf83d1a", "format": 1 }, { @@ -9139,7 +9146,7 @@ "name": "tests/sanity/ignore-2.17.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c9271c547f92773ba4ed8df6eb56394c85deefb66078ae7336b285aee9d252d9", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "format": 1 }, { @@ -13311,7 +13318,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5c20e11dfc1704180b5d197a68107a5a6092c324a99739646c42bb0e1a0dc8a4", + "chksum_sha256": "56d5b1f84c1fe53d65c7450a967427dd1e64a5ae6f5029e786b617686a98eb69", "format": 1 }, { diff --git a/ansible_collections/community/aws/MANIFEST.json b/ansible_collections/community/aws/MANIFEST.json index 224e6ba06..514454326 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.1.0", + "version": "7.2.0", "authors": [ "Ansible (https://github.com/ansible)" ], @@ -28,7 +28,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "efadd5485c903284fc4f80439e50ff696569304185ef6c966c442c2b5603c5c8", + "chksum_sha256": "160883c33483553569816c9173e6073c59ded3c77bc8fdab656e7c72b1794d3a", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/aws/changelogs/changelog.yaml b/ansible_collections/community/aws/changelogs/changelog.yaml index ea65a58be..e299d000e 100644 --- a/ansible_collections/community/aws/changelogs/changelog.yaml +++ b/ansible_collections/community/aws/changelogs/changelog.yaml @@ -3713,7 +3713,7 @@ releases: 7.1.0: changes: bugfixes: - - aws_ssm - disable `enable-bracketed-paste` to fix issue with amazon linux + - aws_ssm - disable ``enable-bracketed-paste`` to fix issue with amazon linux 2023 and other OSes (https://github.com/ansible-collections/community.aws/issues/1756) minor_changes: - aws_ssm - Updated the documentation to explicitly state that an S3 bucket @@ -3734,3 +3734,24 @@ releases: - release.yml - ssm-fedora34.yml release_date: '2024-01-10' + 7.2.0: + changes: + bugfixes: + - ssm(connection) - fix bucket region logic when region is ``us-east-1`` (https://github.com/ansible-collections/community.aws/pull/1908). + minor_changes: + - glue_job - add support for 2 new instance types which are G.4X and G.8X (https://github.com/ansible-collections/community.aws/pull/2048). + - msk_cluster - Support for additional ``m5`` and ``m7g`` types of MSK clusters + (https://github.com/ansible-collections/community.aws/pull/1947). + release_summary: This release includes a new module ``dynamodb_table_info``, + new features for the ``glue_job`` and ``msk_cluster`` modules, and a bugfix + for the ``aws_ssm`` connection plugin. + fragments: + - 1908-fix_find_out_bucket_region_logic.yml + - 1947-add_support_msk_addtinal_type.yml + - 20240402-lambda-test-runtime.yml + - 2048-add-new-instance-types-in-gluejob.yaml + modules: + - description: Returns information about a Dynamo DB table + name: dynamodb_table_info + namespace: '' + release_date: '2024-04-05' diff --git a/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst b/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst index 651b7c763..b47d79fe4 100644 --- a/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst +++ b/ansible_collections/community/aws/docs/docsite/rst/CHANGELOG.rst @@ -4,6 +4,29 @@ community.aws Release Notes .. contents:: Topics +v7.2.0 +====== + +Release Summary +--------------- + +This release includes a new module ``dynamodb_table_info``, new features for the ``glue_job`` and ``msk_cluster`` modules, and a bugfix for the ``aws_ssm`` connection plugin. + +Minor Changes +------------- + +- glue_job - add support for 2 new instance types which are G.4X and G.8X (https://github.com/ansible-collections/community.aws/pull/2048). +- msk_cluster - Support for additional ``m5`` and ``m7g`` types of MSK clusters (https://github.com/ansible-collections/community.aws/pull/1947). + +Bugfixes +-------- + +- ssm(connection) - fix bucket region logic when region is ``us-east-1`` (https://github.com/ansible-collections/community.aws/pull/1908). + +New Modules +----------- + +- dynamodb_table_info - Returns information about a Dynamo DB table v7.1.0 ====== @@ -23,7 +46,7 @@ Minor Changes Bugfixes -------- -- aws_ssm - disable `enable-bracketed-paste` to fix issue with amazon linux 2023 and other OSes (https://github.com/ansible-collections/community.aws/issues/1756) +- aws_ssm - disable ``enable-bracketed-paste`` to fix issue with amazon linux 2023 and other OSes (https://github.com/ansible-collections/community.aws/issues/1756) v7.0.0 ====== @@ -134,7 +157,6 @@ This release brings some new plugins and features. Several bugfixes, breaking ch The community.aws collection has dropped support for ``botocore<1.25.0`` and ``boto3<1.22.0``. Support for Python 3.6 has also been dropped. - Minor Changes ------------- @@ -207,7 +229,6 @@ Release Summary This release contains a number of bugfixes for various modules, as well as new features for the ``ec2_launch_template`` and ``msk_cluster`` modules. This is the last planned minor release prior to the release of version 6.0.0. - Minor Changes ------------- @@ -303,7 +324,6 @@ modules. As well as improvements to the ``ecs_cluster``, ``ec2_ecr``, ``ecs_service``, ``iam_role`` and ``ssm_parameter`` plugins. - Minor Changes ------------- @@ -369,7 +389,6 @@ Support for ``ansible-core<2.11`` has also been dropped. This release also brings some new features, bugfixes, breaking changes and deprecated features. - Minor Changes ------------- @@ -531,7 +550,6 @@ Release Summary This release contains a minor bugfix for the ``sns_topic`` module as well as corrections to the documentation for various modules. This is the last planned release of the 4.x series. - Bugfixes -------- @@ -889,7 +907,6 @@ Release Summary Following the release of community.aws 5.0.0, 3.6.0 is a bugfix release and the final planned release for the 3.x series. - Minor Changes ------------- diff --git a/ansible_collections/community/aws/meta/runtime.yml b/ansible_collections/community/aws/meta/runtime.yml index 5d05436df..4c6bc7291 100644 --- a/ansible_collections/community/aws/meta/runtime.yml +++ b/ansible_collections/community/aws/meta/runtime.yml @@ -89,6 +89,7 @@ action_groups: - dms_endpoint - dms_replication_subnet_group - dynamodb_table + - dynamodb_table_info - dynamodb_ttl - ec2_ami_copy - ec2_asg diff --git a/ansible_collections/community/aws/plugins/connection/aws_ssm.py b/ansible_collections/community/aws/plugins/connection/aws_ssm.py index 5186179f4..5c2d6d577 100644 --- a/ansible_collections/community/aws/plugins/connection/aws_ssm.py +++ b/ansible_collections/community/aws/plugins/connection/aws_ssm.py @@ -430,7 +430,10 @@ class Connection(ConnectionBase): bucket_location = tmp_s3_client.get_bucket_location( Bucket=(self.get_option("bucket_name")), ) - bucket_region = bucket_location["LocationConstraint"] + if bucket_location["LocationConstraint"]: + bucket_region = bucket_location["LocationConstraint"] + else: + bucket_region = "us-east-1" if self.get_option("bucket_endpoint_url"): return self.get_option("bucket_endpoint_url"), bucket_region diff --git a/ansible_collections/community/aws/plugins/module_utils/common.py b/ansible_collections/community/aws/plugins/module_utils/common.py index 0c4374729..321349a1d 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.1.0" +COMMUNITY_AWS_COLLECTION_VERSION = "7.2.0" diff --git a/ansible_collections/community/aws/plugins/modules/dynamodb_table_info.py b/ansible_collections/community/aws/plugins/modules/dynamodb_table_info.py new file mode 100644 index 000000000..66349e2d7 --- /dev/null +++ b/ansible_collections/community/aws/plugins/modules/dynamodb_table_info.py @@ -0,0 +1,292 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: dynamodb_table_info +version_added: 7.2.0 +short_description: Returns information about a Dynamo DB table +description: + - Returns information about the Dynamo DB table, including the current status of the table, + when it was created, the primary key schema, and any indexes on the table. +author: + - Aubin Bikouo (@abikouo) +options: + name: + description: + - The name of the table to describe. + required: true + type: str +extends_documentation_fragment: + - amazon.aws.common.modules + - amazon.aws.region.modules + - amazon.aws.boto3 +""" + +EXAMPLES = r""" +- name: Return information about the DynamoDB table named 'my-table' + community.aws.dynamodb_table_info: + name: my-table +""" + +RETURN = r""" +table: + description: The returned table params from the describe API call. + returned: success + type: complex + contains: + table_name: + description: The name of the table. + returned: always + type: str + table_status: + description: The current state of the table. + returned: always + type: str + sample: 'ACTIVE' + creation_date_time: + description: The date and time when the table was created, in UNIX epoch time format. + returned: always + type: str + table_size_bytes: + description: The total size of the specified table, in bytes. + returned: always + type: int + item_count: + description: The number of items in the specified table. + returned: always + type: int + table_arn: + description: The Amazon Resource Name (ARN) that uniquely identifies the table. + returned: always + type: str + table_id: + description: Unique identifier for the table for which the backup was created. + returned: always + type: str + attribute_definitions: + description: A list of attributes for describing the key schema for the table and indexes. + returned: always + type: complex + contains: + attribute_name: + description: A name for the attribute. + type: str + returned: always + attribute_type: + description: The data type for the attribute, S (String), N (Number) and B (Binary). + type: str + returned: always + key_schema: + description: A list of key schemas that specify the attributes that make up the primary key of a table, or the key attributes of an index. + returned: always + type: complex + contains: + attribute_name: + description: The name of a key attribute. + type: str + returned: always + key_type: + description: The role that this key attribute will assume, 'HASH' for partition key, 'RANGE' for sort key + type: str + returned: always + billing_mode: + description: Controls how you are charged for read and write throughput and how you manage capacity. + returned: always + type: str + local_secondary_indexes: + description: Represents one or more local secondary indexes on the table. + returned: if any, on the table + type: list + elements: dict + global_secondary_indexes: + description: The global secondary indexes of table. + returned: if any, on the table + type: list + elements: dict + stream_specification: + description: The current DynamoDB Streams configuration for the table. + returned: if any, on the table + type: complex + contains: + stream_enabled: + description: Indicates whether DynamoDB Streams is enabled (true) or disabled (false) on the table. + type: bool + returned: always + sample: true + stream_view_type: + description: When an item in the table is modified, stream_view_type determines what information is written to the stream for this table. + type: str + returned: always + sample: KEYS_ONLY + latest_stream_label: + description: A timestamp, in ISO 8601 format, for this stream. + type: str + returned: if any on the table + latest_stream_arn: + description: The Amazon Resource Name (ARN) that uniquely identifies the latest stream for this table. + returned: if any on the table + type: str + global_table_version: + description: Represents the version of global tables in use, if the table is replicated across AWS Regions. + type: str + returned: if the table is replicated + replicas: + description: Represents replicas of the table. + type: list + elements: dict + returned: if any on the table + source_backup_arn: + description: The Amazon Resource Name (ARN) of the backup from which the table was restored. + type: str + returned: if any, on the table + source_table_arn: + description: The ARN of the source table of the backup that is being restored. + type: str + returned: if any, on the table + restore_date_time: + description: Point in time or source backup time. + type: str + returned: if any, on table + restore_in_progress: + description: Indicates if a restore is in progress or not. + type: bool + returned: if any, on table + sse_description: + description: The description of the server-side encryption status on the specified table. + type: dict + returned: if any, on table + sample: {} + archival_summary: + description: Contains information about the table archive. + type: complex + returned: if any, on table + contains: + archival_date_time: + description: The date and time when table archival was initiated by DynamoDB, in UNIX epoch time format. + type: str + returned: always + archival_reason: + description: The reason DynamoDB archived the table. + type: str + returned: always + sample: INACCESSIBLE_ENCRYPTION_CREDENTIALS + archival_backup_arn: + description: The Amazon Resource Name (ARN) of the backup the table was archived to, when applicable in the archival reason. + type: str + returned: always + table_class: + description: The table class of the specified table. + type: str + returned: if any on the table + sample: STANDARD_INFREQUENT_ACCESS + deletion_protection_enabled: + description: Indicates whether deletion protection is enabled (true) or disabled (false) on the table. + type: bool + returned: always + sample: true + provisioned_throughput: + description: The provisioned throughput settings for the table. + type: dict + returned: always + sample: '{"number_of_decreases_today": 0, "read_capacity_units": 1, "write_capacity_units": 1}' + tags: + description: A dict of tags associated with the DynamoDB table. + returned: always + type: dict +""" + +try: + import botocore +except ImportError: + pass # Handled by AnsibleAWSModule + +from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict + +from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict + +from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule + + +# ResourceNotFoundException is expected here if the table doesn't exist +@AWSRetry.jittered_backoff(catch_extra_error_codes=["LimitExceededException", "ResourceInUseException"]) +def _describe_table(client, **params): + return client.describe_table(**params) + + +def describe_dynamodb_table(module): + table_name = module.params.get("name") + retry_decorator = AWSRetry.jittered_backoff( + catch_extra_error_codes=["LimitExceededException", "ResourceInUseException", "ResourceNotFoundException"], + ) + client = module.client("dynamodb", retry_decorator=retry_decorator) + try: + table = _describe_table(client, TableName=table_name) + except is_boto3_error_code("ResourceNotFoundException"): + module.exit_json(table={}) + except ( + botocore.exceptions.ClientError, + botocore.exceptions.BotoCoreError, + ) as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg="Failed to describe table") + + table = table["Table"] + try: + tags = client.list_tags_of_resource(aws_retry=True, ResourceArn=table["TableArn"])["Tags"] + except is_boto3_error_code("AccessDeniedException"): + module.warn("Permission denied when listing tags") + tags = [] + except ( + botocore.exceptions.ClientError, + botocore.exceptions.BotoCoreError, + ) as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg="Failed to list table tags") + + table = camel_dict_to_snake_dict(table) + table["tags"] = boto3_tag_list_to_ansible_dict(tags) + + if "table_class_summary" in table: + table["table_class"] = table["table_class_summary"]["table_class"] + del table["table_class_summary"] + + # billing_mode_summary doesn't always seem to be set but is always set for PAY_PER_REQUEST + # and when updating the billing_mode + if "billing_mode_summary" in table: + table["billing_mode"] = table["billing_mode_summary"]["billing_mode"] + del table["billing_mode_summary"] + else: + table["billing_mode"] = "PROVISIONED" + + # Restore summary + if "restore_summary" in table: + table["source_backup_arn"] = table["restore_summary"].get("source_backup_arn", "") + table["source_table_arn"] = table["restore_summary"].get("source_table_arn", "") + table["restore_date_time"] = table["restore_summary"].get("restore_date_time", "") + table["restore_in_progress"] = table["restore_summary"].get("restore_in_progress") + del table["restore_summary"] + + module.exit_json(table=table) + + +def main(): + argument_spec = dict( + name=dict( + required=True, + ), + ) + + module = AnsibleAWSModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + describe_dynamodb_table(module) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/community/aws/plugins/modules/glue_job.py b/ansible_collections/community/aws/plugins/modules/glue_job.py index 256779975..10ad102e3 100644 --- a/ansible_collections/community/aws/plugins/modules/glue_job.py +++ b/ansible_collections/community/aws/plugins/modules/glue_job.py @@ -95,7 +95,8 @@ options: worker_type: description: - The type of predefined worker that is allocated when a job runs. - choices: [ 'Standard', 'G.1X', 'G.2X' ] + - Support for instance types C(G.4X( and C(G.8X) was added in community.aws release 7.2.0. + choices: [ 'Standard', 'G.1X', 'G.2X', 'G.4X', 'G.8X' ] type: str version_added: 1.5.0 notes: @@ -465,7 +466,7 @@ def main(): state=dict(required=True, choices=["present", "absent"], type="str"), tags=dict(type="dict", aliases=["resource_tags"]), timeout=dict(type="int"), - worker_type=dict(choices=["Standard", "G.1X", "G.2X"], type="str"), + worker_type=dict(choices=["Standard", "G.1X", "G.2X", "G.4X", "G.8X"], type="str"), ) module = AnsibleAWSModule( diff --git a/ansible_collections/community/aws/plugins/modules/msk_cluster.py b/ansible_collections/community/aws/plugins/modules/msk_cluster.py index aa0383294..9ecf053f8 100644 --- a/ansible_collections/community/aws/plugins/modules/msk_cluster.py +++ b/ansible_collections/community/aws/plugins/modules/msk_cluster.py @@ -54,6 +54,17 @@ options: - kafka.m5.xlarge - kafka.m5.2xlarge - kafka.m5.4xlarge + - kafka.m5.8xlarge + - kafka.m5.12xlarge + - kafka.m5.16xlarge + - kafka.m5.24xlarge + - kafka.m7g.large + - kafka.m7g.xlarge + - kafka.m7g.2xlarge + - kafka.m7g.4xlarge + - kafka.m7g.8xlarge + - kafka.m7g.12xlarge + - kafka.m7g.16xlarge default: kafka.t3.small type: str ebs_volume_size: @@ -662,6 +673,17 @@ def main(): "kafka.m5.xlarge", "kafka.m5.2xlarge", "kafka.m5.4xlarge", + "kafka.m5.8xlarge", + "kafka.m5.12xlarge", + "kafka.m5.16xlarge", + "kafka.m5.24xlarge", + "kafka.m7g.large", + "kafka.m7g.xlarge", + "kafka.m7g.2xlarge", + "kafka.m7g.4xlarge", + "kafka.m7g.8xlarge", + "kafka.m7g.12xlarge", + "kafka.m7g.16xlarge", ], default="kafka.t3.small", ), diff --git a/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/main.yml b/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/main.yml index 268e61bae..5b3592f30 100644 --- a/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/main.yml +++ b/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/main.yml @@ -30,6 +30,16 @@ that: - create_table is successful - create_table is changed + + - name: Ensure the table was not created + dynamodb_table_info: + name: "{{ table_name }}" + register: table_info + + - name: Assert the table was not created + assert: + that: + - not table_info.table - name: Create table dynamodb_table: @@ -65,6 +75,17 @@ - create_table.table_name == table_name - create_table.write_capacity == 1 + - name: Ensure the table was created + dynamodb_table_info: + name: "{{ table_name }}" + register: table_info + + - name: Assert the table was created + assert: + that: + - table_info.table + - 'table_info.table.attribute_definitions == [{"attribute_name": table_index, "attribute_type": table_index_type[0]}]' + - name: Create table - idempotent - check_mode dynamodb_table: state: present diff --git a/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/test_pay_per_request.yml b/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/test_pay_per_request.yml index b469a1b51..301d22c06 100644 --- a/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/test_pay_per_request.yml +++ b/ansible_collections/community/aws/tests/integration/targets/dynamodb_table/tasks/test_pay_per_request.yml @@ -15,6 +15,16 @@ - create_table is successful - create_table is changed +- name: Ensure the table was not created + dynamodb_table_info: + name: "{{ table_name_on_demand }}" + register: _table + +- name: Assert the table does not exist + assert: + that: + - not _table.table + - name: Create table - pay-per-request dynamodb_table: state: present @@ -32,6 +42,17 @@ - create_table is changed - create_table.billing_mode == "PAY_PER_REQUEST" +- name: Ensure the table was created + dynamodb_table_info: + name: "{{ table_name_on_demand }}" + register: _table + +- name: Assert the table has been created with the expected billing mode + assert: + that: + - _table.table + - _table.table.billing_mode == 'PAY_PER_REQUEST' + - name: Create table - pay-per-request - check failure dynamodb_table: state: present @@ -71,6 +92,16 @@ - create_complex_table is successful - create_complex_table is changed +- name: Ensure the table was not created + dynamodb_table_info: + name: "{{ table_name_on_demand_complex }}" + register: _complex_table + +- name: Assert the table does not exist + assert: + that: + - not _complex_table.table + - name: Create complex table - check failure on index dynamodb_table: state: present @@ -120,6 +151,17 @@ - create_complex_table.table_name == table_name_on_demand_complex - create_complex_table.tags == tags_default +- name: Ensure the table was created + dynamodb_table_info: + name: "{{ table_name_on_demand_complex }}" + register: _complex_table + +- name: Assert the table has been created + assert: + that: + - _complex_table.table + - _complex_table.table.billing_mode == 'PAY_PER_REQUEST' + - name: Update complex table billing_mode dynamodb_table: state: present @@ -140,3 +182,13 @@ - convert_complex_table is changed - '"billing_mode" in convert_complex_table' - convert_complex_table.billing_mode == "PROVISIONED" + +- name: Read table info + dynamodb_table_info: + name: "{{ table_name_on_demand_complex }}" + register: _complex_table + +- name: Assert the table has been updated + assert: + that: + - _complex_table.table.billing_mode == 'PROVISIONED' 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 abc4cc5d0..c4271cdd6 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 @@ -23,7 +23,7 @@ name: "{{ lambda_name }}" state: present zip_file: /tmp/lambda.zip - runtime: python3.7 + runtime: python3.12 role: "{{ ROLE_ARN.arn }}" handler: ansible_lambda_target.lambda_handler timeout: 30 diff --git a/ansible_collections/community/aws/tests/integration/targets/s3_bucket_notification/tasks/test_lambda_notifications.yml b/ansible_collections/community/aws/tests/integration/targets/s3_bucket_notification/tasks/test_lambda_notifications.yml index 23ed32e32..b4cc8a6e0 100644 --- a/ansible_collections/community/aws/tests/integration/targets/s3_bucket_notification/tasks/test_lambda_notifications.yml +++ b/ansible_collections/community/aws/tests/integration/targets/s3_bucket_notification/tasks/test_lambda_notifications.yml @@ -41,7 +41,7 @@ name: '{{ lambda_name }}' state: present role: "{{ lambda_role_name }}" - runtime: python3.7 + runtime: python3.12 zip_file: '{{function_res.dest}}' handler: lambda_function.lambda_handler memory_size: '128' diff --git a/ansible_collections/community/aws/tests/integration/targets/secretsmanager_secret/tasks/rotation.yml b/ansible_collections/community/aws/tests/integration/targets/secretsmanager_secret/tasks/rotation.yml index 697c5ecc2..77151227d 100644 --- a/ansible_collections/community/aws/tests/integration/targets/secretsmanager_secret/tasks/rotation.yml +++ b/ansible_collections/community/aws/tests/integration/targets/secretsmanager_secret/tasks/rotation.yml @@ -55,7 +55,7 @@ name: "{{ lambda_name }}" state: present zip_file: "{{ tmp.path }}/hello_world.zip" - runtime: 'python3.9' + runtime: 'python3.12' role: "{{ iam_role_output.arn }}" handler: 'hello_world.lambda_handler' register: lambda_output @@ -169,7 +169,7 @@ name: "{{ lambda_name }}" state: absent zip_file: "{{ tmp.path }}/hello_world.zip" - runtime: 'python3.9' + runtime: 'python3.12' role: "{{ secret_manager_role }}" handler: 'hello_world.lambda_handler' ignore_errors: yes diff --git a/ansible_collections/community/aws/tests/integration/targets/sns_topic/tasks/main.yml b/ansible_collections/community/aws/tests/integration/targets/sns_topic/tasks/main.yml index 00f3f71d9..25f636832 100644 --- a/ansible_collections/community/aws/tests/integration/targets/sns_topic/tasks/main.yml +++ b/ansible_collections/community/aws/tests/integration/targets/sns_topic/tasks/main.yml @@ -309,7 +309,7 @@ name: '{{ sns_topic_lambda_name }}' state: present zip_file: '{{ tempdir.path }}/{{ sns_topic_lambda_function }}.zip' - runtime: python3.9 + runtime: python3.12 role: '{{ sns_topic_lambda_role }}' handler: '{{ sns_topic_lambda_function }}.handler' register: lambda_result diff --git a/ansible_collections/community/aws/tests/sanity/ignore-2.17.txt b/ansible_collections/community/aws/tests/sanity/ignore-2.17.txt index 67d3693df..e69de29bb 100644 --- a/ansible_collections/community/aws/tests/sanity/ignore-2.17.txt +++ b/ansible_collections/community/aws/tests/sanity/ignore-2.17.txt @@ -1,2 +0,0 @@ -plugins/connection/aws_ssm.py yamllint:unparsable-with-libyaml # bug in ansible-test - https://github.com/ansible/ansible/issues/82353 -plugins/inventory/aws_mq.py yamllint:unparsable-with-libyaml # bug in ansible-test - https://github.com/ansible/ansible/issues/82353 diff --git a/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml index 8697acd43..19a36fb46 100644 --- a/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml +++ b/ansible_collections/community/crypto/.azure-pipelines/azure-pipelines.yml @@ -65,6 +65,17 @@ stages: test: 'devel/sanity/extra' - 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: [] @@ -87,17 +98,6 @@ stages: test: '2.15/sanity/1' - name: Units test: '2.15/units/1' - - stage: Ansible_2_14 - displayName: Sanity & Units 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: Sanity - test: '2.14/sanity/1' - - name: Units - test: '2.14/units/1' ### Docker - stage: Docker_devel displayName: Docker devel @@ -111,8 +111,21 @@ stages: test: fedora39 - name: Ubuntu 22.04 test: ubuntu2204 - - name: Alpine 3 - test: alpine3 + - name: Alpine 3.19 + test: alpine319 + groups: + - 1 + - 2 + - stage: Docker_2_17 + displayName: Docker 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: 2.17/linux/{0} + targets: + - name: Alpine 3.19 + test: alpine319 groups: - 1 - 2 @@ -128,6 +141,8 @@ stages: test: fedora38 - name: openSUSE 15 test: opensuse15 + - name: Alpine 3 + test: alpine3 groups: - 1 - 2 @@ -146,19 +161,6 @@ stages: groups: - 1 - 2 - - stage: Docker_2_14 - displayName: Docker 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.14/linux/{0} - targets: - - name: Ubuntu 20.04 - test: ubuntu2004 - groups: - - 1 - - 2 ### Community Docker - stage: Docker_community_devel @@ -188,8 +190,8 @@ stages: parameters: testFormat: devel/{0} targets: - - name: Alpine 3.18 - test: alpine/3.18 + - name: Alpine 3.19 + test: alpine/3.19 - name: Fedora 39 test: fedora/39 - name: Ubuntu 22.04 @@ -204,12 +206,25 @@ stages: parameters: testFormat: devel/{0} targets: - - name: macOS 13.2 - test: macos/13.2 + - name: macOS 14.3 + test: macos/14.3 - name: RHEL 9.3 test: rhel/9.3 - - name: FreeBSD 13.2 - test: freebsd/13.2 + - name: FreeBSD 14.0 + test: freebsd/14.0 + groups: + - 1 + - 2 + - stage: Remote_2_17 + displayName: Remote 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: 2.17/{0} + targets: + - name: FreeBSD 13.3 + test: freebsd/13.3 groups: - 1 - 2 @@ -221,10 +236,14 @@ stages: parameters: testFormat: 2.16/{0} targets: + - name: macOS 13.2 + test: macos/13.2 - name: RHEL 9.2 test: rhel/9.2 - name: RHEL 8.8 test: rhel/8.8 + - name: FreeBSD 13.2 + test: freebsd/13.2 groups: - 1 - 2 @@ -249,38 +268,34 @@ stages: groups: - 1 - 2 - - stage: Remote_2_14 - displayName: Remote 2.14 +### Generic + - stage: Generic_devel + displayName: Generic devel dependsOn: [] jobs: - template: templates/matrix.yml parameters: - testFormat: 2.14/{0} + nameFormat: Python {0} + testFormat: devel/generic/{0} targets: - #- name: macOS 12.0 - # test: macos/12.0 - - name: RHEL 9.0 - test: rhel/9.0 - #- name: FreeBSD 12.4 - # test: freebsd/12.4 + - test: 3.8 + # - test: 3.9 + # - test: "3.10" + - test: "3.11" + - test: "3.12" groups: - 1 - 2 -### Generic - - stage: Generic_devel - displayName: Generic devel + - stage: Generic_2_17 + displayName: Generic 2.17 dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Python {0} - testFormat: devel/generic/{0} + testFormat: 2.17/generic/{0} targets: - - test: 3.7 - # - test: 3.8 - # - test: 3.9 - # - test: "3.10" - - test: "3.11" + - test: "3.7" - test: "3.12" groups: - 1 @@ -314,19 +329,6 @@ stages: groups: - 1 - 2 - - stage: Generic_2_14 - displayName: Generic 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - nameFormat: Python {0} - testFormat: 2.14/generic/{0} - targets: - - test: 3.9 - groups: - - 1 - - 2 ## Finally @@ -334,22 +336,22 @@ stages: condition: succeededOrFailed() dependsOn: - Ansible_devel + - Ansible_2_17 - Ansible_2_16 - Ansible_2_15 - - Ansible_2_14 - Remote_devel_extra_vms - Remote_devel + - Remote_2_17 - Remote_2_16 - Remote_2_15 - - Remote_2_14 - Docker_devel + - Docker_2_17 - Docker_2_16 - Docker_2_15 - - Docker_2_14 - Docker_community_devel - Generic_devel + - Generic_2_17 - Generic_2_16 - Generic_2_15 - - Generic_2_14 jobs: - template: templates/coverage.yml diff --git a/ansible_collections/community/crypto/.github/workflows/ansible-test.yml b/ansible_collections/community/crypto/.github/workflows/ansible-test.yml index be831028b..d31e861c4 100644 --- a/ansible_collections/community/crypto/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/crypto/.github/workflows/ansible-test.yml @@ -34,6 +34,7 @@ jobs: - '2.11' - '2.12' - '2.13' + - '2.14' # 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 @@ -74,6 +75,7 @@ jobs: - '2.11' - '2.12' - '2.13' + - '2.14' steps: - name: >- @@ -253,6 +255,23 @@ jobs: docker: default python: '3.8' target: azp/generic/2/ + # 2.14 + - ansible: '2.14' + docker: ubuntu2004 + python: '' + target: azp/posix/1/ + - ansible: '2.14' + docker: ubuntu2004 + python: '' + target: azp/posix/2/ + - ansible: '2.14' + docker: default + python: '3.9' + target: azp/generic/1/ + - ansible: '2.14' + docker: default + python: '3.9' + target: azp/generic/2/ steps: - name: >- diff --git a/ansible_collections/community/crypto/.github/workflows/reuse.yml b/ansible_collections/community/crypto/.github/workflows/reuse.yml index 29b1f951a..7646c5cfb 100644 --- a/ansible_collections/community/crypto/.github/workflows/reuse.yml +++ b/ansible_collections/community/crypto/.github/workflows/reuse.yml @@ -29,4 +29,4 @@ jobs: rm -f tests/integration/targets/*/files/roots/*.pem - name: REUSE Compliance Check - uses: fsfe/reuse-action@v2 + uses: fsfe/reuse-action@v3 diff --git a/ansible_collections/community/crypto/CHANGELOG.md b/ansible_collections/community/crypto/CHANGELOG.md index f54352a87..1652a3ad2 100644 --- a/ansible_collections/community/crypto/CHANGELOG.md +++ b/ansible_collections/community/crypto/CHANGELOG.md @@ -1,217 +1,224 @@ # Community Crypto Release Notes **Topics** + +- <a href="#v2-19-0">v2\.19\.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="#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-plugins">New Plugins</a> - - <a href="#filter">Filter</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="#release-summary-1">Release Summary</a> - - <a href="#bugfixes-1">Bugfixes</a> + - <a href="#release-summary-2">Release Summary</a> + - <a href="#bugfixes-2">Bugfixes</a> - <a href="#v2-17-0">v2\.17\.0</a> - - <a href="#release-summary-2">Release Summary</a> - - <a href="#minor-changes-1">Minor Changes</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-3">Release Summary</a> - - <a href="#bugfixes-2">Bugfixes</a> + - <a href="#release-summary-4">Release Summary</a> + - <a href="#bugfixes-3">Bugfixes</a> - <a href="#v2-16-1">v2\.16\.1</a> - - <a href="#release-summary-4">Release Summary</a> - - <a href="#bugfixes-3">Bugfixes</a> + - <a href="#release-summary-5">Release Summary</a> + - <a href="#bugfixes-4">Bugfixes</a> - <a href="#v2-16-0">v2\.16\.0</a> - - <a href="#release-summary-5">Release Summary</a> - - <a href="#minor-changes-2">Minor Changes</a> - - <a href="#bugfixes-4">Bugfixes</a> + - <a href="#release-summary-6">Release Summary</a> + - <a href="#minor-changes-3">Minor Changes</a> + - <a href="#bugfixes-5">Bugfixes</a> - <a href="#v2-15-1">v2\.15\.1</a> - - <a href="#release-summary-6">Release Summary</a> - - <a href="#bugfixes-5">Bugfixes</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="#release-summary-7">Release Summary</a> - - <a href="#minor-changes-3">Minor Changes</a> - - <a href="#deprecated-features-1">Deprecated Features</a> - - <a href="#bugfixes-6">Bugfixes</a> - - <a href="#new-plugins-1">New Plugins</a> - - <a href="#filter-1">Filter</a> - - <a href="#lookup">Lookup</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="#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-8">Release Summary</a> - - <a href="#bugfixes-7">Bugfixes</a> - - <a href="#known-issues">Known Issues</a> + - <a href="#release-summary-9">Release Summary</a> + - <a href="#bugfixes-8">Bugfixes</a> + - <a href="#known-issues">Known Issues</a> - <a href="#v2-14-0">v2\.14\.0</a> - - <a href="#release-summary-9">Release Summary</a> - - <a href="#minor-changes-4">Minor Changes</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-10">Release Summary</a> - - <a href="#bugfixes-8">Bugfixes</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-11">Release Summary</a> - - <a href="#minor-changes-5">Minor Changes</a> - - <a href="#deprecated-features-2">Deprecated Features</a> - - <a href="#bugfixes-9">Bugfixes</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="#release-summary-12">Release Summary</a> - - <a href="#minor-changes-6">Minor Changes</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="#release-summary-13">Release Summary</a> + - <a href="#release-summary-14">Release Summary</a> - <a href="#v2-11-0">v2\.11\.0</a> - - <a href="#release-summary-14">Release Summary</a> - - <a href="#minor-changes-7">Minor Changes</a> - - <a href="#bugfixes-10">Bugfixes</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="#release-summary-15">Release Summary</a> - - <a href="#bugfixes-11">Bugfixes</a> - - <a href="#new-plugins-2">New Plugins</a> - - <a href="#filter-2">Filter</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="#release-summary-16">Release Summary</a> - - <a href="#minor-changes-8">Minor Changes</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="#release-summary-17">Release Summary</a> + - <a href="#release-summary-18">Release Summary</a> - <a href="#v2-8-0">v2\.8\.0</a> - - <a href="#release-summary-18">Release Summary</a> - - <a href="#minor-changes-9">Minor Changes</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="#release-summary-19">Release Summary</a> - - <a href="#bugfixes-12">Bugfixes</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="#release-summary-20">Release Summary</a> - - <a href="#minor-changes-10">Minor Changes</a> - - <a href="#bugfixes-13">Bugfixes</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="#release-summary-21">Release Summary</a> - - <a href="#minor-changes-11">Minor Changes</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="#release-summary-22">Release Summary</a> - - <a href="#minor-changes-12">Minor Changes</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="#release-summary-23">Release Summary</a> - - <a href="#deprecated-features-3">Deprecated Features</a> - - <a href="#bugfixes-14">Bugfixes</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="#release-summary-24">Release Summary</a> + - <a href="#release-summary-25">Release Summary</a> - <a href="#v2-3-3">v2\.3\.3</a> - - <a href="#release-summary-25">Release Summary</a> - - <a href="#bugfixes-15">Bugfixes</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-26">Release Summary</a> - - <a href="#bugfixes-16">Bugfixes</a> + - <a href="#release-summary-27">Release Summary</a> + - <a href="#bugfixes-17">Bugfixes</a> - <a href="#v2-3-1">v2\.3\.1</a> - - <a href="#release-summary-27">Release Summary</a> - - <a href="#bugfixes-17">Bugfixes</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="#release-summary-28">Release Summary</a> - - <a href="#minor-changes-13">Minor Changes</a> - - <a href="#bugfixes-18">Bugfixes</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="#release-summary-29">Release Summary</a> - - <a href="#bugfixes-19">Bugfixes</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="#release-summary-30">Release Summary</a> - - <a href="#bugfixes-20">Bugfixes</a> + - <a href="#release-summary-31">Release Summary</a> + - <a href="#bugfixes-21">Bugfixes</a> - <a href="#v2-2-2">v2\.2\.2</a> - - <a href="#release-summary-31">Release Summary</a> - - <a href="#bugfixes-21">Bugfixes</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="#release-summary-32">Release Summary</a> - - <a href="#bugfixes-22">Bugfixes</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="#release-summary-33">Release Summary</a> - - <a href="#minor-changes-14">Minor Changes</a> - - <a href="#bugfixes-23">Bugfixes</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="#release-summary-34">Release Summary</a> - - <a href="#minor-changes-15">Minor Changes</a> - - <a href="#bugfixes-24">Bugfixes</a> - - <a href="#new-modules">New Modules</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="#release-summary-35">Release Summary</a> + - <a href="#release-summary-36">Release Summary</a> - <a href="#v2-0-1">v2\.0\.1</a> - - <a href="#release-summary-36">Release Summary</a> - - <a href="#minor-changes-16">Minor Changes</a> - - <a href="#bugfixes-25">Bugfixes</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-37">Release Summary</a> - - <a href="#minor-changes-17">Minor Changes</a> - - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a> - - <a href="#deprecated-features-4">Deprecated Features</a> - - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a> - - <a href="#bugfixes-26">Bugfixes</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="#release-summary-38">Release Summary</a> - - <a href="#bugfixes-27">Bugfixes</a> + - <a href="#release-summary-39">Release Summary</a> + - <a href="#bugfixes-28">Bugfixes</a> - <a href="#v1-9-3">v1\.9\.3</a> - - <a href="#release-summary-39">Release Summary</a> - - <a href="#bugfixes-28">Bugfixes</a> + - <a href="#release-summary-40">Release Summary</a> + - <a href="#bugfixes-29">Bugfixes</a> - <a href="#v1-9-2">v1\.9\.2</a> - - <a href="#release-summary-40">Release Summary</a> + - <a href="#release-summary-41">Release Summary</a> - <a href="#v1-9-1">v1\.9\.1</a> - - <a href="#release-summary-41">Release Summary</a> + - <a href="#release-summary-42">Release Summary</a> - <a href="#v1-9-0">v1\.9\.0</a> - - <a href="#release-summary-42">Release Summary</a> - - <a href="#minor-changes-18">Minor Changes</a> - - <a href="#bugfixes-29">Bugfixes</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="#release-summary-43">Release Summary</a> - - <a href="#minor-changes-19">Minor Changes</a> - - <a href="#bugfixes-30">Bugfixes</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="#release-summary-44">Release Summary</a> - - <a href="#bugfixes-31">Bugfixes</a> + - <a href="#release-summary-45">Release Summary</a> + - <a href="#bugfixes-32">Bugfixes</a> - <a href="#v1-7-0">v1\.7\.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="#new-modules-1">New Modules</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="#release-summary-46">Release Summary</a> - - <a href="#bugfixes-33">Bugfixes</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="#release-summary-47">Release Summary</a> - - <a href="#bugfixes-34">Bugfixes</a> + - <a href="#release-summary-48">Release Summary</a> + - <a href="#bugfixes-35">Bugfixes</a> - <a href="#v1-6-0">v1\.6\.0</a> - - <a href="#release-summary-48">Release Summary</a> - - <a href="#minor-changes-21">Minor Changes</a> - - <a href="#deprecated-features-5">Deprecated Features</a> - - <a href="#bugfixes-35">Bugfixes</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="#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="#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="#release-summary-50">Release Summary</a> - - <a href="#minor-changes-23">Minor Changes</a> - - <a href="#bugfixes-37">Bugfixes</a> + - <a href="#release-summary-51">Release Summary</a> + - <a href="#minor-changes-24">Minor Changes</a> + - <a href="#bugfixes-38">Bugfixes</a> - <a href="#v1-3-0">v1\.3\.0</a> - - <a href="#release-summary-51">Release Summary</a> - - <a href="#minor-changes-24">Minor Changes</a> - - <a href="#bugfixes-38">Bugfixes</a> - - <a href="#new-modules-2">New Modules</a> + - <a href="#release-summary-52">Release Summary</a> + - <a href="#minor-changes-25">Minor Changes</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="#release-summary-52">Release Summary</a> - - <a href="#minor-changes-25">Minor Changes</a> - - <a href="#security-fixes">Security Fixes</a> - - <a href="#bugfixes-39">Bugfixes</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="#bugfixes-40">Bugfixes</a> - <a href="#v1-1-1">v1\.1\.1</a> - - <a href="#release-summary-53">Release Summary</a> - - <a href="#bugfixes-40">Bugfixes</a> + - <a href="#release-summary-54">Release Summary</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="#minor-changes-26">Minor Changes</a> - - <a href="#bugfixes-41">Bugfixes</a> - - <a href="#new-modules-3">New Modules</a> + - <a href="#release-summary-55">Release Summary</a> + - <a href="#minor-changes-27">Minor Changes</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="#release-summary-55">Release Summary</a> - - <a href="#minor-changes-27">Minor Changes</a> - - <a href="#deprecated-features-7">Deprecated Features</a> - - <a href="#removed-features-previously-deprecated-1">Removed Features \(previously deprecated\)</a> - - <a href="#bugfixes-42">Bugfixes</a> - - <a href="#new-modules-4">New Modules</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="#new-modules-5">New Modules</a> -<a id="v2-18-0"></a> -## v2\.18\.0 +<a id="v2-19-0"></a> +## v2\.19\.0 <a id="release-summary"></a> ### Release Summary @@ -221,16 +228,45 @@ Bugfix and feature release\. <a id="minor-changes"></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)\)\. +* 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> ### 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)\)\. +* 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> ### 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> +### New Modules + +* x509\_certificate\_convert \- Convert X\.509 certificates + +<a id="v2-18-0"></a> +## v2\.18\.0 + +<a id="release-summary-1"></a> +### Release Summary + +Bugfix and feature release\. + +<a id="minor-changes-1"></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> +### 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> +### 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)\)\. * luks\_device \- fixed module falsely outputting <code>changed\=false</code> when trying to add a new slot with a key that is already present in another slot\. The module now rejects adding keys that are already present in another slot \([https\://github\.com/ansible\-collections/community\.crypto/pull/710](https\://github\.com/ansible\-collections/community\.crypto/pull/710)\)\. * luks\_device \- fixed testing of LUKS passphrases in when specifying a keyslot for cryptsetup version 2\.0\.3\. The output of this cryptsetup version slightly differs from later versions \([https\://github\.com/ansible\-collections/community\.crypto/pull/710](https\://github\.com/ansible\-collections/community\.crypto/pull/710)\)\. @@ -247,12 +283,12 @@ Bugfix and feature release\. <a id="v2-17-1"></a> ## v2\.17\.1 -<a id="release-summary-1"></a> +<a id="release-summary-2"></a> ### Release Summary Bugfix release for compatibility with cryptography 42\.0\.0\. -<a id="bugfixes-1"></a> +<a id="bugfixes-2"></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)\)\. @@ -262,12 +298,12 @@ Bugfix release for compatibility with cryptography 42\.0\.0\. <a id="v2-17-0"></a> ## v2\.17\.0 -<a id="release-summary-2"></a> +<a id="release-summary-3"></a> ### Release Summary Feature release\. -<a id="minor-changes-1"></a> +<a id="minor-changes-2"></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)\)\. @@ -275,12 +311,12 @@ Feature release\. <a id="v2-16-2"></a> ## v2\.16\.2 -<a id="release-summary-3"></a> +<a id="release-summary-4"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-2"></a> +<a id="bugfixes-3"></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)\)\. @@ -291,12 +327,12 @@ Bugfix release\. <a id="v2-16-1"></a> ## v2\.16\.1 -<a id="release-summary-4"></a> +<a id="release-summary-5"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-3"></a> +<a id="bugfixes-4"></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)\)\. @@ -304,17 +340,17 @@ Bugfix release\. <a id="v2-16-0"></a> ## v2\.16\.0 -<a id="release-summary-5"></a> +<a id="release-summary-6"></a> ### Release Summary Bugfix release\. -<a id="minor-changes-2"></a> +<a id="minor-changes-3"></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-4"></a> +<a id="bugfixes-5"></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)\)\. @@ -322,12 +358,12 @@ Bugfix release\. <a id="v2-15-1"></a> ## v2\.15\.1 -<a id="release-summary-6"></a> +<a id="release-summary-7"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-5"></a> +<a id="bugfixes-6"></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)\)\. @@ -335,22 +371,22 @@ Bugfix release\. <a id="v2-15-0"></a> ## v2\.15\.0 -<a id="release-summary-7"></a> +<a id="release-summary-8"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-3"></a> +<a id="minor-changes-4"></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-1"></a> +<a id="deprecated-features-2"></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-6"></a> +<a id="bugfixes-7"></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)\)\. @@ -372,7 +408,7 @@ Bugfix and feature release\. <a id="v2-14-1"></a> ## v2\.14\.1 -<a id="release-summary-8"></a> +<a id="release-summary-9"></a> ### Release Summary Bugfix and maintenance release with updated documentation\. @@ -385,7 +421,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-7"></a> +<a id="bugfixes-8"></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)\)\. @@ -398,12 +434,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-9"></a> +<a id="release-summary-10"></a> ### Release Summary Feature release\. -<a id="minor-changes-4"></a> +<a id="minor-changes-5"></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)\)\. @@ -413,12 +449,12 @@ Feature release\. <a id="v2-13-1"></a> ## v2\.13\.1 -<a id="release-summary-10"></a> +<a id="release-summary-11"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-8"></a> +<a id="bugfixes-9"></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)\)\. @@ -427,22 +463,22 @@ Bugfix release\. <a id="v2-13-0"></a> ## v2\.13\.0 -<a id="release-summary-11"></a> +<a id="release-summary-12"></a> ### Release Summary Bugfix and maintenance release\. -<a id="minor-changes-5"></a> +<a id="minor-changes-6"></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-2"></a> +<a id="deprecated-features-3"></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-9"></a> +<a id="bugfixes-10"></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)\)\. @@ -451,12 +487,12 @@ Bugfix and maintenance release\. <a id="v2-12-0"></a> ## v2\.12\.0 -<a id="release-summary-12"></a> +<a id="release-summary-13"></a> ### Release Summary Feature release\. -<a id="minor-changes-6"></a> +<a id="minor-changes-7"></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)\)\. @@ -464,7 +500,7 @@ Feature release\. <a id="v2-11-1"></a> ## v2\.11\.1 -<a id="release-summary-13"></a> +<a id="release-summary-14"></a> ### Release Summary Maintenance release with improved documentation\. @@ -472,17 +508,17 @@ Maintenance release with improved documentation\. <a id="v2-11-0"></a> ## v2\.11\.0 -<a id="release-summary-14"></a> +<a id="release-summary-15"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-7"></a> +<a id="minor-changes-8"></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-10"></a> +<a id="bugfixes-11"></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)\)\. @@ -492,12 +528,12 @@ Feature and bugfix release\. <a id="v2-10-0"></a> ## v2\.10\.0 -<a id="release-summary-15"></a> +<a id="release-summary-16"></a> ### Release Summary Bugfix and feature release\. -<a id="bugfixes-11"></a> +<a id="bugfixes-12"></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)\)\. @@ -519,12 +555,12 @@ Bugfix and feature release\. <a id="v2-9-0"></a> ## v2\.9\.0 -<a id="release-summary-16"></a> +<a id="release-summary-17"></a> ### Release Summary Regular feature release\. -<a id="minor-changes-8"></a> +<a id="minor-changes-9"></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)\)\. @@ -532,7 +568,7 @@ Regular feature release\. <a id="v2-8-1"></a> ## v2\.8\.1 -<a id="release-summary-17"></a> +<a id="release-summary-18"></a> ### Release Summary Maintenance release with improved documentation\. @@ -540,12 +576,12 @@ Maintenance release with improved documentation\. <a id="v2-8-0"></a> ## v2\.8\.0 -<a id="release-summary-18"></a> +<a id="release-summary-19"></a> ### Release Summary Feature release\. -<a id="minor-changes-9"></a> +<a id="minor-changes-10"></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)\)\. @@ -555,12 +591,12 @@ Feature release\. <a id="v2-7-1"></a> ## v2\.7\.1 -<a id="release-summary-19"></a> +<a id="release-summary-20"></a> ### Release Summary Maintenance release\. -<a id="bugfixes-12"></a> +<a id="bugfixes-13"></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)\)\. @@ -568,17 +604,17 @@ Maintenance release\. <a id="v2-7-0"></a> ## v2\.7\.0 -<a id="release-summary-20"></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 \- 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-13"></a> +<a id="bugfixes-14"></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)\)\. @@ -586,12 +622,12 @@ Feature release\. <a id="v2-6-0"></a> ## v2\.6\.0 -<a id="release-summary-21"></a> +<a id="release-summary-22"></a> ### Release Summary Feature release\. -<a id="minor-changes-11"></a> +<a id="minor-changes-12"></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)\)\. @@ -600,12 +636,12 @@ Feature release\. <a id="v2-5-0"></a> ## v2\.5\.0 -<a id="release-summary-22"></a> +<a id="release-summary-23"></a> ### Release Summary Maintenance release with improved licensing declaration and documentation fixes\. -<a id="minor-changes-12"></a> +<a id="minor-changes-13"></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)\)\. @@ -613,17 +649,17 @@ Maintenance release with improved licensing declaration and documentation fixes\ <a id="v2-4-0"></a> ## v2\.4\.0 -<a id="release-summary-23"></a> +<a id="release-summary-24"></a> ### Release Summary Deprecation and bugfix release\. No new features this time\. -<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\.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-14"></a> +<a id="bugfixes-15"></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)\)\. @@ -631,7 +667,7 @@ Deprecation and bugfix release\. No new features this time\. <a id="v2-3-4"></a> ## v2\.3\.4 -<a id="release-summary-24"></a> +<a id="release-summary-25"></a> ### Release Summary Re\-release of what was intended to be 2\.3\.3\. @@ -647,12 +683,12 @@ has been added\. <a id="v2-3-3"></a> ## v2\.3\.3 -<a id="release-summary-25"></a> +<a id="release-summary-26"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-15"></a> +<a id="bugfixes-16"></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>\. @@ -662,12 +698,12 @@ Bugfix release\. <a id="v2-3-2"></a> ## v2\.3\.2 -<a id="release-summary-26"></a> +<a id="release-summary-27"></a> ### Release Summary Maintenance and bugfix release\. -<a id="bugfixes-16"></a> +<a id="bugfixes-17"></a> ### Bugfixes * Include <code>simplified\_bsd\.txt</code> license file for the ECS module utils\. @@ -676,12 +712,12 @@ Maintenance and bugfix release\. <a id="v2-3-1"></a> ## v2\.3\.1 -<a id="release-summary-27"></a> +<a id="release-summary-28"></a> ### Release Summary Maintenance release\. -<a id="bugfixes-17"></a> +<a id="bugfixes-18"></a> ### Bugfixes * Include <code>PSF\-license\.txt</code> file for <code>plugins/module\_utils/\_version\.py</code>\. @@ -689,12 +725,12 @@ Maintenance release\. <a id="v2-3-0"></a> ## v2\.3\.0 -<a id="release-summary-28"></a> +<a id="release-summary-29"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-13"></a> +<a id="minor-changes-14"></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)\)\. @@ -708,7 +744,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-18"></a> +<a id="bugfixes-19"></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)\)\. @@ -717,12 +753,12 @@ Feature and bugfix release\. <a id="v2-2-4"></a> ## v2\.2\.4 -<a id="release-summary-29"></a> +<a id="release-summary-30"></a> ### Release Summary Regular maintenance release\. -<a id="bugfixes-19"></a> +<a id="bugfixes-20"></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)\)\. @@ -730,12 +766,12 @@ Regular maintenance release\. <a id="v2-2-3"></a> ## v2\.2\.3 -<a id="release-summary-30"></a> +<a id="release-summary-31"></a> ### Release Summary Regular bugfix release\. -<a id="bugfixes-20"></a> +<a id="bugfixes-21"></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)\)\. @@ -743,14 +779,14 @@ Regular bugfix release\. <a id="v2-2-2"></a> ## v2\.2\.2 -<a id="release-summary-31"></a> +<a id="release-summary-32"></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-21"></a> +<a id="bugfixes-22"></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)\)\. @@ -762,12 +798,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-32"></a> +<a id="release-summary-33"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-22"></a> +<a id="bugfixes-23"></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)\)\. @@ -775,17 +811,17 @@ Bugfix release\. <a id="v2-2-0"></a> ## v2\.2\.0 -<a id="release-summary-33"></a> +<a id="release-summary-34"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-14"></a> +<a id="minor-changes-15"></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-23"></a> +<a id="bugfixes-24"></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)\)\. @@ -793,24 +829,24 @@ Regular bugfix and feature release\. <a id="v2-1-0"></a> ## v2\.1\.0 -<a id="release-summary-34"></a> +<a id="release-summary-35"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-15"></a> +<a id="minor-changes-16"></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-24"></a> +<a id="bugfixes-25"></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"></a> +<a id="new-modules-1"></a> ### New Modules * crypto\_info \- Retrieve cryptographic capabilities @@ -819,7 +855,7 @@ Feature and bugfix release\. <a id="v2-0-2"></a> ## v2\.0\.2 -<a id="release-summary-35"></a> +<a id="release-summary-36"></a> ### Release Summary Documentation fix release\. No actual code changes\. @@ -827,17 +863,17 @@ Documentation fix release\. No actual code changes\. <a id="v2-0-1"></a> ## v2\.0\.1 -<a id="release-summary-36"></a> +<a id="release-summary-37"></a> ### Release Summary Bugfix release with extra forward compatibility for newer versions of cryptography\. -<a id="minor-changes-16"></a> +<a id="minor-changes-17"></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-25"></a> +<a id="bugfixes-26"></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)\)\. @@ -848,12 +884,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-37"></a> +<a id="release-summary-38"></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-17"></a> +<a id="minor-changes-18"></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)\)\. @@ -878,7 +914,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-4"></a> +<a id="deprecated-features-5"></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)\)\. @@ -910,7 +946,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-26"></a> +<a id="bugfixes-27"></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)\)\. @@ -922,12 +958,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-38"></a> +<a id="release-summary-39"></a> ### Release Summary Regular bugfix release\. -<a id="bugfixes-27"></a> +<a id="bugfixes-28"></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)\)\. @@ -936,12 +972,12 @@ Regular bugfix release\. <a id="v1-9-3"></a> ## v1\.9\.3 -<a id="release-summary-39"></a> +<a id="release-summary-40"></a> ### Release Summary Regular bugfix release\. -<a id="bugfixes-28"></a> +<a id="bugfixes-29"></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)\)\. @@ -949,7 +985,7 @@ Regular bugfix release\. <a id="v1-9-2"></a> ## v1\.9\.2 -<a id="release-summary-40"></a> +<a id="release-summary-41"></a> ### Release Summary Bugfix release to fix the changelog\. No other change compared to 1\.9\.0\. @@ -957,7 +993,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-41"></a> +<a id="release-summary-42"></a> ### Release Summary Accidental 1\.9\.1 release\. Identical to 1\.9\.0\. @@ -965,18 +1001,18 @@ Accidental 1\.9\.1 release\. Identical to 1\.9\.0\. <a id="v1-9-0"></a> ## v1\.9\.0 -<a id="release-summary-42"></a> +<a id="release-summary-43"></a> ### Release Summary Regular feature release\. -<a id="minor-changes-18"></a> +<a id="minor-changes-19"></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-29"></a> +<a id="bugfixes-30"></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)\)\. @@ -987,12 +1023,12 @@ Regular feature release\. <a id="v1-8-0"></a> ## v1\.8\.0 -<a id="release-summary-43"></a> +<a id="release-summary-44"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-19"></a> +<a id="minor-changes-20"></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)\)\. @@ -1000,7 +1036,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-30"></a> +<a id="bugfixes-31"></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)\)\. @@ -1009,12 +1045,12 @@ Regular bugfix and feature release\. <a id="v1-7-1"></a> ## v1\.7\.1 -<a id="release-summary-44"></a> +<a id="release-summary-45"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-31"></a> +<a id="bugfixes-32"></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)\)\. @@ -1022,12 +1058,12 @@ Bugfix release\. <a id="v1-7-0"></a> ## v1\.7\.0 -<a id="release-summary-45"></a> +<a id="release-summary-46"></a> ### Release Summary Regular feature and bugfix release\. -<a id="minor-changes-20"></a> +<a id="minor-changes-21"></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)\)\. @@ -1050,14 +1086,14 @@ 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-32"></a> +<a id="bugfixes-33"></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-1"></a> +<a id="new-modules-2"></a> ### New Modules * openssl\_publickey\_info \- Provide information for OpenSSL public keys @@ -1065,12 +1101,12 @@ Regular feature and bugfix release\. <a id="v1-6-2"></a> ## v1\.6\.2 -<a id="release-summary-46"></a> +<a id="release-summary-47"></a> ### Release Summary Bugfix release\. Fixes compatibility issue of ACME modules with step\-ca\. -<a id="bugfixes-33"></a> +<a id="bugfixes-34"></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)\)\. @@ -1078,12 +1114,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-47"></a> +<a id="release-summary-48"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-34"></a> +<a id="bugfixes-35"></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)\)\. @@ -1091,12 +1127,12 @@ Bugfix release\. <a id="v1-6-0"></a> ## v1\.6\.0 -<a id="release-summary-48"></a> +<a id="release-summary-49"></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-21"></a> +<a id="minor-changes-22"></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)\)\. @@ -1105,12 +1141,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-5"></a> +<a id="deprecated-features-6"></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-35"></a> +<a id="bugfixes-36"></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)\)\. @@ -1119,23 +1155,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-49"></a> +<a id="release-summary-50"></a> ### Release Summary Regular feature and bugfix release\. Deprecates a return value\. -<a id="minor-changes-22"></a> +<a id="minor-changes-23"></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-6"></a> +<a id="deprecated-features-7"></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-36"></a> +<a id="bugfixes-37"></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)\)\. @@ -1143,12 +1179,12 @@ Regular feature and bugfix release\. Deprecates a return value\. <a id="v1-4-0"></a> ## v1\.4\.0 -<a id="release-summary-50"></a> +<a id="release-summary-51"></a> ### Release Summary Release with several new features and bugfixes\. -<a id="minor-changes-23"></a> +<a id="minor-changes-24"></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)\)\. @@ -1158,7 +1194,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-37"></a> +<a id="bugfixes-38"></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)\)\. @@ -1166,12 +1202,12 @@ Release with several new features and bugfixes\. <a id="v1-3-0"></a> ## v1\.3\.0 -<a id="release-summary-51"></a> +<a id="release-summary-52"></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-24"></a> +<a id="minor-changes-25"></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)\)\. @@ -1181,14 +1217,14 @@ 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-38"></a> +<a id="bugfixes-39"></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-2"></a> +<a id="new-modules-3"></a> ### New Modules * openssl\_csr\_pipe \- Generate OpenSSL Certificate Signing Request \(CSR\) @@ -1198,12 +1234,12 @@ Contains new modules <code>openssl\_privatekey\_pipe</code>\, <code>openssl\_csr <a id="v1-2-0"></a> ## v1\.2\.0 -<a id="release-summary-52"></a> +<a id="release-summary-53"></a> ### Release Summary Please note that this release fixes a security issue \(CVE\-2020\-25646\)\. -<a id="minor-changes-25"></a> +<a id="minor-changes-26"></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)\)\. @@ -1219,7 +1255,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-39"></a> +<a id="bugfixes-40"></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)\)\. @@ -1227,12 +1263,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-53"></a> +<a id="release-summary-54"></a> ### Release Summary Bugfixes for Ansible 2\.10\.0\. -<a id="bugfixes-40"></a> +<a id="bugfixes-41"></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)\)\. @@ -1241,12 +1277,12 @@ Bugfixes for Ansible 2\.10\.0\. <a id="v1-1-0"></a> ## v1\.1\.0 -<a id="release-summary-54"></a> +<a id="release-summary-55"></a> ### Release Summary Release for Ansible 2\.10\.0\. -<a id="minor-changes-26"></a> +<a id="minor-changes-27"></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)\)\. @@ -1259,14 +1295,14 @@ 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-41"></a> +<a id="bugfixes-42"></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-3"></a> +<a id="new-modules-4"></a> ### New Modules * openssl\_signature \- Sign data with openssl @@ -1275,12 +1311,12 @@ Release for Ansible 2\.10\.0\. <a id="v1-0-0"></a> ## v1\.0\.0 -<a id="release-summary-55"></a> +<a id="release-summary-56"></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-27"></a> +<a id="minor-changes-28"></a> ### Minor Changes * luks\_device \- accept <code>passphrase</code>\, <code>new\_passphrase</code> and <code>remove\_passphrase</code>\. @@ -1309,7 +1345,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-7"></a> +<a id="deprecated-features-8"></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\. @@ -1319,7 +1355,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-42"></a> +<a id="bugfixes-43"></a> ### Bugfixes * ACME modules\: fix bug in ACME v1 account update code @@ -1342,7 +1378,7 @@ 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-4"></a> +<a id="new-modules-5"></a> ### New Modules * ecs\_domain \- Request validation of a domain with the Entrust Certificate Services \(ECS\) API diff --git a/ansible_collections/community/crypto/CHANGELOG.rst b/ansible_collections/community/crypto/CHANGELOG.rst index 320169717..b2dca8e3f 100644 --- a/ansible_collections/community/crypto/CHANGELOG.rst +++ b/ansible_collections/community/crypto/CHANGELOG.rst @@ -4,6 +4,35 @@ Community Crypto Release Notes .. contents:: Topics +v2.19.0 +======= + +Release Summary +--------------- + +Bugfix and feature release. + +Minor Changes +------------- + +- When using cryptography >= 42.0.0, use offset-aware ``datetime.datetime`` 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/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). + +Deprecated Features +------------------- + +- acme.backends module utils - from community.crypto on, all implementations of ``CryptoBackend`` must override ``get_ordered_csr_identifiers()``. The current default implementation, which simply sorts the result of ``get_csr_identifiers()``, will then be removed (https://github.com/ansible-collections/community.crypto/pull/725). + +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/pull/725). + +New Modules +----------- + +- x509_certificate_convert - Convert X.509 certificates + v2.18.0 ======= diff --git a/ansible_collections/community/crypto/FILES.json b/ansible_collections/community/crypto/FILES.json index 249caaa96..e98f9499c 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": "82056264d02238b30cfe7740554b4dcde7ec173c7a5de5e494f2fad309462455", + "chksum_sha256": "6e277188c1cbc0030cb55f73f6ebde233c77c66e2aa0d19476f9b7bae729d345", "format": 1 }, { @@ -130,7 +130,7 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "aac90c499964bd9233fc13565169248e29e9eda7cf97a2d4db56f6fdba9558ed", + "chksum_sha256": "4250c0cd843d1a134c3d806ef9030b55f9a1b949902d1a746ccd19edb9f51a95", "format": 1 }, { @@ -165,7 +165,7 @@ "name": ".github/workflows/reuse.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "907950e209820f04e0122e100c86690cf5ac0f4a15cb950cce4d2af6eaaddb37", + "chksum_sha256": "5d7f877d94901193f7273865244e67010c8196234debbacf6be5f27ec51f417c", "format": 1 }, { @@ -263,7 +263,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e03726652f634d6ff4b51599ec42f48c6ff77aaec7d59c186770af2c599b2d3f", + "chksum_sha256": "7dcaea3df82e79d7b11bb628e95889ccfb31077902d6ddaee8655a83f577b418", "format": 1 }, { @@ -316,6 +316,13 @@ "format": 1 }, { + "name": "docs/docsite/config.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0c5ec9ff76cf4db33b5d3f771419ef50d448e5d510cb7a98fc07dd9ecee69c4e", + "format": 1 + }, + { "name": "docs/docsite/extra-docs.yml", "ftype": "file", "chksum_type": "sha256", @@ -564,21 +571,21 @@ "name": "plugins/module_utils/acme/backend_cryptography.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4b8f578400e6bd0762ba44c0784c6a8e4fc442e436243836ace40317eb936b61", + "chksum_sha256": "5bccf4747fa4ef5853858db1683bfa4d31951fc1da78341c36063617eb4b2719", "format": 1 }, { "name": "plugins/module_utils/acme/backend_openssl_cli.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5e5e5127e8eb261168dfe60dcd1e1fd63ad1196ca5947a1845c3f7481dcaf431", + "chksum_sha256": "7a722bedddbc63e4d6e66b10659f63531c2675e19740ccc3381b70f6ed3fdba4", "format": 1 }, { "name": "plugins/module_utils/acme/backends.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cf618865eb9f569e5d775d0539463ce6f7abd3cd593f4528a83f3f1bfb2885e5", + "chksum_sha256": "e2c50aaec5b7404e7a8437d34f8246adcb6a7390dff505ce772d04b9a9530177", "format": 1 }, { @@ -641,7 +648,7 @@ "name": "plugins/module_utils/crypto/module_backends/certificate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "707b1e0abbd35ffb76d00744ee35b4f5521b7184de04d587f34cc256aa1a7728", + "chksum_sha256": "c8858dddd2447413319f622af45c004f3b64eb6038e3e288454b76418d28d0f2", "format": 1 }, { @@ -655,28 +662,28 @@ "name": "plugins/module_utils/crypto/module_backends/certificate_entrust.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0046918bf9e870753fb5a24815ada1dcc42077f2ba62e950942f26c36a298b62", + "chksum_sha256": "79486afc80b485e4c4c930b59f44c8320e5ece7eb63408bf5f5ac2bc66c3eeed", "format": 1 }, { "name": "plugins/module_utils/crypto/module_backends/certificate_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "20a96ca9b95f652564f49dce0e477a314da3f6cc1e6f51e3ae75992e6f54da5b", + "chksum_sha256": "cd9c993f1c224036eba267820de7e21cec8a06a138d943b776541be214f1d14f", "format": 1 }, { "name": "plugins/module_utils/crypto/module_backends/certificate_ownca.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8491949f4ed06374834f8ba4cd67edac9bbbeae47247b0e978c92220aaf3cb50", + "chksum_sha256": "6c58c55efbdec1869fc10fe63785242aee81f2dc8fff03397de5b75303ed724d", "format": 1 }, { "name": "plugins/module_utils/crypto/module_backends/certificate_selfsigned.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c535db42e5267798cb1d12c1329ed3e526ede4afae8dcef10d619e779535ecf6", + "chksum_sha256": "d46e3f53d82fe161efdc94f337126f66fcfb8e49647367c08a68ee2232ca6e8c", "format": 1 }, { @@ -774,14 +781,14 @@ "name": "plugins/module_utils/crypto/cryptography_crl.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "070fbd85edef9007d52574252b31f189dabc6256b828251075d506e6f1186082", + "chksum_sha256": "ad9a5bdd95492d516dc390346b968b0191a8901d7682382e978a7f67e681878a", "format": 1 }, { "name": "plugins/module_utils/crypto/cryptography_support.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "429ae5d529c41a60c0cf15e55b745cbd9adfd569ea315adf693527ba72499451", + "chksum_sha256": "3839218fd95217f9fbb44cb01ac33ec87837021d90fe92dac2ac1509a29f5564", "format": 1 }, { @@ -802,14 +809,14 @@ "name": "plugins/module_utils/crypto/pem.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9045d933bdb216615500049e5773323f005b2355868f2628c9775cf88e524ae3", + "chksum_sha256": "8a37877e3d15f35f92bb5a28698db59b6c8c605f99d89cf42554418378d7738b", "format": 1 }, { "name": "plugins/module_utils/crypto/support.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "af8b7e736a0383370681a6a9017a9e9f3c9bbcf324c3b6c2bc99e5031bef3183", + "chksum_sha256": "7d27f0bf007ccdb80a8d144381545f6406abad02396dbd39def186147a6efa91", "format": 1 }, { @@ -872,7 +879,7 @@ "name": "plugins/module_utils/openssh/certificate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3edc83078c5dee008ccb961123d202b4ea2340772f28137dcef60e945604464c", + "chksum_sha256": "2febea40e9db5c2f560a0e399603812f520b575b00cec33bfae2e536962d24c7", "format": 1 }, { @@ -942,7 +949,7 @@ "name": "plugins/modules/acme_certificate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c3f29dfd43f862717692b9ea8a48a186f3bf48f73cbe400ded858aa1286662ac", + "chksum_sha256": "5f0f0039f146654c43e4a2a44e7be9becfc9a1d0566e11bef39ad591b472725d", "format": 1 }, { @@ -956,7 +963,7 @@ "name": "plugins/modules/acme_challenge_cert_helper.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "073bd164227b3dfd709e76288c1d3185474556274257e793e77f7acbd2220904", + "chksum_sha256": "8484e4dc9508cffab80145f63ebabf0e88e6d203a3e466f2c000ca3e465596cb", "format": 1 }, { @@ -998,7 +1005,7 @@ "name": "plugins/modules/get_certificate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "316e351393face995abc0334f38736f3eb27bd73a9faece5206c061f37122ab0", + "chksum_sha256": "3ea3b665adf3bbc3c2dc8e92cf9efd6c7b273aec0c8f1ef29e6414b0a9c50dd9", "format": 1 }, { @@ -1121,10 +1128,17 @@ "format": 1 }, { + "name": "plugins/modules/x509_certificate_convert.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b41327e91bb4111c6b9e4293684a2ad6d4cfa566101303ac4b38507a71c18716", + "format": 1 + }, + { "name": "plugins/modules/x509_certificate_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9cdcd6e9d4d11182ff9bf203c1432b0d96d74f31548f8eb34ae5b7beb48d57fc", + "chksum_sha256": "e39c0d16a89cc7cac74d2c81e0406c9e5c1ebe8da0dd9c9c5ef9c26a78d5eae0", "format": 1 }, { @@ -1138,7 +1152,7 @@ "name": "plugins/modules/x509_crl.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bc95c541cd09e5d61f437b7c701e3c3370821618a271f98d4746de8480e9084f", + "chksum_sha256": "eb2dfed3b7ec2739444923eb22812533901e9f6e7b6f19e127db7d34b3f6c6aa", "format": 1 }, { @@ -4579,6 +4593,55 @@ "format": 1 }, { + "name": "tests/integration/targets/x509_certificate_convert", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/x509_certificate_convert/meta", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/x509_certificate_convert/meta/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e550791b9b9cf709c4dbec99b2fd8603263883e7eab8c8d99805c2aa4bcaa8a2", + "format": 1 + }, + { + "name": "tests/integration/targets/x509_certificate_convert/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/x509_certificate_convert/tasks/impl.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c41118537236b6020f57408e488caac150d7f68d5e5c2a1a5b576441d467d710", + "format": 1 + }, + { + "name": "tests/integration/targets/x509_certificate_convert/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "89871cb736941b87c796ec88bd5bb119dc7adf62b9379ecebd1ae620156f939a", + "format": 1 + }, + { + "name": "tests/integration/targets/x509_certificate_convert/aliases", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "efd331a62ed0b05469a451ee76dfab1231fee154835999a0cda0473e9bfe30f8", + "format": 1 + }, + { "name": "tests/integration/targets/x509_certificate_info", "ftype": "dir", "chksum_type": null, @@ -4848,7 +4911,7 @@ "name": "tests/sanity/ignore-2.10.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9c564907d4db67b2eab6b7387740cbf6146bb2f236db4eac52fc320fa2e0eefb", + "chksum_sha256": "0cfffbe82096f8efdba1b354fad867dd681faac5a4029419261c228ca128c97f", "format": 1 }, { @@ -4862,7 +4925,7 @@ "name": "tests/sanity/ignore-2.11.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1b44914e1e87736a09ebfdabf48dae543323720b6864fb9064052e874d96847d", + "chksum_sha256": "409ff4ad0805b8ac9d20d7c7ae2e76f35ac8ed6c14ea124d75f768e4299af964", "format": 1 }, { @@ -4876,7 +4939,7 @@ "name": "tests/sanity/ignore-2.12.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a4c87a60391639fdf51e7be2088785d7d1950580d27cbc348d45c2bad0887a4a", + "chksum_sha256": "69653fb8464973ead8ebbdadf67ec37adc5222978de6033fa8c76fe90292fb54", "format": 1 }, { @@ -4890,7 +4953,7 @@ "name": "tests/sanity/ignore-2.13.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "38df4b447aa4f0fa4b168df195dff78362f955ed3c4117266c320045be6d00a7", + "chksum_sha256": "9d1eec057555e6cfcd9757bead5d91d32069ecdb786eebca25c253e85e5e9f47", "format": 1 }, { @@ -4904,7 +4967,7 @@ "name": "tests/sanity/ignore-2.14.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "38df4b447aa4f0fa4b168df195dff78362f955ed3c4117266c320045be6d00a7", + "chksum_sha256": "9d1eec057555e6cfcd9757bead5d91d32069ecdb786eebca25c253e85e5e9f47", "format": 1 }, { @@ -4957,10 +5020,24 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "88f167104e425a472b8fd111b8b2e9d7b2e1135ace2d5130cef81ca38aeba161", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.18.txt.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "tests/sanity/ignore-2.9.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "dad1b754c46149195a1a26af8e56bb1aa449d4acec41532bfaf45a8254b11050", + "chksum_sha256": "0ebc63c03bea984b7363e6e7ac6b1cf2ef1a866637ab8564cbad5061a62dc1e8", "format": 1 }, { @@ -5429,7 +5506,7 @@ "name": "CHANGELOG.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5430eaa014f0f010ed69848fea7d36d8dbb9fe9a8d7612887dd52c73389dfef1", + "chksum_sha256": "ca2c6e6efdcfdb7ee6ee1b3bbb095989678081d32fa9aca67b65f57e96a37026", "format": 1 }, { @@ -5443,7 +5520,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "124c1a02abb35f4b3e98c6449bd07d7a606a80e34f297b60be1ed43673955bba", + "chksum_sha256": "6ba9093a33e39e50b4a9436cbfdb36c2591a15c0aeadc8e7072b980df760ee6d", "format": 1 }, { @@ -5464,7 +5541,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "dd847490669a8106ad134aa8c1d21e9620891badee9173763ca0643187e7e735", + "chksum_sha256": "704b9171377cd1c819ac83f7603438188432dfc6296bb7c6bfa7291c85d3b8b6", "format": 1 } ], diff --git a/ansible_collections/community/crypto/MANIFEST.json b/ansible_collections/community/crypto/MANIFEST.json index 2e16020a1..40dbbd275 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.18.0", + "version": "2.19.0", "authors": [ "Ansible (github.com/ansible)" ], @@ -41,7 +41,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "fc4c33abc854162fe45421f98db891d66b0d614f3c5ddfcb8d14f308db7e9df2", + "chksum_sha256": "b8a70c677576d6f7bda75b45d97af355a4f371b9269a791bdef8976361b39f75", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/crypto/README.md b/ansible_collections/community/crypto/README.md index 64ffd4eae..99c6a4f62 100644 --- a/ansible_collections/community/crypto/README.md +++ b/ansible_collections/community/crypto/README.md @@ -18,7 +18,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, and ansible-core-2.16 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. +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. ## External requirements @@ -54,6 +54,7 @@ If you use the Ansible package and do not update collections independently, use - openssl_signature_info module - openssl_signature module - split_pem filter + - x509_certificate_convert module - x509_certificate_info module and filter - x509_certificate_pipe module - x509_certificate module diff --git a/ansible_collections/community/crypto/changelogs/changelog.yaml b/ansible_collections/community/crypto/changelogs/changelog.yaml index 044bd81a8..856a965ec 100644 --- a/ansible_collections/community/crypto/changelogs/changelog.yaml +++ b/ansible_collections/community/crypto/changelogs/changelog.yaml @@ -1052,6 +1052,33 @@ releases: name: to_serial namespace: null release_date: '2024-02-25' + 2.19.0: + changes: + 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/pull/725). + deprecated_features: + - acme.backends module utils - from community.crypto on, all implementations + of ``CryptoBackend`` must override ``get_ordered_csr_identifiers()``. The + current default implementation, which simply sorts the result of ``get_csr_identifiers()``, + will then be removed (https://github.com/ansible-collections/community.crypto/pull/725). + minor_changes: + - When using cryptography >= 42.0.0, use offset-aware ``datetime.datetime`` + 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/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). + release_summary: Bugfix and feature release. + fragments: + - 2.19.0.yml + - 725-acme_certificate-order.yml + - 727-cryptography-utc.yml + modules: + - description: Convert X.509 certificates + name: x509_certificate_convert + namespace: '' + release_date: '2024-04-20' 2.2.0: changes: bugfixes: diff --git a/ansible_collections/community/crypto/docs/docsite/config.yml b/ansible_collections/community/crypto/docs/docsite/config.yml new file mode 100644 index 000000000..1d6cf8554 --- /dev/null +++ b/ansible_collections/community/crypto/docs/docsite/config.yml @@ -0,0 +1,7 @@ +--- +# 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 + +changelog: + write_changelog: true 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 2e388980a..0722c1f99 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,7 +11,6 @@ __metaclass__ = type import base64 import binascii -import datetime import os import traceback @@ -42,11 +41,15 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.math impor ) 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, + get_not_valid_after, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import ( @@ -298,31 +301,51 @@ class CryptographyBackend(CryptoBackend): }, } - def get_csr_identifiers(self, csr_filename=None, csr_content=None): + def get_ordered_csr_identifiers(self, csr_filename=None, csr_content=None): ''' - Return a set of requested identifiers (CN and SANs) for the CSR. + Return a list of requested identifiers (CN and SANs) for the CSR. Each identifier is a pair (type, identifier), where type is either 'dns' or 'ip'. + + The list is deduplicated, and if a CNAME is present, it will be returned + as the first element in the result. ''' - identifiers = set([]) if csr_content is None: csr_content = read_file(csr_filename) else: csr_content = to_bytes(csr_content) csr = cryptography.x509.load_pem_x509_csr(csr_content, _cryptography_backend) + + identifiers = set() + result = [] + + def add_identifier(identifier): + if identifier in identifiers: + return + identifiers.add(identifier) + result.append(identifier) + for sub in csr.subject: if sub.oid == cryptography.x509.oid.NameOID.COMMON_NAME: - identifiers.add(('dns', sub.value)) + add_identifier(('dns', sub.value)) for extension in csr.extensions: if extension.oid == cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME: for name in extension.value: if isinstance(name, cryptography.x509.DNSName): - identifiers.add(('dns', name.value)) + add_identifier(('dns', name.value)) elif isinstance(name, cryptography.x509.IPAddress): - identifiers.add(('ip', name.value.compressed)) + add_identifier(('ip', name.value.compressed)) else: raise BackendException('Found unsupported SAN identifier {0}'.format(name)) - return identifiers + return result + + def get_csr_identifiers(self, csr_filename=None, csr_content=None): + ''' + Return a set of requested identifiers (CN and SANs) for the CSR. + Each identifier is a pair (type, identifier), where type is either + 'dns' or 'ip'. + ''' + return set(self.get_ordered_csr_identifiers(csr_filename=csr_filename, csr_content=csr_content)) def get_cert_days(self, cert_filename=None, cert_content=None, now=None): ''' @@ -353,8 +376,10 @@ class CryptographyBackend(CryptoBackend): raise BackendException('Cannot parse certificate {0}: {1}'.format(cert_filename, e)) if now is None: - now = datetime.datetime.now() - return (cert.not_valid_after - now).days + now = get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE) + elif CRYPTOGRAPHY_TIMEZONE: + now = ensure_utc_timezone(now) + return (get_not_valid_after(cert) - now).days def create_chain_matcher(self, criterium): ''' 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 dabcbdb3b..9a1ed1f5a 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 @@ -225,11 +225,14 @@ class OpenSSLCLIBackend(CryptoBackend): # We do not want to error out on something IPAddress() cannot parse return ip - def get_csr_identifiers(self, csr_filename=None, csr_content=None): + def get_ordered_csr_identifiers(self, csr_filename=None, csr_content=None): ''' - Return a set of requested identifiers (CN and SANs) for the CSR. + Return a list of requested identifiers (CN and SANs) for the CSR. Each identifier is a pair (type, identifier), where type is either 'dns' or 'ip'. + + The list is deduplicated, and if a CNAME is present, it will be returned + as the first element in the result. ''' filename = csr_filename data = None @@ -241,24 +244,40 @@ class OpenSSLCLIBackend(CryptoBackend): dummy, out, dummy = self.module.run_command( openssl_csr_cmd, data=data, check_rc=True, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE) - identifiers = set([]) + identifiers = set() + result = [] + + def add_identifier(identifier): + if identifier in identifiers: + return + identifiers.add(identifier) + result.append(identifier) + common_name = re.search(r"Subject:.* CN\s?=\s?([^\s,;/]+)", to_text(out, errors='surrogate_or_strict')) if common_name is not None: - identifiers.add(('dns', common_name.group(1))) + add_identifier(('dns', common_name.group(1))) subject_alt_names = re.search( r"X509v3 Subject Alternative Name: (?:critical)?\n +([^\n]+)\n", to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL) if subject_alt_names is not None: for san in subject_alt_names.group(1).split(", "): if san.lower().startswith("dns:"): - identifiers.add(('dns', san[4:])) + add_identifier(('dns', san[4:])) elif san.lower().startswith("ip:"): - identifiers.add(('ip', self._normalize_ip(san[3:]))) + add_identifier(('ip', self._normalize_ip(san[3:]))) elif san.lower().startswith("ip address:"): - identifiers.add(('ip', self._normalize_ip(san[11:]))) + add_identifier(('ip', self._normalize_ip(san[11:]))) else: raise BackendException('Found unsupported SAN identifier "{0}"'.format(san)) - return identifiers + return result + + def get_csr_identifiers(self, csr_filename=None, csr_content=None): + ''' + Return a set of requested identifiers (CN and SANs) for the CSR. + Each identifier is a pair (type, identifier), where type is either + 'dns' or 'ip'. + ''' + return set(self.get_ordered_csr_identifiers(csr_filename=csr_filename, csr_content=csr_content)) def get_cert_days(self, cert_filename=None, cert_content=None, now=None): ''' 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 5c48e1a74..2d95a3ee3 100644 --- a/ansible_collections/community/crypto/plugins/module_utils/acme/backends.py +++ b/ansible_collections/community/crypto/plugins/module_utils/acme/backends.py @@ -34,6 +34,23 @@ class CryptoBackend(object): def create_mac_key(self, alg, key): '''Create a MAC key.''' + def get_ordered_csr_identifiers(self, csr_filename=None, csr_content=None): + ''' + Return a list of requested identifiers (CN and SANs) for the CSR. + Each identifier is a pair (type, identifier), where type is either + 'dns' or 'ip'. + + The list is deduplicated, and if a CNAME is present, it will be returned + as the first element in the result. + ''' + self.module.deprecate( + "Every backend must override the get_ordered_csr_identifiers() method." + " The default implementation will be removed in 3.0.0 and this method will be marked as `abstractmethod` by then.", + version='3.0.0', + collection_name='community.crypto', + ) + return sorted(self.get_csr_identifiers(csr_filename=csr_filename, csr_content=csr_content)) + @abc.abstractmethod def get_csr_identifiers(self, csr_filename=None, csr_content=None): ''' diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_crl.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_crl.py index 62499e08b..8ef0d65da 100644 --- a/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_crl.py +++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_crl.py @@ -19,6 +19,7 @@ from .basic import ( ) from .cryptography_support import ( + CRYPTOGRAPHY_TIMEZONE, cryptography_decode_name, ) @@ -27,6 +28,11 @@ from ._obj2txt import ( ) +# TODO: once cryptography has a _utc variant of InvalidityDate.invalidity_date, set this +# to True and adjust get_invalidity_date() accordingly. +# (https://github.com/pyca/cryptography/issues/10818) +CRYPTOGRAPHY_TIMEZONE_INVALIDITY_DATE = False + TIMESTAMP_FORMAT = "%Y%m%d%H%M%SZ" @@ -55,7 +61,7 @@ else: def cryptography_decode_revoked_certificate(cert): result = { 'serial_number': cert.serial_number, - 'revocation_date': cert.revocation_date, + 'revocation_date': get_revocation_date(cert), 'issuer': None, 'issuer_critical': False, 'reason': None, @@ -77,7 +83,7 @@ def cryptography_decode_revoked_certificate(cert): pass try: ext = cert.extensions.get_extension_for_class(x509.InvalidityDate) - result['invalidity_date'] = ext.value.invalidity_date + result['invalidity_date'] = get_invalidity_date(ext.value) result['invalidity_date_critical'] = ext.critical except x509.ExtensionNotFound: pass @@ -112,3 +118,38 @@ def cryptography_get_signature_algorithm_oid_from_crl(crl): crl._x509_crl.sig_alg.algorithm ) return x509.oid.ObjectIdentifier(dotted) + + +def get_next_update(obj): + if CRYPTOGRAPHY_TIMEZONE: + return obj.next_update_utc + return obj.next_update + + +def get_last_update(obj): + if CRYPTOGRAPHY_TIMEZONE: + return obj.last_update_utc + return obj.last_update + + +def get_revocation_date(obj): + if CRYPTOGRAPHY_TIMEZONE: + return obj.revocation_date_utc + return obj.revocation_date + + +def get_invalidity_date(obj): + # TODO: special handling if CRYPTOGRAPHY_TIMEZONE_INVALIDITY_DATE is True + return obj.invalidity_date + + +def set_next_update(builder, value): + return builder.next_update(value) + + +def set_last_update(builder, value): + return builder.last_update(value) + + +def set_revocation_date(builder, value): + return builder.revocation_date(value) diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_support.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_support.py index b767d3417..3d07b35b1 100644 --- a/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_support.py +++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_support.py @@ -29,7 +29,9 @@ try: from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding import ipaddress + _HAS_CRYPTOGRAPHY = True except ImportError: + _HAS_CRYPTOGRAPHY = False # Error handled in the calling module. pass @@ -106,6 +108,11 @@ from ._objects import ( from ._obj2txt import obj2txt +CRYPTOGRAPHY_TIMEZONE = False +if _HAS_CRYPTOGRAPHY: + CRYPTOGRAPHY_TIMEZONE = LooseVersion(cryptography.__version__) >= LooseVersion('42.0.0') + + DOTTED_OID = re.compile(r'^\d+(?:\.\d+)+$') @@ -807,3 +814,23 @@ def cryptography_verify_certificate_signature(certificate, signer_public_key): certificate.signature_hash_algorithm, signer_public_key ) + + +def get_not_valid_after(obj): + if CRYPTOGRAPHY_TIMEZONE: + return obj.not_valid_after_utc + return obj.not_valid_after + + +def get_not_valid_before(obj): + if CRYPTOGRAPHY_TIMEZONE: + return obj.not_valid_before_utc + return obj.not_valid_before + + +def set_not_valid_after(builder, value): + return builder.not_valid_after(value) + + +def set_not_valid_before(builder, value): + return builder.not_valid_before(value) 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 7a56d7e9d..7bc93d934 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 @@ -32,6 +32,8 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import ( cryptography_compare_public_keys, + get_not_valid_after, + get_not_valid_before, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate_info import ( @@ -251,12 +253,12 @@ class CertificateBackend(object): # Check not before if not_before is not None and not self.ignore_timestamps: - if self.existing_certificate.not_valid_before != not_before: + if get_not_valid_before(self.existing_certificate) != not_before: return True # Check not after if not_after is not None and not self.ignore_timestamps: - if self.existing_certificate.not_valid_after != not_after: + if get_not_valid_after(self.existing_certificate) != not_after: return True return False 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 baf53f5de..7dc4641e1 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 @@ -10,7 +10,6 @@ __metaclass__ = type import datetime -import time import os from ansible.module_utils.common.text.converters import to_native, to_bytes @@ -19,11 +18,14 @@ 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 ( + CRYPTOGRAPHY_TIMEZONE, cryptography_serial_number_of_cert, + get_not_valid_after, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import ( @@ -99,7 +101,7 @@ class EntrustCertificateBackend(CertificateBackend): # Handle expiration (30 days if not specified) expiry = self.notAfter if not expiry: - gmt_now = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())) + gmt_now = get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE) expiry = gmt_now + datetime.timedelta(days=365) expiry_iso3339 = expiry.strftime("%Y-%m-%dT%H:%M:%S.00Z") @@ -154,7 +156,7 @@ class EntrustCertificateBackend(CertificateBackend): expiry = None if self.backend == 'cryptography': serial_number = "{0:X}".format(cryptography_serial_number_of_cert(self.existing_certificate)) - expiry = self.existing_certificate.not_valid_after + expiry = get_not_valid_after(self.existing_certificate) # get some information about the expiry of this certificate expiry_iso3339 = expiry.strftime("%Y-%m-%dT%H:%M:%S.00Z") 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 b10733ceb..5db6c3586 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 @@ -12,7 +12,6 @@ __metaclass__ = type import abc import binascii -import datetime import traceback from ansible.module_utils import six @@ -24,13 +23,17 @@ 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 ( + CRYPTOGRAPHY_TIMEZONE, cryptography_decode_name, cryptography_get_extensions_from_cert, cryptography_oid_to_name, cryptography_serial_number_of_cert, + get_not_valid_after, + get_not_valid_before, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.publickey_info import ( @@ -169,7 +172,7 @@ class CertificateInfoRetrieval(object): not_after = self.get_not_after() result['not_before'] = not_before.strftime(TIMESTAMP_FORMAT) result['not_after'] = not_after.strftime(TIMESTAMP_FORMAT) - result['expired'] = not_after < datetime.datetime.utcnow() + result['expired'] = not_after < get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE) result['public_key'] = to_native(self._get_public_key_pem()) @@ -322,10 +325,10 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval): return None, False def get_not_before(self): - return self.cert.not_valid_before + return get_not_valid_before(self.cert) def get_not_after(self): - return self.cert.not_valid_after + return get_not_valid_after(self.cert) def _get_public_key_pem(self): return self.cert.public_key().public_bytes( 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 ac1cf845a..4d312e6b7 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 @@ -31,6 +31,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp cryptography_key_needs_digest_for_signing, cryptography_serial_number_of_cert, cryptography_verify_certificate_signature, + get_not_valid_after, + get_not_valid_before, + set_not_valid_after, + set_not_valid_before, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import ( @@ -120,8 +124,8 @@ class OwnCACertificateBackendCryptography(CertificateBackend): cert_builder = cert_builder.subject_name(self.csr.subject) cert_builder = cert_builder.issuer_name(self.ca_cert.subject) cert_builder = cert_builder.serial_number(self.serial_number) - cert_builder = cert_builder.not_valid_before(self.notBefore) - cert_builder = cert_builder.not_valid_after(self.notAfter) + cert_builder = set_not_valid_before(cert_builder, self.notBefore) + cert_builder = set_not_valid_after(cert_builder, self.notAfter) cert_builder = cert_builder.public_key(self.csr.public_key()) has_ski = False for extension in self.csr.extensions: @@ -220,8 +224,8 @@ class OwnCACertificateBackendCryptography(CertificateBackend): if self.cert is None: self.cert = self.existing_certificate result.update({ - 'notBefore': self.cert.not_valid_before.strftime("%Y%m%d%H%M%SZ"), - 'notAfter': self.cert.not_valid_after.strftime("%Y%m%d%H%M%SZ"), + 'notBefore': get_not_valid_before(self.cert).strftime("%Y%m%d%H%M%SZ"), + 'notAfter': get_not_valid_after(self.cert).strftime("%Y%m%d%H%M%SZ"), 'serial_number': cryptography_serial_number_of_cert(self.cert), }) 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 8695d43ee..edd8d8d77 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 @@ -22,6 +22,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp cryptography_key_needs_digest_for_signing, cryptography_serial_number_of_cert, cryptography_verify_certificate_signature, + get_not_valid_after, + get_not_valid_before, + set_not_valid_after, + set_not_valid_before, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import ( @@ -95,8 +99,8 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend): cert_builder = cert_builder.subject_name(self.csr.subject) cert_builder = cert_builder.issuer_name(self.csr.subject) cert_builder = cert_builder.serial_number(self.serial_number) - cert_builder = cert_builder.not_valid_before(self.notBefore) - cert_builder = cert_builder.not_valid_after(self.notAfter) + cert_builder = set_not_valid_before(cert_builder, self.notBefore) + cert_builder = set_not_valid_after(cert_builder, self.notAfter) cert_builder = cert_builder.public_key(self.privatekey.public_key()) has_ski = False for extension in self.csr.extensions: @@ -154,8 +158,8 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend): if self.cert is None: self.cert = self.existing_certificate result.update({ - 'notBefore': self.cert.not_valid_before.strftime("%Y%m%d%H%M%SZ"), - 'notAfter': self.cert.not_valid_after.strftime("%Y%m%d%H%M%SZ"), + 'notBefore': get_not_valid_before(self.cert).strftime("%Y%m%d%H%M%SZ"), + 'notAfter': get_not_valid_after(self.cert).strftime("%Y%m%d%H%M%SZ"), 'serial_number': cryptography_serial_number_of_cert(self.cert), }) diff --git a/ansible_collections/community/crypto/plugins/module_utils/crypto/pem.py b/ansible_collections/community/crypto/plugins/module_utils/crypto/pem.py index da46548c7..5e6571fe0 100644 --- a/ansible_collections/community/crypto/plugins/module_utils/crypto/pem.py +++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/pem.py @@ -9,6 +9,7 @@ __metaclass__ = type PEM_START = '-----BEGIN ' +PEM_END_START = '-----END ' PEM_END = '-----' PKCS8_PRIVATEKEY_NAMES = ('PRIVATE KEY', 'ENCRYPTED PRIVATE KEY') PKCS1_PRIVATEKEY_SUFFIX = ' PRIVATE KEY' @@ -77,3 +78,31 @@ def extract_first_pem(text): if not all_pems: return None return all_pems[0] + + +def _extract_type(line, start=PEM_START): + if not line.startswith(start): + return None + if not line.endswith(PEM_END): + return None + return line[len(start):-len(PEM_END)] + + +def extract_pem(content, strict=False): + lines = content.splitlines() + if len(lines) < 3: + raise ValueError('PEM must have at least 3 lines, have only {count}'.format(count=len(lines))) + header_type = _extract_type(lines[0]) + if header_type is None: + raise ValueError('First line is not of format {start}...{end}: {line!r}'.format(start=PEM_START, end=PEM_END, line=lines[0])) + footer_type = _extract_type(lines[-1], start=PEM_END_START) + if strict: + if header_type != footer_type: + raise ValueError('Header type ({header}) is different from footer type ({footer})'.format(header=header_type, footer=footer_type)) + for idx, line in enumerate(lines[1:-2]): + if len(line) != 64: + raise ValueError('Line {idx} has length {len} instead of 64'.format(idx=idx, len=len(line))) + if not (0 < len(lines[-2]) <= 64): + raise ValueError('Last line has length {len}, should be in (0, 64]'.format(len=len(lines[-2]))) + content = lines[1:-1] + return header_type, ''.join(content) 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 473246b1b..8b59a3b70 100644 --- a/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py +++ b/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py @@ -279,7 +279,19 @@ def parse_ordered_name_field(input_list, name_field_name): return result -def convert_relative_to_datetime(relative_time_string): +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( @@ -304,13 +316,14 @@ def convert_relative_to_datetime(relative_time_string): offset += datetime.timedelta( seconds=int(parsed_result.group("seconds"))) + now = get_now_datetime(with_timezone=with_timezone) if parsed_result.group("prefix") == "+": - return datetime.datetime.utcnow() + offset + return now + offset else: - return datetime.datetime.utcnow() - offset + return now - offset -def get_relative_time_option(input_string, input_name, backend='cryptography'): +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. @@ -323,7 +336,7 @@ def get_relative_time_option(input_string, input_name, backend='cryptography'): input_string, input_name) # Relative time if result.startswith("+") or result.startswith("-"): - result_datetime = convert_relative_to_datetime(result) + 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': @@ -332,9 +345,13 @@ def get_relative_time_option(input_string, input_name, backend='cryptography'): 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: - return datetime.datetime.strptime(result, date_fmt) + 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' % 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 54d1b1ec5..f59766651 100644 --- a/ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py +++ b/ansible_collections/community/crypto/plugins/module_utils/openssh/certificate.py @@ -22,7 +22,9 @@ __metaclass__ = type import abc import binascii +import datetime as _datetime import os +import sys from base64 import b64encode from datetime import datetime from hashlib import sha256 @@ -61,8 +63,17 @@ _ECDSA_CURVE_IDENTIFIERS_LOOKUP = { b'nistp521': 'ecdsa-nistp521', } -_ALWAYS = datetime(1970, 1, 1) -_FOREVER = datetime.max +_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 _CRITICAL_OPTIONS = ( 'force-command', @@ -136,7 +147,7 @@ class OpensshCertificateTimeParameters(object): elif dt == _FOREVER: result = 'forever' else: - result = dt.isoformat() if date_format == 'human_readable' else dt.strftime("%Y%m%d%H%M%S") + result = dt.isoformat().replace('+00:00', '') if date_format == 'human_readable' else dt.strftime("%Y%m%d%H%M%S") elif date_format == 'timestamp': td = dt - _ALWAYS result = int((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 6) @@ -167,7 +178,10 @@ class OpensshCertificateTimeParameters(object): result = _FOREVER else: try: - result = datetime.utcfromtimestamp(timestamp) + if _USE_TIMEZONE: + result = datetime.fromtimestamp(timestamp, tz=_datetime.timezone.utc) + else: + result = datetime.utcfromtimestamp(timestamp) except OverflowError as e: raise ValueError return result @@ -180,11 +194,11 @@ class OpensshCertificateTimeParameters(object): elif time_string == 'forever': result = _FOREVER elif is_relative_time_string(time_string): - result = convert_relative_to_datetime(time_string) + result = convert_relative_to_datetime(time_string, with_timezone=_USE_TIMEZONE) else: for time_format in ("%Y-%m-%d", "%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S"): try: - result = datetime.strptime(time_string, time_format) + result = _ensure_utc_timezone_if_use_timezone(datetime.strptime(time_string, time_format)) except ValueError: pass if result is None: diff --git a/ansible_collections/community/crypto/plugins/modules/acme_certificate.py b/ansible_collections/community/crypto/plugins/modules/acme_certificate.py index 9c0b349c4..21a6d6ae9 100644 --- a/ansible_collections/community/crypto/plugins/modules/acme_certificate.py +++ b/ansible_collections/community/crypto/plugins/modules/acme_certificate.py @@ -661,7 +661,7 @@ class ACMECertificateClient(object): raise ModuleFailException("CSR %s not found" % (self.csr)) # Extract list of identifiers from CSR - self.identifiers = self.client.backend.get_csr_identifiers(csr_filename=self.csr, csr_content=self.csr_content) + self.identifiers = self.client.backend.get_ordered_csr_identifiers(csr_filename=self.csr, csr_content=self.csr_content) def is_first_step(self): ''' 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 9740cd16d..48b65f998 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,6 +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, +) + CRYPTOGRAPHY_IMP_ERR = None try: import cryptography @@ -244,8 +254,9 @@ def main(): domain = to_text(challenge_data['resource']) identifier_type, identifier = to_text(challenge_data.get('resource_original', 'dns:' + challenge_data['resource'])).split(':', 1) subject = issuer = cryptography.x509.Name([]) - not_valid_before = datetime.datetime.utcnow() - not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(days=10) + now = get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE) + not_valid_before = now + not_valid_after = now + datetime.timedelta(days=10) if identifier_type == 'dns': san = cryptography.x509.DNSName(identifier) elif identifier_type == 'ip': @@ -254,7 +265,7 @@ def main(): raise ModuleFailException('Unsupported identifier type "{0}"'.format(identifier_type)) # Generate regular self-signed certificate - regular_certificate = cryptography.x509.CertificateBuilder().subject_name( + cert_builder = cryptography.x509.CertificateBuilder().subject_name( subject ).issuer_name( issuer @@ -262,14 +273,13 @@ def main(): private_key.public_key() ).serial_number( cryptography.x509.random_serial_number() - ).not_valid_before( - not_valid_before - ).not_valid_after( - not_valid_after ).add_extension( cryptography.x509.SubjectAlternativeName([san]), critical=False, - ).sign( + ) + cert_builder = set_not_valid_before(cert_builder, not_valid_before) + cert_builder = set_not_valid_after(cert_builder, not_valid_after) + regular_certificate = cert_builder.sign( private_key, cryptography.hazmat.primitives.hashes.SHA256(), _cryptography_backend @@ -278,7 +288,7 @@ def main(): # Process challenge if challenge == 'tls-alpn-01': value = base64.b64decode(challenge_data['resource_value']) - challenge_certificate = cryptography.x509.CertificateBuilder().subject_name( + cert_builder = cryptography.x509.CertificateBuilder().subject_name( subject ).issuer_name( issuer @@ -286,10 +296,6 @@ def main(): private_key.public_key() ).serial_number( cryptography.x509.random_serial_number() - ).not_valid_before( - not_valid_before - ).not_valid_after( - not_valid_after ).add_extension( cryptography.x509.SubjectAlternativeName([san]), critical=False, @@ -299,7 +305,10 @@ def main(): encode_octet_string(value), ), critical=True, - ).sign( + ) + cert_builder = set_not_valid_before(cert_builder, not_valid_before) + cert_builder = set_not_valid_after(cert_builder, not_valid_after) + challenge_certificate = cert_builder.sign( private_key, cryptography.hazmat.primitives.hashes.SHA256(), _cryptography_backend diff --git a/ansible_collections/community/crypto/plugins/modules/get_certificate.py b/ansible_collections/community/crypto/plugins/modules/get_certificate.py index 0f8abc90a..6ae9439d3 100644 --- a/ansible_collections/community/crypto/plugins/modules/get_certificate.py +++ b/ansible_collections/community/crypto/plugins/modules/get_certificate.py @@ -209,7 +209,6 @@ EXAMPLES = ''' import atexit import base64 -import datetime import traceback from os.path import isfile @@ -221,9 +220,16 @@ 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, cryptography_get_extensions_from_cert, + get_not_valid_after, + get_not_valid_before, ) MINIMAL_CRYPTOGRAPHY_VERSION = '1.6' @@ -392,7 +398,7 @@ def main(): for attribute in x509.subject: result['subject'][cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value - result['expired'] = x509.not_valid_after < datetime.datetime.utcnow() + result['expired'] = get_not_valid_after(x509) < get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE) result['extensions'] = [] for dotted_number, entry in cryptography_get_extensions_from_cert(x509).items(): @@ -410,8 +416,8 @@ def main(): for attribute in x509.issuer: result['issuer'][cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value - result['not_after'] = x509.not_valid_after.strftime('%Y%m%d%H%M%SZ') - result['not_before'] = x509.not_valid_before.strftime('%Y%m%d%H%M%SZ') + result['not_after'] = get_not_valid_after(x509).strftime('%Y%m%d%H%M%SZ') + result['not_before'] = get_not_valid_before(x509).strftime('%Y%m%d%H%M%SZ') result['serial_number'] = x509.serial_number result['signature_algorithm'] = cryptography_oid_to_name(x509.signature_algorithm_oid) diff --git a/ansible_collections/community/crypto/plugins/modules/x509_certificate_convert.py b/ansible_collections/community/crypto/plugins/modules/x509_certificate_convert.py new file mode 100644 index 000000000..d3e39dc11 --- /dev/null +++ b/ansible_collections/community/crypto/plugins/modules/x509_certificate_convert.py @@ -0,0 +1,280 @@ +#!/usr/bin/python +# -*- 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 + + +DOCUMENTATION = r''' +--- +module: x509_certificate_convert +short_description: Convert X.509 certificates +version_added: 2.19.0 +description: + - This module allows to convert X.509 certificates between different formats. +author: + - Felix Fontein (@felixfontein) +extends_documentation_fragment: + - ansible.builtin.files + - community.crypto.attributes + - community.crypto.attributes.files +attributes: + check_mode: + support: full + diff_mode: + support: none + safe_file_operations: + support: full +options: + src_path: + description: + - Name of the file containing the X.509 certificate to convert. + - Exactly one of O(src_path) or O(src_content) must be specified. + type: path + src_content: + description: + - The content of the file containing the X.509 certificate to convert. + - This must be text. If you are not sure that the input file is PEM, you must Base64 encode + the value and set O(src_content_base64=true). You can use the + P(ansible.builtin.b64encode#filter) filter plugin for this. + - Exactly one of O(src_path) or O(src_content) must be specified. + type: str + src_content_base64: + description: + - If set to V(true) when O(src_content) is provided, the module assumes that the value + of O(src_content) is Base64 encoded. + type: bool + default: false + format: + description: + - Determines which format the destination X.509 certificate should be written in. + - Please note that not every key can be exported in any format, and that not every + format supports encryption. + type: str + choices: + - pem + - der + required: true + strict: + description: + - If the input is a PEM file, ensure that it contains a single PEM object, that + the header and footer match, and are of type C(CERTIFICATE) or C(X509 CERTIFICATE). + type: bool + default: false + dest_path: + description: + - Name of the file in which the generated TLS/SSL X.509 certificate will be written. + type: path + required: true + backup: + description: + - Create a backup file including a timestamp so you can get + the original X.509 certificate back if you overwrote it with a new one by accident. + type: bool + default: false +seealso: + - plugin: ansible.builtin.b64encode + plugin_type: filter + - module: community.crypto.x509_certificate + - module: community.crypto.x509_certificate_pipe + - module: community.crypto.x509_certificate_info +''' + +EXAMPLES = r''' +- name: Convert PEM X.509 certificate to DER format + community.crypto.x509_certificate_convert: + src_path: /etc/ssl/cert/ansible.com.pem + dest_path: /etc/ssl/cert/ansible.com.der + format: der +''' + +RETURN = r''' +backup_file: + description: Name of backup file created. + returned: changed and if O(backup) is V(true) + type: str + sample: /path/to/cert.pem.2019-03-09@11:22~ +''' + +import base64 +import os + +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.io import ( + load_file_if_exists, + write_file, +) + +from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import ( + OpenSSLObjectError, +) + +from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import ( + PEM_START, + PEM_END_START, + PEM_END, + identify_pem_format, + split_pem_list, + extract_pem, +) + +from ansible_collections.community.crypto.plugins.module_utils.crypto.support import ( + OpenSSLObject, +) + + +def parse_certificate(input, strict=False): + input_format = 'pem' if identify_pem_format(input) else 'der' + if input_format == 'pem': + pems = split_pem_list(to_text(input)) + if len(pems) > 1 and strict: + raise ValueError('The input contains {count} PEM objects, expecting only one since strict=true'.format(count=len(pems))) + pem_header_type, content = extract_pem(pems[0], strict=strict) + if strict and pem_header_type not in ('CERTIFICATE', 'X509 CERTIFICATE'): + raise ValueError('type is {type!r}, expecting CERTIFICATE or X509 CERTIFICATE'.format(type=pem_header_type)) + input = base64.b64decode(content) + else: + pem_header_type = None + return input, input_format, pem_header_type + + +class X509CertificateConvertModule(OpenSSLObject): + def __init__(self, module): + super(X509CertificateConvertModule, self).__init__( + module.params['dest_path'], + 'present', + False, + module.check_mode, + ) + + self.src_path = module.params['src_path'] + self.src_content = module.params['src_content'] + self.src_content_base64 = module.params['src_content_base64'] + if self.src_content is not None: + self.input = to_bytes(self.src_content) + if self.src_content_base64: + try: + self.input = base64.b64decode(self.input) + except Exception as exc: + module.fail_json(msg='Cannot Base64 decode src_content: {exc}'.format(exc=exc)) + else: + try: + with open(self.src_path, 'rb') as f: + self.input = f.read() + except Exception as exc: + module.fail_json(msg='Failure while reading file {fn}: {exc}'.format(fn=self.src_path, exc=exc)) + + self.format = module.params['format'] + self.strict = module.params['strict'] + self.wanted_pem_type = 'CERTIFICATE' + + try: + self.input, self.input_format, dummy = parse_certificate(self.input, strict=self.strict) + except Exception as exc: + module.fail_json(msg='Error while parsing PEM: {exc}'.format(exc=exc)) + + self.backup = module.params['backup'] + self.backup_file = None + + module.params['path'] = self.path + + self.dest_content = load_file_if_exists(self.path, module) + self.dest_content_format = None + self.dest_content_pem_type = None + if self.dest_content is not None: + try: + self.dest_content, self.dest_content_format, self.dest_content_pem_type = parse_certificate( + self.dest_content, strict=True) + except Exception: + pass + + def needs_conversion(self): + if self.dest_content is None or self.dest_content_format is None: + return True + if self.dest_content_format != self.format: + return True + if self.input != self.dest_content: + return True + if self.format == 'pem' and self.dest_content_pem_type != self.wanted_pem_type: + return True + return False + + def get_dest_certificate(self): + if self.format == 'der': + return self.input + data = to_bytes(base64.b64encode(self.input)) + lines = [to_bytes('{0}{1}{2}'.format(PEM_START, self.wanted_pem_type, PEM_END))] + lines += [data[i:i + 64] for i in range(0, len(data), 64)] + lines.append(to_bytes('{0}{1}{2}\n'.format(PEM_END_START, self.wanted_pem_type, PEM_END))) + return b'\n'.join(lines) + + def generate(self, module): + """Do conversion.""" + if self.needs_conversion(): + # Convert + cert_data = self.get_dest_certificate() + if not self.check_mode: + if self.backup: + self.backup_file = module.backup_local(self.path) + write_file(module, cert_data) + self.changed = True + + file_args = module.load_file_common_arguments(module.params) + if module.check_file_absent_if_check_mode(file_args['path']): + self.changed = True + else: + self.changed = module.set_fs_attributes_if_different(file_args, self.changed) + + def dump(self): + """Serialize the object into a dictionary.""" + result = dict( + changed=self.changed, + ) + if self.backup_file: + result['backup_file'] = self.backup_file + + return result + + +def main(): + argument_spec = dict( + src_path=dict(type='path'), + src_content=dict(type='str'), + src_content_base64=dict(type='bool', default=False), + format=dict(type='str', required=True, choices=['pem', 'der']), + strict=dict(type='bool', default=False), + dest_path=dict(type='path', required=True), + backup=dict(type='bool', default=False), + ) + module = AnsibleModule( + argument_spec, + supports_check_mode=True, + add_file_common_args=True, + required_one_of=[('src_path', 'src_content')], + mutually_exclusive=[('src_path', 'src_content')], + ) + + base_dir = os.path.dirname(module.params['dest_path']) or '.' + if not os.path.isdir(base_dir): + module.fail_json( + name=base_dir, + msg='The directory %s does not exist or the file is not a directory' % base_dir + ) + + try: + cert = X509CertificateConvertModule(module) + cert.generate(module) + result = cert.dump() + module.exit_json(**result) + except OpenSSLObjectError as exc: + module.fail_json(msg=to_native(exc)) + + +if __name__ == '__main__': + main() 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 d89f610c5..8379937f7 100644 --- a/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py +++ b/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py @@ -410,6 +410,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im get_relative_time_option, ) +from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import ( + CRYPTOGRAPHY_TIMEZONE, +) + from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate_info import ( select_backend, ) @@ -451,7 +455,7 @@ def main(): module.fail_json( msg='The value for valid_at.{0} must be of type string (got {1})'.format(k, type(v)) ) - valid_at[k] = get_relative_time_option(v, 'valid_at.{0}'.format(k)) + valid_at[k] = get_relative_time_option(v, 'valid_at.{0}'.format(k), with_timezone=CRYPTOGRAPHY_TIMEZONE) try: result = module_backend.get_info(der_support_enabled=module.params['content'] is None) diff --git a/ansible_collections/community/crypto/plugins/modules/x509_crl.py b/ansible_collections/community/crypto/plugins/modules/x509_crl.py index 1ac97005a..527975b88 100644 --- a/ansible_collections/community/crypto/plugins/modules/x509_crl.py +++ b/ansible_collections/community/crypto/plugins/modules/x509_crl.py @@ -475,6 +475,7 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im ) from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import ( + CRYPTOGRAPHY_TIMEZONE, cryptography_decode_name, cryptography_get_name, cryptography_key_needs_digest_for_signing, @@ -484,11 +485,17 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp ) from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_crl import ( + CRYPTOGRAPHY_TIMEZONE_INVALIDITY_DATE, REVOCATION_REASON_MAP, TIMESTAMP_FORMAT, cryptography_decode_revoked_certificate, cryptography_dump_revoked, cryptography_get_signature_algorithm_oid_from_crl, + get_next_update, + get_last_update, + set_next_update, + set_last_update, + set_revocation_date, ) from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import ( @@ -560,8 +567,8 @@ class CRL(OpenSSLObject): except (TypeError, ValueError) as exc: module.fail_json(msg=to_native(exc)) - self.last_update = get_relative_time_option(module.params['last_update'], 'last_update') - self.next_update = get_relative_time_option(module.params['next_update'], 'next_update') + self.last_update = get_relative_time_option(module.params['last_update'], 'last_update', with_timezone=CRYPTOGRAPHY_TIMEZONE) + self.next_update = get_relative_time_option(module.params['next_update'], 'next_update', with_timezone=CRYPTOGRAPHY_TIMEZONE) self.digest = select_message_digest(module.params['digest']) if self.digest is None: @@ -607,7 +614,8 @@ class CRL(OpenSSLObject): result['issuer_critical'] = rc['issuer_critical'] result['revocation_date'] = get_relative_time_option( rc['revocation_date'], - path_prefix + 'revocation_date' + path_prefix + 'revocation_date', + with_timezone=CRYPTOGRAPHY_TIMEZONE, ) if rc['reason']: result['reason'] = REVOCATION_REASON_MAP[rc['reason']] @@ -615,7 +623,8 @@ class CRL(OpenSSLObject): if rc['invalidity_date']: result['invalidity_date'] = get_relative_time_option( rc['invalidity_date'], - path_prefix + 'invalidity_date' + path_prefix + 'invalidity_date', + with_timezone=CRYPTOGRAPHY_TIMEZONE_INVALIDITY_DATE, ) result['invalidity_date_critical'] = rc['invalidity_date_critical'] self.revoked_certificates.append(result) @@ -731,9 +740,9 @@ class CRL(OpenSSLObject): if self.crl is None: return False - if self.last_update != self.crl.last_update and not self.ignore_timestamps: + if self.last_update != get_last_update(self.crl) and not self.ignore_timestamps: return False - if self.next_update != self.crl.next_update and not self.ignore_timestamps: + if self.next_update != get_next_update(self.crl) and not self.ignore_timestamps: return False if cryptography_key_needs_digest_for_signing(self.privatekey): if self.crl.signature_hash_algorithm is None or self.digest.name != self.crl.signature_hash_algorithm.name: @@ -780,8 +789,8 @@ class CRL(OpenSSLObject): except ValueError as e: raise CRLError(e) - crl = crl.last_update(self.last_update) - crl = crl.next_update(self.next_update) + crl = set_last_update(crl, self.last_update) + crl = set_next_update(crl, self.next_update) if self.update and self.crl: new_entries = set([self._compress_entry(entry) for entry in self.revoked_certificates]) @@ -792,7 +801,7 @@ class CRL(OpenSSLObject): for entry in self.revoked_certificates: revoked_cert = RevokedCertificateBuilder() revoked_cert = revoked_cert.serial_number(entry['serial_number']) - revoked_cert = revoked_cert.revocation_date(entry['revocation_date']) + revoked_cert = set_revocation_date(revoked_cert, entry['revocation_date']) if entry['issuer'] is not None: revoked_cert = revoked_cert.add_extension( x509.CertificateIssuer(entry['issuer']), @@ -876,8 +885,8 @@ class CRL(OpenSSLObject): for entry in self.revoked_certificates: result['revoked_certificates'].append(cryptography_dump_revoked(entry, idn_rewrite=self.name_encoding)) elif self.crl: - result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT) - result['next_update'] = self.crl.next_update.strftime(TIMESTAMP_FORMAT) + result['last_update'] = get_last_update(self.crl).strftime(TIMESTAMP_FORMAT) + result['next_update'] = get_next_update(self.crl).strftime(TIMESTAMP_FORMAT) result['digest'] = cryptography_oid_to_name(cryptography_get_signature_algorithm_oid_from_crl(self.crl)) issuer = [] for attribute in self.crl.issuer: diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/aliases b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/aliases new file mode 100644 index 000000000..4602f1185 --- /dev/null +++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/aliases @@ -0,0 +1,7 @@ +# 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/2 +azp/posix/2 +destructive diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/meta/main.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/meta/main.yml new file mode 100644 index 000000000..7c2b42405 --- /dev/null +++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/meta/main.yml @@ -0,0 +1,9 @@ +--- +# 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_openssl + - setup_remote_tmp_dir + - prepare_jinja2_compat diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/tasks/impl.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/tasks/impl.yml new file mode 100644 index 000000000..e0c438937 --- /dev/null +++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/tasks/impl.yml @@ -0,0 +1,212 @@ +--- +# 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: Read PEM cert + slurp: + src: '{{ remote_tmp_dir }}/cert_2.pem' + register: slurp_pem + +- name: Read DER cert + slurp: + src: '{{ remote_tmp_dir }}/cert_2.der' + register: slurp_der + +- name: Convert PEM cert (check mode) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.pem' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_1 + check_mode: true + +- name: Convert PEM cert + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.pem' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_2 + +- name: Convert PEM cert (idempotent, check mode) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.pem' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_3 + check_mode: true + +- name: Convert PEM cert (idempotent) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.pem' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_4 + +- name: Convert PEM cert (overwrite, check mode) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_2.pem' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_5 + check_mode: true + +- name: Convert PEM cert (overwrite) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_2.pem' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_6 + +- name: Convert PEM cert (idempotent, content) + x509_certificate_convert: + src_content: '{{ slurp_pem.content | b64decode }}' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_7 + +- name: Convert PEM cert (idempotent, content, base64) + x509_certificate_convert: + src_content: '{{ slurp_pem.content }}' + src_content_base64: true + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_8 + +- name: Convert PEM cert (idempotent, content, base64, from DER) + x509_certificate_convert: + src_content: '{{ slurp_der.content }}' + src_content_base64: true + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_9 + +- name: Convert PEM cert (idempotent, from DER) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_2.der' + format: pem + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.pem' + register: result_10 + +- name: Check conditions + assert: + that: + - result_1 is changed + - result_2 is changed + - result_3 is not changed + - result_4 is not changed + - result_5 is changed + - result_6 is changed + - result_7 is not changed + - result_8 is not changed + - result_9 is not changed + - result_10 is not changed + +- name: Convert DER cert (check mode) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.der' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_1 + check_mode: true + +- name: Convert DER cert + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.der' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_2 + +- name: Convert DER cert (idempotent, check mode) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.der' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_3 + check_mode: true + +- name: Convert DER cert (idempotent) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_1.der' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_4 + +- name: Convert DER cert (overwrite, check mode) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_2.der' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_5 + check_mode: true + +- name: Convert DER cert (overwrite) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_2.der' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_6 + +- name: Convert DER cert (idempotent, content, base64) + x509_certificate_convert: + src_content: '{{ slurp_der.content }}' + src_content_base64: true + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_7 + +- name: Convert DER cert (idempotent, content, from PEM) + x509_certificate_convert: + src_content: '{{ slurp_pem.content | b64decode }}' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_8 + +- name: Convert DER cert (idempotent, content, base64, from PEM) + x509_certificate_convert: + src_content: '{{ slurp_pem.content }}' + src_content_base64: true + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_9 + +- name: Convert DER cert (idempotent, from PEM) + x509_certificate_convert: + src_path: '{{ remote_tmp_dir }}/cert_2.pem' + format: der + strict: true + dest_path: '{{ remote_tmp_dir }}/out_1.der' + register: result_10 + +- name: Check conditions + assert: + that: + - result_1 is changed + - result_2 is changed + - result_3 is not changed + - result_4 is not changed + - result_5 is changed + - result_6 is changed + - result_7 is not changed + - result_8 is not changed + - result_9 is not changed + - result_10 is not changed diff --git a/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/tasks/main.yml b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/tasks/main.yml new file mode 100644 index 000000000..291572f1d --- /dev/null +++ b/ansible_collections/community/crypto/tests/integration/targets/x509_certificate_convert/tasks/main.yml @@ -0,0 +1,136 @@ +--- +# 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 # +#################################################################### + +- name: Generate privatekey + openssl_privatekey: + path: '{{ remote_tmp_dir }}/privatekey.pem' + size: '{{ default_rsa_key_size_certifiates }}' + +- name: Generate CSR 1 + openssl_csr: + path: '{{ remote_tmp_dir }}/csr_1.csr' + privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' + subject: + commonName: www.example.com + C: de + L: Somewhere + ST: Zurich + streetAddress: Welcome Street + O: Ansible + organizationalUnitName: + - Crypto Department + - ACME Department + serialNumber: "1234" + SN: Last Name + GN: First Name + title: Chief + pseudonym: test + UID: asdf + emailAddress: test@example.com + postalAddress: 1234 Somewhere + postalCode: "1234" + useCommonNameForSAN: false + key_usage: + - digitalSignature + - keyAgreement + - Non Repudiation + - Key Encipherment + - dataEncipherment + - Certificate Sign + - cRLSign + - Encipher Only + - decipherOnly + key_usage_critical: true + extended_key_usage: + - serverAuth # the same as "TLS Web Server Authentication" + - TLS Web Server Authentication + - TLS Web Client Authentication + - Code Signing + - E-mail Protection + - timeStamping + - OCSPSigning + - Any Extended Key Usage + - qcStatements + - DVCS + - IPSec User + - biometricInfo + subject_alt_name: + - "DNS:www.ansible.com" + - "DNS:öç.com" + # cryptography < 2.1 cannot handle certain Unicode characters + - "DNS:{{ 'www.öç' if cryptography_version.stdout is version('2.1', '<') else '☺' }}.com" + - "IP:1.2.3.4" + - "IP:::1" + - "email:test@example.org" + - "URI:https://example.org/test/index.html" + basic_constraints: + - "CA:TRUE" + - "pathlen:23" + basic_constraints_critical: true + ocsp_must_staple: true + subject_key_identifier: '{{ "00:11:22:33" if cryptography_version.stdout is version("1.3", ">=") else omit }}' + authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' + authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' + authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' + vars: + value_for_authority_cert_issuer: + - "DNS:ca.example.org" + - "IP:1.2.3.4" + +- name: Generate CSR 2 + openssl_csr: + path: '{{ remote_tmp_dir }}/csr_2.csr' + privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' + useCommonNameForSAN: false + basic_constraints: + - "CA:TRUE" + +- name: Generate CSR 3 + openssl_csr: + path: '{{ remote_tmp_dir }}/csr_3.csr' + privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' + useCommonNameForSAN: false + subject_alt_name: + - "DNS:*.ansible.com" + - "DNS:*.example.org" + - "IP:DEAD:BEEF::1" + basic_constraints: + - "CA:FALSE" + authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' + authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' + vars: + value_for_authority_cert_issuer: + - "DNS:ca.example.org" + - "IP:1.2.3.4" + +- name: Generate selfsigned certificates + x509_certificate: + path: '{{ remote_tmp_dir }}/cert_{{ item }}.pem' + csr_path: '{{ remote_tmp_dir }}/csr_{{ item }}.csr' + privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' + provider: selfsigned + selfsigned_digest: sha256 + selfsigned_not_after: "+10d" + selfsigned_not_before: "-3d" + loop: + - 1 + - 2 + - 3 + +- name: Convert PEM files to DER + command: + cmd: openssl x509 -inform PEM -outform DER -in {{ remote_tmp_dir }}/cert_{{ item }}.pem -out {{ remote_tmp_dir }}/cert_{{ item }}.der + loop: + - 1 + - 2 + - 3 + +- name: Running tests + include_tasks: impl.yml diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.10.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.10.txt index 81d34f186..a2980b921 100644 --- a/ansible_collections/community/crypto/tests/sanity/ignore-2.10.txt +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.10.txt @@ -15,6 +15,7 @@ plugins/modules/openssl_csr_info.py validate-modules:invalid-documentation plugins/modules/openssl_csr_pipe.py validate-modules:invalid-documentation plugins/modules/openssl_privatekey_info.py validate-modules:invalid-documentation plugins/modules/openssl_publickey_info.py validate-modules:invalid-documentation +plugins/modules/x509_certificate_convert.py validate-modules:invalid-documentation plugins/modules/x509_certificate_info.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:return-syntax-error diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.11.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.11.txt index 2677551db..07a994f88 100644 --- a/ansible_collections/community/crypto/tests/sanity/ignore-2.11.txt +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.11.txt @@ -14,6 +14,7 @@ plugins/modules/openssl_csr_info.py validate-modules:invalid-documentation plugins/modules/openssl_csr_pipe.py validate-modules:invalid-documentation plugins/modules/openssl_privatekey_info.py validate-modules:invalid-documentation plugins/modules/openssl_publickey_info.py validate-modules:invalid-documentation +plugins/modules/x509_certificate_convert.py validate-modules:invalid-documentation plugins/modules/x509_certificate_info.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:return-syntax-error diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.12.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.12.txt index 26e5b6864..54b6198ba 100644 --- a/ansible_collections/community/crypto/tests/sanity/ignore-2.12.txt +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.12.txt @@ -9,6 +9,7 @@ plugins/modules/openssl_csr_info.py validate-modules:invalid-documentation plugins/modules/openssl_csr_pipe.py validate-modules:invalid-documentation plugins/modules/openssl_privatekey_info.py validate-modules:invalid-documentation plugins/modules/openssl_publickey_info.py validate-modules:invalid-documentation +plugins/modules/x509_certificate_convert.py validate-modules:invalid-documentation plugins/modules/x509_certificate_info.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:return-syntax-error diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.13.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.13.txt index 74ca94712..389b3f533 100644 --- a/ansible_collections/community/crypto/tests/sanity/ignore-2.13.txt +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.13.txt @@ -8,6 +8,7 @@ plugins/modules/openssl_csr_info.py validate-modules:invalid-documentation plugins/modules/openssl_csr_pipe.py validate-modules:invalid-documentation plugins/modules/openssl_privatekey_info.py validate-modules:invalid-documentation plugins/modules/openssl_publickey_info.py validate-modules:invalid-documentation +plugins/modules/x509_certificate_convert.py validate-modules:invalid-documentation plugins/modules/x509_certificate_info.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:invalid-documentation plugins/modules/x509_crl_info.py validate-modules:invalid-documentation diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.14.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.14.txt index 74ca94712..389b3f533 100644 --- a/ansible_collections/community/crypto/tests/sanity/ignore-2.14.txt +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.14.txt @@ -8,6 +8,7 @@ plugins/modules/openssl_csr_info.py validate-modules:invalid-documentation plugins/modules/openssl_csr_pipe.py validate-modules:invalid-documentation plugins/modules/openssl_privatekey_info.py validate-modules:invalid-documentation plugins/modules/openssl_publickey_info.py validate-modules:invalid-documentation +plugins/modules/x509_certificate_convert.py validate-modules:invalid-documentation plugins/modules/x509_certificate_info.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:invalid-documentation plugins/modules/x509_crl_info.py validate-modules:invalid-documentation diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.18.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..9ffe1e998 --- /dev/null +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.18.txt @@ -0,0 +1,2 @@ +tests/ee/roles/smoke/library/smoke_ipaddress.py shebang +tests/ee/roles/smoke/library/smoke_pyyaml.py shebang diff --git a/ansible_collections/community/crypto/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/crypto/tests/sanity/ignore-2.18.txt.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.18.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/sanity/ignore-2.9.txt b/ansible_collections/community/crypto/tests/sanity/ignore-2.9.txt index e20c4e5f3..c5b2bb0bf 100644 --- a/ansible_collections/community/crypto/tests/sanity/ignore-2.9.txt +++ b/ansible_collections/community/crypto/tests/sanity/ignore-2.9.txt @@ -14,6 +14,7 @@ plugins/modules/openssl_csr_info.py validate-modules:invalid-documentation plugins/modules/openssl_csr_pipe.py validate-modules:invalid-documentation plugins/modules/openssl_privatekey_info.py validate-modules:invalid-documentation plugins/modules/openssl_publickey_info.py validate-modules:invalid-documentation +plugins/modules/x509_certificate_convert.py validate-modules:invalid-documentation plugins/modules/x509_certificate_info.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:invalid-documentation plugins/modules/x509_crl.py validate-modules:return-syntax-error diff --git a/ansible_collections/community/dns/.github/workflows/ansible-test.yml b/ansible_collections/community/dns/.github/workflows/ansible-test.yml index 7ed813e13..186079a41 100644 --- a/ansible_collections/community/dns/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/dns/.github/workflows/ansible-test.yml @@ -37,6 +37,7 @@ jobs: - 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 @@ -78,6 +79,7 @@ jobs: - stable-2.14 - stable-2.15 - stable-2.16 + - stable-2.17 - devel steps: @@ -111,7 +113,6 @@ jobs: ansible: - devel python: - - 3.7 - 3.8 - 3.9 - "3.10" @@ -150,6 +151,11 @@ jobs: python: "3.6" - ansible: stable-2.16 python: "3.11" + # 2.17 + - ansible: stable-2.17 + python: "3.7" + - ansible: stable-2.17 + python: "3.12" steps: - name: >- diff --git a/ansible_collections/community/dns/.github/workflows/docs-pr.yml b/ansible_collections/community/dns/.github/workflows/docs-pr.yml index cc71d2492..63c021d46 100644 --- a/ansible_collections/community/dns/.github/workflows/docs-pr.yml +++ b/ansible_collections/community/dns/.github/workflows/docs-pr.yml @@ -32,6 +32,7 @@ jobs: init-extra-html-theme-options: | documentation_home_url=https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/branch/main/ render-file-line: '> * `$<status>` [$<path_tail>](https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr/${{ github.event.number }}/$<path_tail>)' + extra-collections: community.library_inventory_filtering_v1 publish-docs-gh-pages: # for now we won't run this on forks diff --git a/ansible_collections/community/dns/.github/workflows/docs-push.yml b/ansible_collections/community/dns/.github/workflows/docs-push.yml index 85274e17d..f03ef77fb 100644 --- a/ansible_collections/community/dns/.github/workflows/docs-push.yml +++ b/ansible_collections/community/dns/.github/workflows/docs-push.yml @@ -37,6 +37,7 @@ jobs: init-html-short-title: Community.Dns Collection Docs init-extra-html-theme-options: | documentation_home_url=https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/branch/main/ + extra-collections: community.library_inventory_filtering_v1 publish-docs-gh-pages: # for now we won't run this on forks diff --git a/ansible_collections/community/dns/CHANGELOG.md b/ansible_collections/community/dns/CHANGELOG.md index fbce77c60..9881ee7ed 100644 --- a/ansible_collections/community/dns/CHANGELOG.md +++ b/ansible_collections/community/dns/CHANGELOG.md @@ -2,188 +2,216 @@ **Topics** -- <a href="#v2-8-3">v2\.8\.3</a> +- <a href="#v2-9-0">v2\.9\.0</a> - <a href="#release-summary">Release Summary</a> - <a href="#bugfixes">Bugfixes</a> -- <a href="#v2-8-2">v2\.8\.2</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="#security-fixes">Security Fixes</a> - <a href="#bugfixes-1">Bugfixes</a> -- <a href="#v2-8-1">v2\.8\.1</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-0">v2\.8\.0</a> +- <a href="#v2-8-1">v2\.8\.1</a> - <a href="#release-summary-3">Release Summary</a> - - <a href="#minor-changes">Minor Changes</a> - - <a href="#deprecated-features">Deprecated Features</a> - <a href="#bugfixes-3">Bugfixes</a> -- <a href="#v2-7-0">v2\.7\.0</a> +- <a href="#v2-8-0">v2\.8\.0</a> - <a href="#release-summary-4">Release Summary</a> - - <a href="#minor-changes-1">Minor Changes</a> + - <a href="#minor-changes">Minor Changes</a> + - <a href="#deprecated-features">Deprecated Features</a> - <a href="#bugfixes-4">Bugfixes</a> -- <a href="#v2-6-4">v2\.6\.4</a> +- <a href="#v2-7-0">v2\.7\.0</a> - <a href="#release-summary-5">Release Summary</a> + - <a href="#minor-changes-1">Minor Changes</a> - <a href="#bugfixes-5">Bugfixes</a> -- <a href="#v2-6-3">v2\.6\.3</a> +- <a href="#v2-6-4">v2\.6\.4</a> - <a href="#release-summary-6">Release Summary</a> - <a href="#bugfixes-6">Bugfixes</a> -- <a href="#v2-6-2">v2\.6\.2</a> +- <a href="#v2-6-3">v2\.6\.3</a> - <a href="#release-summary-7">Release Summary</a> - <a href="#bugfixes-7">Bugfixes</a> -- <a href="#v2-6-1">v2\.6\.1</a> +- <a href="#v2-6-2">v2\.6\.2</a> - <a href="#release-summary-8">Release Summary</a> - <a href="#bugfixes-8">Bugfixes</a> -- <a href="#v2-6-0">v2\.6\.0</a> +- <a href="#v2-6-1">v2\.6\.1</a> - <a href="#release-summary-9">Release Summary</a> - - <a href="#minor-changes-2">Minor Changes</a> - <a href="#bugfixes-9">Bugfixes</a> - - <a href="#new-plugins">New Plugins</a> +- <a href="#v2-6-0">v2\.6\.0</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="#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-10">Release Summary</a> - - <a href="#bugfixes-10">Bugfixes</a> -- <a href="#v2-5-6">v2\.5\.6</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="#known-issues">Known Issues</a> - <a href="#v2-5-5">v2\.5\.5</a> - - <a href="#release-summary-12">Release Summary</a> - - <a href="#bugfixes-11">Bugfixes</a> -- <a href="#v2-5-4">v2\.5\.4</a> - <a href="#release-summary-13">Release Summary</a> - <a href="#bugfixes-12">Bugfixes</a> -- <a href="#v2-5-3">v2\.5\.3</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-2">v2\.5\.2</a> +- <a href="#v2-5-3">v2\.5\.3</a> - <a href="#release-summary-15">Release Summary</a> - <a href="#bugfixes-14">Bugfixes</a> -- <a href="#v2-5-1">v2\.5\.1</a> +- <a href="#v2-5-2">v2\.5\.2</a> - <a href="#release-summary-16">Release Summary</a> - <a href="#bugfixes-15">Bugfixes</a> -- <a href="#v2-5-0">v2\.5\.0</a> +- <a href="#v2-5-1">v2\.5\.1</a> - <a href="#release-summary-17">Release Summary</a> - - <a href="#minor-changes-3">Minor Changes</a> - - <a href="#deprecated-features-1">Deprecated Features</a> - <a href="#bugfixes-16">Bugfixes</a> -- <a href="#v2-4-2">v2\.4\.2</a> +- <a href="#v2-5-0">v2\.5\.0</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-1">v2\.4\.1</a> +- <a href="#v2-4-2">v2\.4\.2</a> - <a href="#release-summary-19">Release Summary</a> - <a href="#bugfixes-18">Bugfixes</a> -- <a href="#v2-4-0">v2\.4\.0</a> +- <a href="#v2-4-1">v2\.4\.1</a> - <a href="#release-summary-20">Release Summary</a> - - <a href="#minor-changes-4">Minor Changes</a> - <a href="#bugfixes-19">Bugfixes</a> -- <a href="#v2-3-4">v2\.3\.4</a> +- <a href="#v2-4-0">v2\.4\.0</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-3">v2\.3\.3</a> +- <a href="#v2-3-4">v2\.3\.4</a> - <a href="#release-summary-22">Release Summary</a> - <a href="#bugfixes-21">Bugfixes</a> -- <a href="#v2-3-2">v2\.3\.2</a> +- <a href="#v2-3-3">v2\.3\.3</a> - <a href="#release-summary-23">Release Summary</a> - <a href="#bugfixes-22">Bugfixes</a> -- <a href="#v2-3-1">v2\.3\.1</a> +- <a href="#v2-3-2">v2\.3\.2</a> - <a href="#release-summary-24">Release Summary</a> - - <a href="#minor-changes-5">Minor Changes</a> - <a href="#bugfixes-23">Bugfixes</a> -- <a href="#v2-3-0">v2\.3\.0</a> +- <a href="#v2-3-1">v2\.3\.1</a> - <a href="#release-summary-25">Release Summary</a> - - <a href="#minor-changes-6">Minor Changes</a> + - <a href="#minor-changes-5">Minor Changes</a> - <a href="#bugfixes-24">Bugfixes</a> -- <a href="#v2-2-1">v2\.2\.1</a> +- <a href="#v2-3-0">v2\.3\.0</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-0">v2\.2\.0</a> +- <a href="#v2-2-1">v2\.2\.1</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-1-1">v2\.1\.1</a> +- <a href="#v2-2-0">v2\.2\.0</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-0">v2\.1\.0</a> +- <a href="#v2-1-1">v2\.1\.1</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-0-9">v2\.0\.9</a> +- <a href="#v2-1-0">v2\.1\.0</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-8">v2\.0\.8</a> +- <a href="#v2-0-9">v2\.0\.9</a> - <a href="#release-summary-31">Release Summary</a> - <a href="#bugfixes-30">Bugfixes</a> -- <a href="#v2-0-7">v2\.0\.7</a> +- <a href="#v2-0-8">v2\.0\.8</a> - <a href="#release-summary-32">Release Summary</a> - <a href="#bugfixes-31">Bugfixes</a> -- <a href="#v2-0-6">v2\.0\.6</a> +- <a href="#v2-0-7">v2\.0\.7</a> - <a href="#release-summary-33">Release Summary</a> - <a href="#bugfixes-32">Bugfixes</a> -- <a href="#v2-0-5">v2\.0\.5</a> +- <a href="#v2-0-6">v2\.0\.6</a> - <a href="#release-summary-34">Release Summary</a> - <a href="#bugfixes-33">Bugfixes</a> -- <a href="#v2-0-4">v2\.0\.4</a> +- <a href="#v2-0-5">v2\.0\.5</a> - <a href="#release-summary-35">Release Summary</a> - <a href="#bugfixes-34">Bugfixes</a> -- <a href="#v2-0-3">v2\.0\.3</a> +- <a href="#v2-0-4">v2\.0\.4</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="#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-37">Release Summary</a> - - <a href="#bugfixes-35">Bugfixes</a> -- <a href="#v2-0-1">v2\.0\.1</a> - <a href="#release-summary-38">Release Summary</a> - <a href="#bugfixes-36">Bugfixes</a> -- <a href="#v2-0-0">v2\.0\.0</a> +- <a href="#v2-0-1">v2\.0\.1</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="#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-37">Bugfixes</a> - - <a href="#new-plugins-1">New Plugins</a> + - <a href="#bugfixes-38">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-40">Release Summary</a> - - <a href="#minor-changes-11">Minor Changes</a> - - <a href="#bugfixes-38">Bugfixes</a> -- <a href="#v1-1-0">v1\.1\.0</a> - <a href="#release-summary-41">Release Summary</a> - - <a href="#minor-changes-12">Minor Changes</a> + - <a href="#minor-changes-11">Minor Changes</a> - <a href="#bugfixes-39">Bugfixes</a> -- <a href="#v1-0-1">v1\.0\.1</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-0">v1\.0\.0</a> +- <a href="#v1-0-1">v1\.0\.1</a> - <a href="#release-summary-43">Release Summary</a> - <a href="#bugfixes-41">Bugfixes</a> -- <a href="#v0-3-0">v0\.3\.0</a> +- <a href="#v1-0-0">v1\.0\.0</a> - <a href="#release-summary-44">Release Summary</a> - - <a href="#minor-changes-13">Minor Changes</a> - <a href="#bugfixes-42">Bugfixes</a> +- <a href="#v0-3-0">v0\.3\.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="#release-summary-45">Release Summary</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-43">Bugfixes</a> + - <a href="#bugfixes-44">Bugfixes</a> - <a href="#new-modules-3">New Modules</a> - <a href="#v0-1-0">v0\.1\.0</a> - - <a href="#release-summary-46">Release Summary</a> - - <a href="#new-plugins-2">New Plugins</a> - - <a href="#filter">Filter</a> + - <a href="#release-summary-47">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="v2-9-0"></a> +## v2\.9\.0 + +<a id="release-summary"></a> +### Release Summary + +Feature and bugfix release\. + +<a id="bugfixes"></a> +### Bugfixes + +* Update Public Suffix List\. +* 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\.dns/pull/197](https\://github\.com/ansible\-collections/community\.dns/pull/197)\)\. + +<a id="new-plugins"></a> +### New Plugins + +<a id="filter"></a> +#### Filter + +* community\.dns\.quote\_txt \- Quotes a string to use as a TXT record entry +* community\.dns\.unquote\_txt \- Unquotes a TXT record entry to a string + <a id="v2-8-3"></a> ## v2\.8\.3 -<a id="release-summary"></a> +<a id="release-summary-1"></a> ### Release Summary Bugfix release\. -<a id="bugfixes"></a> +<a id="bugfixes-1"></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)\)\. @@ -192,7 +220,7 @@ Bugfix release\. <a id="v2-8-2"></a> ## v2\.8\.2 -<a id="release-summary-1"></a> +<a id="release-summary-2"></a> ### Release Summary Bugfix release\. @@ -202,7 +230,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-1"></a> +<a id="bugfixes-2"></a> ### Bugfixes * Update Public Suffix List\. @@ -210,12 +238,12 @@ Bugfix release\. <a id="v2-8-1"></a> ## v2\.8\.1 -<a id="release-summary-2"></a> +<a id="release-summary-3"></a> ### Release Summary Maintenance release with updated PSL\. -<a id="bugfixes-2"></a> +<a id="bugfixes-3"></a> ### Bugfixes * Update Public Suffix List\. @@ -223,7 +251,7 @@ Maintenance release with updated PSL\. <a id="v2-8-0"></a> ## v2\.8\.0 -<a id="release-summary-3"></a> +<a id="release-summary-4"></a> ### Release Summary Feature and maintenance release with updated PSL\. @@ -238,7 +266,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-3"></a> +<a id="bugfixes-4"></a> ### Bugfixes * Update Public Suffix List\. @@ -246,7 +274,7 @@ Feature and maintenance release with updated PSL\. <a id="v2-7-0"></a> ## v2\.7\.0 -<a id="release-summary-4"></a> +<a id="release-summary-5"></a> ### Release Summary Bugfix and feature release with updated PSL\. @@ -257,7 +285,7 @@ Bugfix and feature release with updated PSL\. * 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-4"></a> +<a id="bugfixes-5"></a> ### Bugfixes * Update Public Suffix List\. @@ -266,12 +294,12 @@ Bugfix and feature release with updated PSL\. <a id="v2-6-4"></a> ## v2\.6\.4 -<a id="release-summary-5"></a> +<a id="release-summary-6"></a> ### Release Summary Bugfix and maintenance version\. -<a id="bugfixes-5"></a> +<a id="bugfixes-6"></a> ### Bugfixes * Update Public Suffix List\. @@ -280,12 +308,12 @@ Bugfix and maintenance version\. <a id="v2-6-3"></a> ## v2\.6\.3 -<a id="release-summary-6"></a> +<a id="release-summary-7"></a> ### Release Summary Maintenance release with updated PSL\. -<a id="bugfixes-6"></a> +<a id="bugfixes-7"></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)\)\. @@ -294,12 +322,12 @@ Maintenance release with updated PSL\. <a id="v2-6-2"></a> ## v2\.6\.2 -<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 * Update Public Suffix List\. @@ -307,12 +335,12 @@ Maintenance release with updated PSL\. <a id="v2-6-1"></a> ## v2\.6\.1 -<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\. @@ -320,7 +348,7 @@ Maintenance release with updated PSL\. <a id="v2-6-0"></a> ## v2\.6\.0 -<a id="release-summary-9"></a> +<a id="release-summary-10"></a> ### Release Summary Feature release with an updated Public Suffix List\. @@ -331,13 +359,13 @@ Feature release with an updated Public Suffix List\. * 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-9"></a> +<a id="bugfixes-10"></a> ### Bugfixes * Update Public Suffix List\. * wait\_for\_txt\, resolver module utils \- improve error handling \([https\://github\.com/ansible\-collections/community\.dns/pull/158](https\://github\.com/ansible\-collections/community\.dns/pull/158)\)\. -<a id="new-plugins"></a> +<a id="new-plugins-1"></a> ### New Plugins <a id="lookup"></a> @@ -355,12 +383,12 @@ Feature release with an updated Public Suffix List\. <a id="v2-5-7"></a> ## v2\.5\.7 -<a id="release-summary-10"></a> +<a id="release-summary-11"></a> ### Release Summary Regular maintenance release with updated Public Suffix List\. -<a id="bugfixes-10"></a> +<a id="bugfixes-11"></a> ### Bugfixes * Update Public Suffix List\. @@ -368,7 +396,7 @@ Regular maintenance release with updated Public Suffix List\. <a id="v2-5-6"></a> ## v2\.5\.6 -<a id="release-summary-11"></a> +<a id="release-summary-12"></a> ### Release Summary Maintenance release\. @@ -389,12 +417,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-12"></a> +<a id="release-summary-13"></a> ### Release Summary Maintenance release with updated PSL\. -<a id="bugfixes-11"></a> +<a id="bugfixes-12"></a> ### Bugfixes * Update Public Suffix List\. @@ -402,12 +430,12 @@ Maintenance release with updated PSL\. <a id="v2-5-4"></a> ## v2\.5\.4 -<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\. @@ -415,12 +443,12 @@ Maintenance release with updated PSL\. <a id="v2-5-3"></a> ## v2\.5\.3 -<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\. @@ -428,12 +456,12 @@ Maintenance release with updated PSL\. <a id="v2-5-2"></a> ## v2\.5\.2 -<a id="release-summary-15"></a> +<a id="release-summary-16"></a> ### Release Summary Maintenance release with improved documentation and updated PSL\. -<a id="bugfixes-14"></a> +<a id="bugfixes-15"></a> ### Bugfixes * Update Public Suffix List\. @@ -441,12 +469,12 @@ Maintenance release with improved documentation and updated PSL\. <a id="v2-5-1"></a> ## v2\.5\.1 -<a id="release-summary-16"></a> +<a id="release-summary-17"></a> ### Release Summary Maintenance release \(updated PSL\)\. -<a id="bugfixes-15"></a> +<a id="bugfixes-16"></a> ### Bugfixes * Update Public Suffix List\. @@ -454,7 +482,7 @@ Maintenance release \(updated PSL\)\. <a id="v2-5-0"></a> ## v2\.5\.0 -<a id="release-summary-17"></a> +<a id="release-summary-18"></a> ### Release Summary Feature and bugfix release with updated PSL\. @@ -470,7 +498,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-16"></a> +<a id="bugfixes-17"></a> ### Bugfixes * Update Public Suffix List\. @@ -479,12 +507,12 @@ Feature and bugfix release with updated PSL\. <a id="v2-4-2"></a> ## v2\.4\.2 -<a id="release-summary-18"></a> +<a id="release-summary-19"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-17"></a> +<a id="bugfixes-18"></a> ### Bugfixes * Update Public Suffix List\. @@ -492,12 +520,12 @@ Maintenance release with updated Public Suffix List\. <a id="v2-4-1"></a> ## v2\.4\.1 -<a id="release-summary-19"></a> +<a id="release-summary-20"></a> ### Release Summary Regular maintenance release\. -<a id="bugfixes-18"></a> +<a id="bugfixes-19"></a> ### Bugfixes * Update Public Suffix List\. @@ -506,7 +534,7 @@ Regular maintenance release\. <a id="v2-4-0"></a> ## v2\.4\.0 -<a id="release-summary-20"></a> +<a id="release-summary-21"></a> ### Release Summary Feature and maintenance release\. @@ -518,7 +546,7 @@ Feature and maintenance release\. * 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-19"></a> +<a id="bugfixes-20"></a> ### Bugfixes * Update Public Suffix List\. @@ -526,12 +554,12 @@ Feature and maintenance release\. <a id="v2-3-4"></a> ## v2\.3\.4 -<a id="release-summary-21"></a> +<a id="release-summary-22"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-20"></a> +<a id="bugfixes-21"></a> ### Bugfixes * Update Public Suffix List\. @@ -539,12 +567,12 @@ Maintenance release with updated Public Suffix List\. <a id="v2-3-3"></a> ## v2\.3\.3 -<a id="release-summary-22"></a> +<a id="release-summary-23"></a> ### Release Summary Maintenance release including an updated Public Suffix List\. -<a id="bugfixes-21"></a> +<a id="bugfixes-22"></a> ### Bugfixes * Update Public Suffix List\. @@ -552,12 +580,12 @@ Maintenance release including an updated Public Suffix List\. <a id="v2-3-2"></a> ## v2\.3\.2 -<a id="release-summary-23"></a> +<a id="release-summary-24"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-22"></a> +<a id="bugfixes-23"></a> ### Bugfixes * Update Public Suffix List\. @@ -565,7 +593,7 @@ Maintenance release with updated Public Suffix List\. <a id="v2-3-1"></a> ## v2\.3\.1 -<a id="release-summary-24"></a> +<a id="release-summary-25"></a> ### Release Summary Maintenance release including an updated Public Suffix List\. @@ -575,7 +603,7 @@ Maintenance release including an updated Public Suffix List\. * 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-23"></a> +<a id="bugfixes-24"></a> ### Bugfixes * Update Public Suffix List\. @@ -583,7 +611,7 @@ Maintenance release including an updated Public Suffix List\. <a id="v2-3-0"></a> ## v2\.3\.0 -<a id="release-summary-25"></a> +<a id="release-summary-26"></a> ### Release Summary Maintenance release including an updated Public Suffix List\. @@ -593,7 +621,7 @@ Maintenance release including an updated Public Suffix List\. * 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-24"></a> +<a id="bugfixes-25"></a> ### Bugfixes * Update Public Suffix List\. @@ -601,12 +629,12 @@ Maintenance release including an updated Public Suffix List\. <a id="v2-2-1"></a> ## v2\.2\.1 -<a id="release-summary-26"></a> +<a id="release-summary-27"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-25"></a> +<a id="bugfixes-26"></a> ### Bugfixes * Update Public Suffix List\. @@ -614,7 +642,7 @@ Maintenance release with updated Public Suffix List\. <a id="v2-2-0"></a> ## v2\.2\.0 -<a id="release-summary-27"></a> +<a id="release-summary-28"></a> ### Release Summary Feature release\. @@ -625,7 +653,7 @@ Feature release\. * 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-26"></a> +<a id="bugfixes-27"></a> ### Bugfixes * Update Public Suffix List\. @@ -633,12 +661,12 @@ Feature release\. <a id="v2-1-1"></a> ## v2\.1\.1 -<a id="release-summary-28"></a> +<a id="release-summary-29"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-27"></a> +<a id="bugfixes-28"></a> ### Bugfixes * Update Public Suffix List\. @@ -646,7 +674,7 @@ Maintenance release with updated Public Suffix List\. <a id="v2-1-0"></a> ## v2\.1\.0 -<a id="release-summary-29"></a> +<a id="release-summary-30"></a> ### Release Summary Feature and maintenance release with updated PSL\. @@ -656,7 +684,7 @@ Feature and maintenance release with updated PSL\. * 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-28"></a> +<a id="bugfixes-29"></a> ### Bugfixes * Update Public Suffix List\. @@ -664,12 +692,12 @@ Feature and maintenance release with updated PSL\. <a id="v2-0-9"></a> ## v2\.0\.9 -<a id="release-summary-30"></a> +<a id="release-summary-31"></a> ### Release Summary Maintenance release with updated Public Suffix List and added collection links file\. -<a id="bugfixes-29"></a> +<a id="bugfixes-30"></a> ### Bugfixes * Update Public Suffix List\. @@ -677,12 +705,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-31"></a> +<a id="release-summary-32"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-30"></a> +<a id="bugfixes-31"></a> ### Bugfixes * Update Public Suffix List\. @@ -690,12 +718,12 @@ Maintenance release with updated Public Suffix List\. <a id="v2-0-7"></a> ## v2\.0\.7 -<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\. @@ -703,12 +731,12 @@ Maintenance release with updated Public Suffix List\. <a id="v2-0-6"></a> ## v2\.0\.6 -<a id="release-summary-33"></a> +<a id="release-summary-34"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-32"></a> +<a id="bugfixes-33"></a> ### Bugfixes * Update Public Suffix List\. @@ -717,12 +745,12 @@ Bugfix release\. <a id="v2-0-5"></a> ## v2\.0\.5 -<a id="release-summary-34"></a> +<a id="release-summary-35"></a> ### Release Summary Maintenance release with updated Public Suffix List\. -<a id="bugfixes-33"></a> +<a id="bugfixes-34"></a> ### Bugfixes * Update Public Suffix List\. @@ -730,12 +758,12 @@ Maintenance release with updated Public Suffix List\. <a id="v2-0-4"></a> ## v2\.0\.4 -<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\. @@ -743,7 +771,7 @@ Maintenance release with updated Public Suffix List\. <a id="v2-0-3"></a> ## v2\.0\.3 -<a id="release-summary-36"></a> +<a id="release-summary-37"></a> ### Release Summary Bugfix release\. @@ -756,12 +784,12 @@ Bugfix release\. <a id="v2-0-2"></a> ## v2\.0\.2 -<a id="release-summary-37"></a> +<a id="release-summary-38"></a> ### Release Summary Regular maintenance release\. -<a id="bugfixes-35"></a> +<a id="bugfixes-36"></a> ### Bugfixes * Update Public Suffix List\. @@ -769,12 +797,12 @@ Regular maintenance release\. <a id="v2-0-1"></a> ## v2\.0\.1 -<a id="release-summary-38"></a> +<a id="release-summary-39"></a> ### Release Summary Maintenance release with Public Suffix List updates\. -<a id="bugfixes-36"></a> +<a id="bugfixes-37"></a> ### Bugfixes * Update Public Suffix List\. @@ -782,7 +810,7 @@ Maintenance release with Public Suffix List updates\. <a id="v2-0-0"></a> ## v2\.0\.0 -<a id="release-summary-39"></a> +<a id="release-summary-40"></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\. @@ -822,7 +850,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-37"></a> +<a id="bugfixes-38"></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)\)\. @@ -834,7 +862,7 @@ This release contains many new features\, modules and plugins\, but also has sev * wait\_for\_txt \- fix handling of too long TXT values \([https\://github\.com/ansible\-collections/community\.dns/pull/65](https\://github\.com/ansible\-collections/community\.dns/pull/65)\)\. * wait\_for\_txt \- resolving nameservers sometimes resulted in an empty list\, yielding wrong results \([https\://github\.com/ansible\-collections/community\.dns/pull/64](https\://github\.com/ansible\-collections/community\.dns/pull/64)\)\. -<a id="new-plugins-1"></a> +<a id="new-plugins-2"></a> ### New Plugins <a id="inventory"></a> @@ -860,7 +888,7 @@ 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-40"></a> +<a id="release-summary-41"></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\. @@ -872,7 +900,7 @@ Last minor 1\.x\.0 version\. The 2\.0\.0 version will have some backwards incomp * 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-38"></a> +<a id="bugfixes-39"></a> ### Bugfixes * Update Public Suffix List\. @@ -881,7 +909,7 @@ 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-41"></a> +<a id="release-summary-42"></a> ### Release Summary Regular maintenance release\. @@ -891,7 +919,7 @@ Regular maintenance release\. * 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-39"></a> +<a id="bugfixes-40"></a> ### Bugfixes * Update Public Suffix List\. @@ -899,12 +927,12 @@ Regular maintenance release\. <a id="v1-0-1"></a> ## v1\.0\.1 -<a id="release-summary-42"></a> +<a id="release-summary-43"></a> ### Release Summary Regular maintenance release\. -<a id="bugfixes-40"></a> +<a id="bugfixes-41"></a> ### Bugfixes * Update Public Suffix List\. @@ -912,12 +940,12 @@ Regular maintenance release\. <a id="v1-0-0"></a> ## v1\.0\.0 -<a id="release-summary-43"></a> +<a id="release-summary-44"></a> ### Release Summary First stable release\. -<a id="bugfixes-41"></a> +<a id="bugfixes-42"></a> ### Bugfixes * Update Public Suffix List\. @@ -925,7 +953,7 @@ First stable release\. <a id="v0-3-0"></a> ## v0\.3\.0 -<a id="release-summary-44"></a> +<a id="release-summary-45"></a> ### Release Summary Fixes bugs\, adds rate limiting for Hosttech JSON API\, and adds a new bulk synchronization module\. @@ -935,7 +963,7 @@ Fixes bugs\, adds rate limiting for Hosttech JSON API\, and adds a new bulk sync * 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-42"></a> +<a id="bugfixes-43"></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)\)\. @@ -949,7 +977,7 @@ 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-45"></a> +<a id="release-summary-46"></a> ### Release Summary Major refactoring release\, which adds a zone information module and supports HostTech\'s new REST API\. @@ -974,7 +1002,7 @@ Major refactoring release\, which adds a zone information module and supports Ho * 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-43"></a> +<a id="bugfixes-44"></a> ### Bugfixes * Update Public Suffix List\. @@ -989,15 +1017,15 @@ 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-46"></a> +<a id="release-summary-47"></a> ### Release Summary Initial public release\. -<a id="new-plugins-2"></a> +<a id="new-plugins-3"></a> ### New Plugins -<a id="filter"></a> +<a id="filter-1"></a> #### Filter * community\.dns\.get\_public\_suffix \- Returns the public suffix of a DNS name diff --git a/ansible_collections/community/dns/CHANGELOG.rst b/ansible_collections/community/dns/CHANGELOG.rst index 37b4a2500..e91d83ebf 100644 --- a/ansible_collections/community/dns/CHANGELOG.rst +++ b/ansible_collections/community/dns/CHANGELOG.rst @@ -4,6 +4,29 @@ Community DNS Collection Release Notes .. contents:: Topics +v2.9.0 +====== + +Release Summary +--------------- + +Feature and bugfix release. + +Bugfixes +-------- + +- Update Public Suffix List. +- 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.dns/pull/197). + +New Plugins +----------- + +Filter +~~~~~~ + +- community.dns.quote_txt - Quotes a string to use as a TXT record entry +- community.dns.unquote_txt - Unquotes a TXT record entry to a string + v2.8.3 ====== diff --git a/ansible_collections/community/dns/FILES.json b/ansible_collections/community/dns/FILES.json index 8bda06632..52b3239cd 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": "cb9ff13908693ca232d8a96c732b37b686549b5a18c58241a40c14cafe97dec0", + "chksum_sha256": "4ef2a19d9715b2b9a70a6fe716ec40726b3c425f3c2b96d9bfe5d12489f74574", "format": 1 }, { @@ -39,14 +39,14 @@ "name": ".github/workflows/docs-pr.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "fa2c8b94ec1355012d9b65d624ad400b327dfbb062cdc7407eb780a892524316", + "chksum_sha256": "dc9bab4e75bea6ee0b6887dd79d1f60ee31f938dc2b1992bfcd263cc623f290c", "format": 1 }, { "name": ".github/workflows/docs-push.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "88f3e91fc95a639fc831039a0503838f9850c51aedc52de0ef7adcfc7939ba4a", + "chksum_sha256": "005d031f01cb3322476bff7beec23f958cea6a2a9790e913771d40c360d2dcb2", "format": 1 }, { @@ -151,7 +151,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "86ce7da485fe12025925410c18b8b391fccc9b84dffff900037604813663277f", + "chksum_sha256": "d6afad220bd94bbf6ffd765666b7589d04b014238a3e02973e066958c44acf43", "format": 1 }, { @@ -193,7 +193,7 @@ "name": "docs/docsite/rst/filter_guide.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b407b72d65102202fc82d449bef8dd026f4d2debb9f7140fa6ac664a4cd4f5fc", + "chksum_sha256": "1af966088512f426e9ed72ce98dac4324fc02ddeafc33a0f70459b2c9bfe9ed7", "format": 1 }, { @@ -211,6 +211,13 @@ "format": 1 }, { + "name": "docs/docsite/config.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0c5ec9ff76cf4db33b5d3f771419ef50d448e5d510cb7a98fc07dd9ecee69c4e", + "format": 1 + }, + { "name": "docs/docsite/extra-docs.yml", "ftype": "file", "chksum_type": "sha256", @@ -379,6 +386,13 @@ "format": 1 }, { + "name": "plugins/filter/quote_txt.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0539523d52bfbe0e0eb6b6d40a5e371fb4cc4705a3eab73eeb3c52198a74023b", + "format": 1 + }, + { "name": "plugins/filter/remove_public_suffix.yml", "ftype": "file", "chksum_type": "sha256", @@ -393,6 +407,20 @@ "format": 1 }, { + "name": "plugins/filter/txt.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1b6220db5e9ea678b67c1a5c31f60df50f6624c6cbd89e9531b95358f2675267", + "format": 1 + }, + { + "name": "plugins/filter/unquote_txt.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "58f2b5e0a6c736160a540b4ea3b7106465223d7c82c5480f71d3e39c7736c56e", + "format": 1 + }, + { "name": "plugins/inventory", "ftype": "dir", "chksum_type": null, @@ -802,7 +830,7 @@ "name": "plugins/plugin_utils/inventory/records.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c77b1d234e40d804759699724336db0683f6c9173f8e36c69b8b0e3d3a33a50c", + "chksum_sha256": "768ceedc4f0b624a22f9b777452f143e0b88639c1bd7e5f861d789ec0269e6e1", "format": 1 }, { @@ -834,10 +862,17 @@ "format": 1 }, { + "name": "plugins/plugin_utils/unsafe.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "93ccc2e18634405c7ff21a91a1df4f17261ac24b0f41bf3c46dbec2f254538c3", + "format": 1 + }, + { "name": "plugins/public_suffix_list.dat", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9bf809262c4506519ef0c2d89681b77c8a87d2bcf5d17d7b0496840c1451cfd9", + "chksum_sha256": "27ae0b652366e8c5675942482de87819cf7947f5f4dc7bc661dc82b9b5da2d04", "format": 1 }, { @@ -960,6 +995,34 @@ "format": 1 }, { + "name": "tests/integration/targets/filter_txt", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/filter_txt/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/filter_txt/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ec0d81efcabab342ec8b892fdf9bcd54bf488a3b92a81a0efbe09f26e2d80c27", + "format": 1 + }, + { + "name": "tests/integration/targets/filter_txt/aliases", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "92c856873b6b98a3a818dc09e1ba4cdd2e0e01449f1a28d6716eff605f1d2b01", + "format": 1 + }, + { "name": "tests/integration/targets/hetzner", "ftype": "dir", "chksum_type": null, @@ -1464,6 +1527,20 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e6ba33006d3aa232443f145cbbc66c1eb5a4c06e75b6a9c63e89972c990d2786", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.18.txt.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "tests/sanity/ignore-2.9.txt", "ftype": "file", "chksum_type": "sha256", @@ -1502,14 +1579,14 @@ "name": "tests/unit/plugins/inventory/test_hetzner_dns_records.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b0a2245e3bc7a899c5ba90f7ea85471fa5f3c26aa612ac859e3cf0ede691ea44", + "chksum_sha256": "fcb263ece98ce1696cd5bbe594b86911d3365d9e8dfd9858ffbf6735c5dd46d2", "format": 1 }, { "name": "tests/unit/plugins/inventory/test_hosttech_dns_records.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c8c44d2037060fbfbaab8d05fc3af1d78513af2a5d91d872199aa75768a82b93", + "chksum_sha256": "20aafd958aa2e24b07b610c7d4efbee67cab74ecaada25876889564de7fe01d6", "format": 1 }, { @@ -1859,7 +1936,7 @@ "name": "tests/unit/requirements-stable-2.10.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1404c050017797dba43f1a8963794f33afaf0e5667abc792c062adf8ac84c254", + "chksum_sha256": "08f43f18582bbe66234f21183103b9c101b9f3a77248c8a27789283b9d6b4306", "format": 1 }, { @@ -1894,7 +1971,7 @@ "name": "CHANGELOG.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ab12a2e489b31f469f321b053a4cb432216fe20e8374cd0ffb4ecf68bc8c7348", + "chksum_sha256": "bc56ad1ca72650697ca9f41b004a70f54ef329c79938268b1430d0dac8fa51d6", "format": 1 }, { @@ -1908,7 +1985,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a2deefeaf4feaee535b1f34f517495188be0c31c22c1e5a33e470f86245dc92f", + "chksum_sha256": "6dd1dbacede2c19ab983288d1fccde3d6369642593b1da10029cdf53e6b3176c", "format": 1 }, { @@ -1936,7 +2013,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9083e4932c4b72abbc6c7382b3c964df7826b1a12a49f4d2e34cc36155380fd7", + "chksum_sha256": "61615f641d8efd57833806770c66a86dfe2ceb595df9fe1e9ef1fc0d9e2bfab4", "format": 1 }, { diff --git a/ansible_collections/community/dns/MANIFEST.json b/ansible_collections/community/dns/MANIFEST.json index fcbfda5d6..0c60fe528 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.8.3", + "version": "2.9.0", "authors": [ "Felix Fontein (github.com/felixfontein)", "Markus Bergholz (github.com/markuman)" @@ -30,7 +30,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8234c71782176e94860f305e6a9e4365b2167e2bd47e59e9c580a1011fc96b39", + "chksum_sha256": "723a758354360ce388c0f83a88527e05dc67d3bcad6495e66deca44b8a169d12", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/dns/README.md b/ansible_collections/community/dns/README.md index 8a404fa3a..32257a110 100644 --- a/ansible_collections/community/dns/README.md +++ b/ansible_collections/community/dns/README.md @@ -16,7 +16,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, and ansible-core 2.16 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. +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. ## External requirements @@ -61,6 +61,8 @@ If you use the Ansible package and do not update collections independently, use - `get_registrable_domain`: given a domain name, returns the *registrable domain name* (also called *registered domain name*). For example, `"www.ansible.com" | community.dns.get_registrable_domain == "ansible.com"` and `"some.random.prefixes.ansible.co.uk" | community.dns.get_registrable_domain == "ansible.co.uk"`. - `remove_public_suffix`: given a domain name, returns the part before the public suffix. For example, `"www.ansible.com" | community.dns.remove_public_suffix == "www.ansible"` and `"some.random.prefixes.ansible.co.uk" | community.dns.remove_public_suffix == "some.random.prefixes.ansible"`. - `remove_registrable_domain`: given a domain name, returns the part before the DNS zone. For example, `"www.ansible.com" | community.dns.remove_registrable_domain == "www"` and `"some.random.prefixes.ansible.co.uk" | community.dns.remove_registrable_domain == "some.random.prefixes"`. + - `quote_txt`: quotes a string for use as a TXT record entry. For example, `"this is a test" | community.dns.quote_txt == '"this is a test"'`. + - `unquote_txt`: unquotes a TXT record entry. For example, `'"foo" "bar"' | community.dns.unquote_txt == "foobar"`. ## Using this collection diff --git a/ansible_collections/community/dns/changelogs/changelog.yaml b/ansible_collections/community/dns/changelogs/changelog.yaml index 626ad4abf..3eafad115 100644 --- a/ansible_collections/community/dns/changelogs/changelog.yaml +++ b/ansible_collections/community/dns/changelogs/changelog.yaml @@ -809,3 +809,23 @@ releases: - 2.8.3.yml - update-psl.yml release_date: '2024-03-24' + 2.9.0: + changes: + bugfixes: + - Update Public Suffix List. + - 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.dns/pull/197). + release_summary: Feature and bugfix release. + fragments: + - 197-unsafe.yml + - 3.9.0.yml + - update-psl.yml + plugins: + filter: + - description: Quotes a string to use as a TXT record entry + name: quote_txt + namespace: null + - description: Unquotes a TXT record entry to a string + name: unquote_txt + namespace: null + release_date: '2024-04-21' diff --git a/ansible_collections/community/dns/docs/docsite/config.yml b/ansible_collections/community/dns/docs/docsite/config.yml new file mode 100644 index 000000000..1d6cf8554 --- /dev/null +++ b/ansible_collections/community/dns/docs/docsite/config.yml @@ -0,0 +1,7 @@ +--- +# 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 + +changelog: + write_changelog: true diff --git a/ansible_collections/community/dns/docs/docsite/rst/filter_guide.rst b/ansible_collections/community/dns/docs/docsite/rst/filter_guide.rst index aee397f8a..5643b2b4e 100644 --- a/ansible_collections/community/dns/docs/docsite/rst/filter_guide.rst +++ b/ansible_collections/community/dns/docs/docsite/rst/filter_guide.rst @@ -23,6 +23,11 @@ These filters allow to work with `public suffixes <https://en.wikipedia.org/wiki The label directly before the public suffix together with the suffix is called the *registrable domain name* or *registered domain name*, since these are usually the names that people can register. Examples for registrable domain names are ``example.com`` and ``example.co.uk``, while ``www.example.com`` is not a registrable domain name. A public suffix itself is also not a registrable domain name, as for example ``github.io``. +The collection also contains filters for working with TXT records: + +- :ansplugin:`community.dns.quote_txt#filter`: quote a string for use as a TXT record; +- :ansplugin:`community.dns.unquote_txt#filter`: extract the value from a (quoted) TXT record. + Working with public suffixes ---------------------------- diff --git a/ansible_collections/community/dns/plugins/filter/quote_txt.yml b/ansible_collections/community/dns/plugins/filter/quote_txt.yml new file mode 100644 index 000000000..c42274718 --- /dev/null +++ b/ansible_collections/community/dns/plugins/filter/quote_txt.yml @@ -0,0 +1,46 @@ +--- +# 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 + +DOCUMENTATION: + name: quote_txt + short_description: Quotes a string to use as a TXT record entry + version_added: 2.9.0 + description: + - Given a string, quotes it so it can be used in a TXT record entry. + options: + _input: + description: + - The string to quote. + type: string + required: true + always_quote: + description: + - Whether to always quote the resulting string in double quotes. + type: bool + default: false + character_encoding: + description: + - Whether to treat numeric escape sequences (V(\\xyz)) as octal or decimal numbers. + - The default value V(decimal) is compatible to L(RFC 1035, https://www.ietf.org/rfc/rfc1035.txt). + type: str + default: decimal + choices: + - decimal + - octal + author: + - Felix Fontein (@felixfontein) + +EXAMPLES: | + - name: Quote a TXT entry + ansible.builtin.set_fact: + public_suffix: "{{ value | community.dns.quote_txt }}" + # Should result in '"this is a test"' + vars: + value: this is a test + +RETURN: + _value: + description: The quoted string that can be used for a TXT entry. + type: string diff --git a/ansible_collections/community/dns/plugins/filter/txt.py b/ansible_collections/community/dns/plugins/filter/txt.py new file mode 100644 index 000000000..4f2d3a16f --- /dev/null +++ b/ansible_collections/community/dns/plugins/filter/txt.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2020-2021, 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.errors import AnsibleFilterError +from ansible.module_utils.common.text.converters import to_text +from ansible.module_utils.six import string_types + +from ansible_collections.community.dns.plugins.module_utils.conversion.txt import ( + decode_txt_value, + encode_txt_value, +) + + +def quote_txt(value, always_quote=False, character_encoding='decimal'): + if not isinstance(value, string_types): + raise AnsibleFilterError('Input for community.dns.quote_txt must be a string') + if not isinstance(always_quote, bool): + raise AnsibleFilterError('always_quote must be a boolean, not {value!r}'.format(value=always_quote)) + if character_encoding not in ('decimal', 'octal'): + raise AnsibleFilterError('character_encoding must be "decimal" or "octal", not {value!r}'.format(value=character_encoding)) + value = to_text(value) + return encode_txt_value(value, always_quote=always_quote, character_encoding=character_encoding) + + +def unquote_txt(value, character_encoding='decimal'): + if not isinstance(value, string_types): + raise AnsibleFilterError('Input for community.dns.unquote_txt must be a string') + if character_encoding not in ('decimal', 'octal'): + raise AnsibleFilterError('character_encoding must be "decimal" or "octal", not {value!r}'.format(value=character_encoding)) + value = to_text(value) + return decode_txt_value(value, character_encoding=character_encoding) + + +class FilterModule(object): + '''Ansible jinja2 filters''' + + def filters(self): + return { + 'quote_txt': quote_txt, + 'unquote_txt': unquote_txt, + } diff --git a/ansible_collections/community/dns/plugins/filter/unquote_txt.yml b/ansible_collections/community/dns/plugins/filter/unquote_txt.yml new file mode 100644 index 000000000..712cf3ad4 --- /dev/null +++ b/ansible_collections/community/dns/plugins/filter/unquote_txt.yml @@ -0,0 +1,42 @@ +--- +# 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 + +DOCUMENTATION: + name: unquote_txt + short_description: Unquotes a TXT record entry to a string + version_added: 2.9.0 + description: + - Given a (quoted) TXT entry content, extracts its value. + options: + _input: + description: + - The string to unquote. + type: string + required: true + character_encoding: + description: + - Whether to treat numeric escape sequences (V(\\xyz)) as octal or decimal numbers. + - The default value V(decimal) is compatible to L(RFC 1035, https://www.ietf.org/rfc/rfc1035.txt). + type: str + default: decimal + choices: + - decimal + - octal + author: + - Felix Fontein (@felixfontein) + +EXAMPLES: | + - name: Unquote a TXT entry + ansible.builtin.set_fact: + public_suffix: "{{ value | community.dns.unquote_txt }}" + # Should result in 'this is a test' + vars: + value: >- + "this is " "a test" + +RETURN: + _value: + description: The extracted string. + type: string 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 30fa11bdc..1d6827f2f 100644 --- a/ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py +++ b/ansible_collections/community/dns/plugins/plugin_utils/inventory/records.py @@ -15,7 +15,6 @@ from ansible.module_utils import six from ansible.module_utils.common._collections_compat import Sequence from ansible.plugins.inventory import BaseInventoryPlugin from ansible.utils.display import Display -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe from ansible.template import Templar from ansible_collections.community.dns.plugins.module_utils.provider import ( @@ -35,6 +34,8 @@ from ansible_collections.community.dns.plugins.module_utils.conversion.converter RecordConverter, ) +from ansible_collections.community.dns.plugins.plugin_utils.unsafe import make_unsafe + display = Display() diff --git a/ansible_collections/community/dns/plugins/plugin_utils/unsafe.py b/ansible_collections/community/dns/plugins/plugin_utils/unsafe.py new file mode 100644 index 000000000..1eb61bea0 --- /dev/null +++ b/ansible_collections/community/dns/plugins/plugin_utils/unsafe.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, 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 re + +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.common._collections_compat import Mapping, Set +from ansible.module_utils.common.collections import is_sequence +from ansible.utils.unsafe_proxy import ( + AnsibleUnsafe, + wrap_var as _make_unsafe, +) + +_RE_TEMPLATE_CHARS = re.compile(u'[{}]') +_RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]') + + +def make_unsafe(value): + if value is None or isinstance(value, AnsibleUnsafe): + return value + + if isinstance(value, Mapping): + return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) + elif isinstance(value, Set): + return set(make_unsafe(elt) for elt in value) + elif is_sequence(value): + return type(value)(make_unsafe(elt) for elt in value) + elif isinstance(value, binary_type): + if _RE_TEMPLATE_CHARS_BYTES.search(value): + value = _make_unsafe(value) + return value + elif isinstance(value, text_type): + if _RE_TEMPLATE_CHARS.search(value): + value = _make_unsafe(value) + return value + + return value diff --git a/ansible_collections/community/dns/plugins/public_suffix_list.dat b/ansible_collections/community/dns/plugins/public_suffix_list.dat index dd8bd923e..125f1e3d7 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-06T15:14:58Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-03-28T15:13:37Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html @@ -6988,10 +6988,6 @@ auto // https://www.iana.org/domains/root/db/autos.html autos -// avianca : Avianca Inc. -// https://www.iana.org/domains/root/db/avianca.html -avianca - // aws : AWS Registry LLC // https://www.iana.org/domains/root/db/aws.html aws @@ -12080,6 +12076,7 @@ autocode.dev // AVM : https://avm.de // Submitted by Andreas Weise <a.weise@avm.de> +myfritz.link myfritz.net // AVStack Pte. Ltd. : https://avstack.io @@ -12357,6 +12354,12 @@ pages.dev r2.dev workers.dev +// cloudscale.ch AG : https://www.cloudscale.ch/ +// Submitted by Gaudenz Steinlin <support@cloudscale.ch> +cust.cloudscale.ch +objects.lpg.cloudscale.ch +objects.rma.cloudscale.ch + // Clovyr : https://clovyr.io // Submitted by Patrick Nielsen <patrick@clovyr.io> wnext.app @@ -12374,22 +12377,33 @@ co.cz // CDN77.com : http://www.cdn77.com // Submitted by Jan Krpes <jan.krpes@cdn77.com> -c.cdn77.org +cdn77-storage.com +rsc.contentproxy9.cz cdn77-ssl.net r.cdn77.net -rsc.cdn77.org ssl.origin.cdn77-secure.org +c.cdn77.org +rsc.cdn77.org // Cloud DNS Ltd : http://www.cloudns.net -// Submitted by Aleksander Hristov <noc@cloudns.net> +// Submitted by Aleksander Hristov <noc@cloudns.net> & Boyan Peychev <boyan@cloudns.net> cloudns.asia +cloudns.be cloudns.biz -cloudns.club cloudns.cc +cloudns.ch +cloudns.cl +cloudns.club +dnsabr.com +cloudns.cx cloudns.eu cloudns.in cloudns.info +dns-cloud.net +dns-dynamic.net +cloudns.nz cloudns.org +cloudns.ph cloudns.pro cloudns.pw cloudns.us @@ -12402,6 +12416,11 @@ cnpy.gdn // Submitted by Moritz Marquardt <git@momar.de> codeberg.page +// CodeSandbox B.V. : https://codesandbox.io +// Submitted by Ives van Hoorne <abuse@codesandbox.io> +csb.app +preview.csb.app + // CoDNS B.V. co.nl co.no @@ -12520,6 +12539,7 @@ dyndns.dappnode.io // Dark, Inc. : https://darklang.com // Submitted by Paul Biggar <ops@darklang.com> builtwithdark.com +darklang.io // DataDetect, LLC. : https://datadetect.com // Submitted by Andrew Banchich <abanchich@sceven.com> @@ -12918,6 +12938,10 @@ ondigitalocean.app // Submitted by Robin H. Johnson <psl-maintainers@digitalocean.com> *.digitaloceanspaces.com +// DigitalPlat : https://www.digitalplat.org/ +// Submitted by Edward Hsing <contact@digitalplat.org> +us.kg + // dnstrace.pro : https://dnstrace.pro/ // Submitted by Chris Partridge <chris@partridge.tech> bci.dnstrace.pro @@ -12959,6 +12983,14 @@ easypanel.host // Submitted by <infracloudteam@namecheap.com> *.ewp.live +// Electromagnetic Field : https://www.emfcamp.org +// Submitted by <noc@emfcamp.org> +at.emf.camp + +// Elefunc, Inc. : https://elefunc.com +// Submitted by Cetin Sert <domains@elefunc.com> +rt.ht + // Elementor : Elementor Ltd. // Submitted by Anton Barkan <antonb@elementor.com> elementor.cloud @@ -13250,7 +13282,8 @@ forgeblocks.com id.forgerock.io // Framer : https://www.framer.com -// Submitted by Koen Rouwhorst <koenrh@framer.com> +// Submitted by Koen Rouwhorst <security@framer.com> +framer.ai framer.app framercanvas.com framer.media @@ -13291,6 +13324,24 @@ freemyip.com // Submitted by Daniel A. Maierhofer <vorstand@funkfeuer.at> wien.funkfeuer.at +// Future Versatile Group. :https://www.fvg-on.net/ +// T.Kabu <webmaster@fvg-on.net> +daemon.asia +dix.asia +mydns.bz +0am.jp +0g0.jp +0j0.jp +0t0.jp +mydns.jp +pgw.jp +wjg.jp +keyword-on.net +live-on.net +server-on.net +mydns.tw +mydns.vc + // Futureweb GmbH : https://www.futureweb.at // Submitted by Andreas Schnederle-Wagner <schnederle@futureweb.at> *.futurecms.at @@ -13334,6 +13385,12 @@ gentlentapis.com lab.ms cdn-edges.net +// Getlocalcert: https://www.getlocalcert.net +// Submitted by Robert Alexander <support@getlocalcert.net> +localcert.net +localhostcert.net +corpnet.work + // Ghost Foundation : https://ghost.org // Submitted by Matt Hanley <security@ghost.org> ghost.io @@ -13480,6 +13537,10 @@ whitesnow.jp zombie.jp heteml.net +// GoDaddy Registry : https://registry.godaddy +// Submitted by Rohan Durrant <tldns@registry.godaddy> +graphic.design + // GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ // Submitted by Tom Whitwell <gov-uk-paas-support@digital.cabinet-office.gov.uk> cloudapps.digital @@ -13599,6 +13660,10 @@ goupile.fr // Submitted by <domeinnaam@minaz.nl> gov.nl +// GrayJay Web Solutions Inc. : https://grayjaysports.ca +// Submitted by Matt Yamkowy <info@grayjaysports.ca> +grayjayleagues.com + // Group 53, LLC : https://www.group53.com // Submitted by Tyler Todd <noc@nova53.net> awsmppl.com @@ -13633,6 +13698,11 @@ hasura-app.io // Submitted by Richard Zowalla <mi-admin@hs-heilbronn.de> pages.it.hs-heilbronn.de +// Helio Networks : https://heliohost.org +// Submitted by Ben Frede <admin@heliohost.org> +helioho.st +heliohost.us + // Hepforge : https://www.hepforge.org // Submitted by David Grellscheid <admin@hepforge.org> hepforge.org @@ -13646,7 +13716,6 @@ herokussl.com // Submitted by Oren Eini <oren@ravendb.net> ravendb.cloud ravendb.community -ravendb.me development.run ravendb.run @@ -13737,7 +13806,7 @@ biz.at info.at // info.cx : http://info.cx -// Submitted by Jacob Slater <whois@igloo.to> +// Submitted by June Slater <whois@igloo.to> info.cx // Interlegis : http://www.interlegis.leg.br @@ -13786,6 +13855,14 @@ iopsys.se // Submitted by Matthew Hardeman <mhardeman@ipifony.com> ipifony.net +// is-a.dev : https://www.is-a.dev +// Submitted by William Harrison <admin@maintainers.is-a.dev> +is-a.dev + +// ir.md : https://nic.ir.md +// Submitted by Ali Soizi <info@nic.ir.md> +ir.md + // IServ GmbH : https://iserv.de // Submitted by Mario Hoberg <info@iserv.de> iservschule.de @@ -13894,6 +13971,11 @@ myjino.ru // Submitted by Daniel Fariña <ingenieria@jotelulu.com> jotelulu.cloud +// JouwWeb B.V. : https://www.jouwweb.nl +// Submitted by Camilo Sperberg <tech@webador.com> +jouwweb.site +webadorsite.com + // Joyent : https://www.joyent.com/ // Submitted by Brian Bennett <brian.bennett@joyent.com> *.triton.zone @@ -13967,6 +14049,10 @@ lpusercontent.com // Submitted by Lelux Admin <publisuffix@lelux.site> lelux.site +// Libre IT Ltd : https://libre.nz +// Submitted by Tomas Maggio <support@libre.nz> +runcontainers.dev + // Lifetime Hosting : https://Lifetime.Hosting/ // Submitted by Mike Fillator <support@lifetime.hosting> co.business @@ -14141,7 +14227,6 @@ co.pl // Managed by Corporate Domains // Microsoft Azure : https://home.azure *.azurecontainer.io -cloudapp.azure.com azure-api.net azureedge.net azurefd.net @@ -14248,13 +14333,18 @@ ngrok.pro torun.pl // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ -// Submitted by Nicholas Ford <nick@nimbushosting.co.uk> +// Submitted by Nicholas Ford <dev@nimbushosting.co.uk> nh-serv.co.uk +nimsite.uk // NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ // Submitted by Jeff Wheelhouse <support@nearlyfreespeech.net> nfshost.com +// NFT.Storage : https://nft.storage/ +// Submitted by Vasco Santos <vasco.santos@protocol.ai> or <support@nft.storage> +ipfs.nftstorage.link + // Noop : https://noop.app // Submitted by Nathaniel Schweinberg <noop@rearc.io> *.developer.app @@ -14434,7 +14524,6 @@ omniwe.site 123minsida.se 123miweb.es 123paginaweb.pt -123sait.ru 123siteweb.fr 123webseite.at 123webseite.de @@ -14452,6 +14541,13 @@ simplesite.pl // Submitted by Eddie Jones <eddie@onefoldmedia.com> nid.io +// Open Domains : https://open-domains.net +// Submitted by William Harrison <admin@open-domains.net> +is-cool.dev +is-not-a.dev +localplayer.dev +is-local.org + // Open Social : https://www.getopensocial.com/ // Submitted by Alexander Varwijk <security@getopensocial.com> opensocial.site @@ -14472,6 +14568,11 @@ operaunite.com // Submitted by Alexandre Linte <alexandre.linte@orange.com> tech.orange +// OsSav Technology Ltd. : https://ossav.com/ +// TLD Nic: http://nic.can.re - TLD Whois Server: whois.can.re +// Submitted by OsSav Technology Ltd. <support@ossav.com> +can.re + // Oursky Limited : https://authgear.com/, https://skygear.io/ // Submitted by Authgear Team <hello@authgear.com>, Skygear Developer <hello@skygear.io> authgear-staging.com @@ -14522,10 +14623,10 @@ pagexl.com // pcarrier.ca Software Inc: https://pcarrier.ca/ // Submitted by Pierre Carrier <pc@rrier.ca> -bar0.net -bar1.net -bar2.net -rdv.to +*.xmit.co +srv.us +gh.srv.us +gl.srv.us // .pl domains (grandfathered) art.pl @@ -14683,9 +14784,12 @@ qcx.io *.sys.qcx.io // QNAP System Inc : https://www.qnap.com -// Submitted by Nick Chang <nickchang@qnap.com> -dev-myqnapcloud.com +// Submitted by Nick Chang <cloudadmin@qnap.com> +myqnapcloud.cn alpha-myqnapcloud.com +dev-myqnapcloud.com +mycloudnas.com +mynascloud.com myqnapcloud.com // Quip : https://quip.com @@ -14915,6 +15019,10 @@ service.gov.scot // Submitted by Shante Adam <shante@skyhat.io> scrysec.com +// Scrypted : https://scrypted.app +// Submitted by Koushik Dutta <public-suffix-list@scrypted.app> +client.scrypted.io + // Securepoint GmbH : https://www.securepoint.de // Submitted by Erik Anders <erik.anders@securepoint.de> firewall-gateway.com @@ -15024,9 +15132,9 @@ small-web.org vp4.me // Snowflake Inc : https://www.snowflake.com/ -// Submitted by Faith Olapade <faith.olapade@snowflake.com> -snowflake.app -privatelink.snowflake.app +// Submitted by Sam Haar <psl@snowflake.com> +*.snowflake.app +*.privatelink.snowflake.app streamlit.app streamlitapp.com @@ -15038,6 +15146,12 @@ try-snowplow.com // Submitted by Drew DeVault <sir@cmpwn.com> srht.site +// StackBlitz : https://stackblitz.com +// Submitted by Dominic Elm <hello@stackblitz.com> +w-corp-staticblitz.com +w-credentialless-staticblitz.com +w-staticblitz.com + // Stackhero : https://www.stackhero.io // Submitted by Adrien Gillon <adrien+public-suffix-list@stackhero.io> stackhero-network.com @@ -15339,6 +15453,10 @@ inc.hk // Submitted by ITComdomains <to@it.com> it.com +// Unison Computing, PBC : https://unison.cloud +// Submitted by Simon Højberg <security@unison.cloud> +unison-services.cloud + // UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ // see also: whois -h whois.udr.org.yt help // Submitted by Atanunu Igbunuroghene <publicsuffixlist@udr.org.yt> @@ -15388,47 +15506,6 @@ v-info.info // Submitted by Nathan van Bakel <info@voorloper.com> voorloper.cloud -// Voxel.sh DNS : https://voxel.sh/dns/ -// Submitted by Mia Rehlinger <dns@voxel.sh> -neko.am -nyaa.am -be.ax -cat.ax -es.ax -eu.ax -gg.ax -mc.ax -us.ax -xy.ax -nl.ci -xx.gl -app.gp -blog.gt -de.gt -to.gt -be.gy -cc.hn -io.kg -jp.kg -tv.kg -uk.kg -us.kg -de.ls -at.md -de.md -jp.md -to.md -indie.porn -vxl.sh -ch.tc -me.tc -we.tc -nyan.to -at.vg -blog.vu -dev.vu -me.vu - // V.UA Domain Administrator : https://domain.v.ua/ // Submitted by Serhii Rostilo <sergey@rostilo.kiev.ua> v.ua @@ -15457,6 +15534,10 @@ reserve-online.com bookonline.app hotelwithflight.com +// WebWaddle Ltd: https://webwaddle.com/ +// Submitted by Merlin Glander <hostmaster@webwaddle.com> +*.wadl.top + // WeDeploy by Liferay, Inc. : https://www.wedeploy.com // Submitted by Henrique Vicente <security@wedeploy.com> wedeploy.io diff --git a/ansible_collections/community/dns/tests/integration/targets/filter_txt/aliases b/ansible_collections/community/dns/tests/integration/targets/filter_txt/aliases new file mode 100644 index 000000000..b7419a24d --- /dev/null +++ b/ansible_collections/community/dns/tests/integration/targets/filter_txt/aliases @@ -0,0 +1,6 @@ +# 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 + +shippable/posix/group1 +skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller 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 new file mode 100644 index 000000000..c0afffcea --- /dev/null +++ b/ansible_collections/community/dns/tests/integration/targets/filter_txt/tasks/main.yml @@ -0,0 +1,49 @@ +--- +# 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: "Test quote_txt filter" + assert: + that: + - >- + '' | community.dns.quote_txt == '""' + - >- + "this is a test" | community.dns.quote_txt == '"this is a test"' + - >- + "test" | community.dns.quote_txt == 'test' + - >- + "test" | community.dns.quote_txt(always_quote=true) == '"test"' + - >- + '"' | community.dns.quote_txt == '\\"' + - >- + ' ' | community.dns.quote_txt == '" "' + - >- + "ä" | community.dns.quote_txt() == '\\195\\164' + - >- + "ä" | community.dns.quote_txt(character_encoding='octal') == '\\303\\244' + - >- + "ä" | community.dns.quote_txt(character_encoding='octal', always_quote=true) == '"\\303\\244"' + - >- + very_long_input | community.dns.quote_txt == very_long_output + vars: + very_long_input: >- + this is a very1, very2, very3, very4, very5, very6, very7, very8, very9, very10, very11, very12, very13, very14, very15, + very16, very17, very18, very19, very20, very21, very22, very23, very24, very25, very26, very27, very28, very29, very30, + very31, very32, very33, very34, very35, very36, very37, very38, very39 long text + very_long_output: >- + "this is a very1, very2, very3, very4, very5, very6, very7, very8, very9, very10, very11, very12, very13, very14, very15, + very16, very17, very18, very19, very20, very21, very22, very23, very24, very25, very26, very27, very28, very29, very30, + very31, very32" ", very33, very34, very35, very36, very37, very38, very39 long text" + +- name: "Test unquote_txt filter" + assert: + that: + - >- + '' | community.dns.unquote_txt == '' + - >- + '""' | community.dns.unquote_txt == '' + - > + '"foo" "bar"' | community.dns.unquote_txt == "foobar" + - > + 'foo "bar baz" bam' | community.dns.unquote_txt == "foobar bazbam" diff --git a/ansible_collections/community/dns/tests/sanity/ignore-2.18.txt b/ansible_collections/community/dns/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..dc9da1161 --- /dev/null +++ b/ansible_collections/community/dns/tests/sanity/ignore-2.18.txt @@ -0,0 +1 @@ +plugins/public_suffix_list.dat no-smart-quotes diff --git a/ansible_collections/community/dns/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/dns/tests/sanity/ignore-2.18.txt.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/dns/tests/sanity/ignore-2.18.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/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 bfaa4886d..44f694708 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 @@ -108,6 +108,68 @@ HETZNER_JSON_DEFAULT_ENTRIES = [ }, ] +HETZNER_JSON_DEFAULT_ENTRIES_UNSAFE = [ + { + 'id': '125', + 'type': 'A', + 'name': '@', + 'value': '1.2.{3.4', + 'ttl': 3600, + 'zone_id': '42', + 'created': '2021-07-09T11:18:37Z', + 'modified': '2021-07-09T11:18:37Z', + }, + { + 'id': '126', + 'type': 'A', + 'name': '*', + 'value': '1.2.{3.5', + 'ttl': 3600, + 'zone_id': '42', + 'created': '2021-07-09T11:18:37Z', + 'modified': '2021-07-09T11:18:37Z', + }, + { + 'id': '127', + 'type': 'AAAA', + 'name': '@', + 'value': '2001:1:2::{3', + 'ttl': 3600, + 'zone_id': '42', + 'created': '2021-07-09T11:18:37Z', + 'modified': '2021-07-09T11:18:37Z', + }, + { + 'id': '128', + 'type': 'AAAA', + 'name': 'foo', + 'value': '2001:1:2::{4', + 'ttl': 3600, + 'zone_id': '42', + 'created': '2021-07-09T11:18:37Z', + 'modified': '2021-07-09T11:18:37Z', + }, + { + 'id': '129', + 'type': 'MX', + 'name': '@', + 'value': '10 example.com', + 'ttl': 3600, + 'zone_id': '42', + 'created': '2021-07-09T11:18:37Z', + 'modified': '2021-07-09T11:18:37Z', + }, + { + 'id': '130', + 'type': 'CNAME', + 'name': 'bar', + 'value': 'example.org.', + 'zone_id': '42', + 'created': '2021-07-09T11:18:37Z', + 'modified': '2021-07-09T11:18:37Z', + }, +] + HETZNER_JSON_BAD_ENTRIES = [ { 'id': '125', @@ -135,6 +197,10 @@ HETZNER_JSON_ZONE_RECORDS_GET_RESULT = { 'records': HETZNER_JSON_DEFAULT_ENTRIES, } +HETZNER_JSON_ZONE_RECORDS_GET_RESULT_UNSAFE = { + 'records': HETZNER_JSON_DEFAULT_ENTRIES_UNSAFE, +} + HETZNER_JSON_ZONE_RECORDS_GET_RESULT_2 = { 'records': HETZNER_JSON_BAD_ENTRIES, } @@ -190,7 +256,7 @@ def test_inventory_file_simple(mocker): .expect_query_values('page', '1') .expect_query_values('per_page', '100') .return_header('Content-Type', 'application/json') - .result_json(HETZNER_JSON_ZONE_RECORDS_GET_RESULT), + .result_json(HETZNER_JSON_ZONE_RECORDS_GET_RESULT_UNSAFE), ]) mocker.patch('ansible_collections.community.dns.plugins.module_utils.http.open_url', open_url) mocker.patch('ansible.inventory.manager.unfrackpath', mock_unfrackpath_noop) @@ -207,8 +273,8 @@ def test_inventory_file_simple(mocker): assert 'bar.example.com' not in im._inventory.hosts assert im._inventory.get_host('example.com') in im._inventory.groups['ungrouped'].hosts assert im._inventory.get_host('*.example.com') in im._inventory.groups['ungrouped'].hosts - assert im._inventory.get_host('example.com').get_vars()['ansible_host'] == '1.2.3.4' - assert im._inventory.get_host('*.example.com').get_vars()['ansible_host'] == '1.2.3.5' + assert im._inventory.get_host('example.com').get_vars()['ansible_host'] == '1.2.{3.4' + assert im._inventory.get_host('*.example.com').get_vars()['ansible_host'] == '1.2.{3.5' assert isinstance(im._inventory.get_host('example.com').get_vars()['ansible_host'], AnsibleUnsafe) assert isinstance(im._inventory.get_host('*.example.com').get_vars()['ansible_host'], AnsibleUnsafe) assert len(im._inventory.groups['ungrouped'].hosts) == 2 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 cefd02a06..11995198c 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 @@ -89,6 +89,64 @@ HOSTTECH_JSON_DEFAULT_ENTRIES = [ }, ] +HOSTTECH_JSON_DEFAULT_ENTRIES_UNSAFE = [ + # (125, 42, 'A', '', '1.2.{3.4', 3600, None, None), + { + 'id': 125, + 'type': 'A', + 'name': '', + 'ipv4': '1.2.{3.4', + 'ttl': 3600, + 'comment': '', + }, + # (126, 42, 'A', '*', '1.2.{3.5', 3600, None, None), + { + 'id': 126, + 'type': 'A', + 'name': '*', + 'ipv4': '1.2.{3.5', + 'ttl': 3600, + 'comment': '', + }, + # (127, 42, 'AAAA', '', '2001:1:2::{3', 3600, None, None), + { + 'id': 127, + 'type': 'AAAA', + 'name': '', + 'ipv6': '2001:1:2::{3', + 'ttl': 3600, + 'comment': '', + }, + # (128, 42, 'AAAA', '*', '2001:1:2::{4', 3600, None, None), + { + 'id': 128, + 'type': 'AAAA', + 'name': 'foo', + 'ipv6': '2001:1:2::{4', + 'ttl': 3600, + 'comment': '', + }, + # (129, 42, 'MX', '', 'example.com', 3600, None, '10'), + { + 'id': 129, + 'type': 'MX', + 'ownername': '', + 'name': 'example.com', + 'pref': 10, + 'ttl': 3600, + 'comment': '', + }, + # (130, 42, 'CNAME', 'bar', 'example.org.', 10800, None, None), + { + 'id': 130, + 'type': 'CNAME', + 'name': 'bar', + 'cname': 'example.org.', + 'ttl': 10800, + 'comment': '', + }, +] + HOSTTECH_JSON_ZONE_LIST_RESULT = { "data": [ @@ -119,6 +177,18 @@ HOSTTECH_JSON_ZONE_RECORDS_GET_RESULT = { "data": HOSTTECH_JSON_DEFAULT_ENTRIES, } +HOSTTECH_JSON_ZONE_GET_RESULT_UNSAFE = { + "data": { + "id": 42, + "name": "example.com", + "email": "test@example.com", + "ttl": 10800, + "nameserver": "ns1.hosttech.ch", + "dnssec": False, + "records": HOSTTECH_JSON_DEFAULT_ENTRIES_UNSAFE, + } +} + original_exists = os.path.exists original_access = os.access @@ -167,7 +237,7 @@ def test_inventory_file_simple(mocker): .expect_header('authorization', 'Bearer foo') .expect_url('https://api.ns1.hosttech.eu/api/user/v1/zones/42') .return_header('Content-Type', 'application/json') - .result_json(HOSTTECH_JSON_ZONE_GET_RESULT), + .result_json(HOSTTECH_JSON_ZONE_GET_RESULT_UNSAFE), ]) mocker.patch('ansible_collections.community.dns.plugins.module_utils.http.open_url', open_url) mocker.patch('ansible.inventory.manager.unfrackpath', mock_unfrackpath_noop) @@ -184,8 +254,8 @@ def test_inventory_file_simple(mocker): assert 'bar.example.com' not in im._inventory.hosts assert im._inventory.get_host('example.com') in im._inventory.groups['ungrouped'].hosts assert im._inventory.get_host('*.example.com') in im._inventory.groups['ungrouped'].hosts - assert im._inventory.get_host('example.com').get_vars()['ansible_host'] == '1.2.3.4' - assert im._inventory.get_host('*.example.com').get_vars()['ansible_host'] == '1.2.3.5' + assert im._inventory.get_host('example.com').get_vars()['ansible_host'] == '1.2.{3.4' + assert im._inventory.get_host('*.example.com').get_vars()['ansible_host'] == '1.2.{3.5' assert isinstance(im._inventory.get_host('example.com').get_vars()['ansible_host'], AnsibleUnsafe) assert isinstance(im._inventory.get_host('*.example.com').get_vars()['ansible_host'], AnsibleUnsafe) assert len(im._inventory.groups['ungrouped'].hosts) == 2 diff --git a/ansible_collections/community/dns/tests/unit/requirements-stable-2.10.txt b/ansible_collections/community/dns/tests/unit/requirements-stable-2.10.txt index 126caabdc..49df5eff9 100644 --- a/ansible_collections/community/dns/tests/unit/requirements-stable-2.10.txt +++ b/ansible_collections/community/dns/tests/unit/requirements-stable-2.10.txt @@ -10,4 +10,4 @@ ipaddress ; python_version < '3.3' dnspython < 2.4.0 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' +lxml < 5.2.0 ; python_version >= '2.7' # lxml 5.2.0 does fail with Python 3.6 due to TOML loading failure diff --git a/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml index b54ccc148..e5d55cf6e 100644 --- a/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml +++ b/ansible_collections/community/docker/.azure-pipelines/azure-pipelines.yml @@ -66,6 +66,17 @@ stages: test: 'devel/sanity/extra' - 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: [] @@ -88,17 +99,6 @@ stages: test: '2.15/sanity/1' - name: Units test: '2.15/units/1' - - stage: Ansible_2_14 - displayName: Sanity & Units 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: Sanity - test: '2.14/sanity/1' - - name: Units - test: '2.14/units/1' ### Docker - stage: Docker_devel @@ -115,8 +115,22 @@ stages: test: ubuntu2004 - name: Ubuntu 22.04 test: ubuntu2204 - - name: Alpine 3 - test: alpine3 + - name: Alpine 3.19 + test: alpine319 + groups: + - 4 + - 5 + - 6 + - stage: Docker_2_17 + displayName: Docker 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: 2.17/linux/{0} + targets: + - name: Alpine 3.19 + test: alpine319 groups: - 4 - 5 @@ -135,6 +149,8 @@ stages: test: centos7 - name: openSUSE 15 test: opensuse15 + - name: Alpine 3 + test: alpine3 groups: - 4 - 5 @@ -155,20 +171,6 @@ stages: - 4 - 5 - 6 - - stage: Docker_2_14 - displayName: Docker 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.14/linux/{0} - targets: - - name: Alpine 3 - test: alpine3 - groups: - - 4 - - 5 - - 6 ### Community Docker - stage: Docker_community_devel @@ -210,7 +212,27 @@ stages: - 3 - 4 - 5 - - 6 + # - 6 -- Docker 26 no longer works with docker-compose v1 + - stage: Remote_2_17 + displayName: Remote 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: 2.17/{0} + targets: + - name: RHEL 9.3 with latest Docker SDK from PyPi + test: rhel/9.3-pypi-latest + # Currently always hangs in group 2 + # - name: RHEL 8.8 + # test: rhel/8.8 + groups: + - 1 + - 2 + - 3 + - 4 + - 5 + # - 6 -- Docker 26 no longer works with docker-compose v1 - stage: Remote_2_16 displayName: Remote 2.16 dependsOn: [] @@ -247,22 +269,6 @@ stages: - 3 - 4 - 5 - - stage: Remote_2_14 - displayName: Remote 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.14/{0} - targets: - - name: RHEL 9.0 - test: rhel/9.0 - groups: - - 1 - - 2 - - 3 - - 4 - - 5 ## Finally @@ -270,17 +276,17 @@ stages: condition: succeededOrFailed() dependsOn: - Ansible_devel + - Ansible_2_17 - Ansible_2_16 - Ansible_2_15 - - Ansible_2_14 - Remote_devel + - Remote_2_17 - Remote_2_16 - Remote_2_15 - - Remote_2_14 - Docker_devel + - Docker_2_17 - Docker_2_16 - Docker_2_15 - - Docker_2_14 - Docker_community_devel jobs: - template: templates/coverage.yml diff --git a/ansible_collections/community/docker/.github/workflows/ansible-test.yml b/ansible_collections/community/docker/.github/workflows/ansible-test.yml index d8910d9f6..d0f253d35 100644 --- a/ansible_collections/community/docker/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/docker/.github/workflows/ansible-test.yml @@ -32,6 +32,7 @@ jobs: - '2.11' - '2.12' - '2.13' + - '2.14' # 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 @@ -72,6 +73,7 @@ jobs: - '2.11' - '2.12' - '2.13' + - '2.14' steps: - name: Perform unit testing against Ansible version ${{ matrix.ansible }} @@ -214,6 +216,19 @@ jobs: docker: alpine3 python: '' target: azp/6/ + # 2.14 + - ansible: '2.14' + docker: alpine3 + python: '' + target: azp/4/ + - ansible: '2.14' + docker: alpine3 + python: '' + target: azp/5/ + - ansible: '2.14' + docker: alpine3 + python: '' + target: azp/6/ steps: - name: Perform integration testing against Ansible version ${{ matrix.ansible }} under Python ${{ matrix.python }} diff --git a/ansible_collections/community/docker/CHANGELOG.md b/ansible_collections/community/docker/CHANGELOG.md index 2e232e769..f3a4b7af6 100644 --- a/ansible_collections/community/docker/CHANGELOG.md +++ b/ansible_collections/community/docker/CHANGELOG.md @@ -2,232 +2,259 @@ **Topics** -- <a href="#v3-8-1">v3\.8\.1</a> +- <a href="#v3-9-0">v3\.9\.0</a> - <a href="#release-summary">Release Summary</a> - - <a href="#security-fixes">Security Fixes</a> + - <a href="#minor-changes">Minor Changes</a> - <a href="#bugfixes">Bugfixes</a> -- <a href="#v3-8-0">v3\.8\.0</a> +- <a href="#v3-8-1">v3\.8\.1</a> - <a href="#release-summary-1">Release Summary</a> - - <a href="#minor-changes">Minor Changes</a> + - <a href="#security-fixes">Security Fixes</a> - <a href="#bugfixes-1">Bugfixes</a> -- <a href="#v3-7-0">v3\.7\.0</a> +- <a href="#v3-8-0">v3\.8\.0</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="#new-modules">New Modules</a> -- <a href="#v3-6-0">v3\.6\.0</a> +- <a href="#v3-7-0">v3\.7\.0</a> - <a href="#release-summary-3">Release Summary</a> - - <a href="#major-changes">Major Changes</a> - <a href="#minor-changes-2">Minor Changes</a> - <a href="#bugfixes-3">Bugfixes</a> - - <a href="#new-modules-1">New Modules</a> -- <a href="#v3-5-0">v3\.5\.0</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="#major-changes">Major Changes</a> - <a href="#minor-changes-3">Minor Changes</a> - - <a href="#deprecated-features">Deprecated Features</a> - <a href="#bugfixes-4">Bugfixes</a> -- <a href="#v3-4-11">v3\.4\.11</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-10">v3\.4\.10</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-9">v3\.4\.9</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-8">v3\.4\.8</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="#release-summary-9">Release Summary</a> - <a href="#known-issues">Known Issues</a> - <a href="#v3-4-7">v3\.4\.7</a> - - <a href="#release-summary-9">Release Summary</a> - - <a href="#bugfixes-8">Bugfixes</a> -- <a href="#v3-4-6">v3\.4\.6</a> - <a href="#release-summary-10">Release Summary</a> - <a href="#bugfixes-9">Bugfixes</a> - - <a href="#known-issues-1">Known Issues</a> -- <a href="#v3-4-5">v3\.4\.5</a> +- <a href="#v3-4-6">v3\.4\.6</a> - <a href="#release-summary-11">Release Summary</a> - <a href="#bugfixes-10">Bugfixes</a> -- <a href="#v3-4-4">v3\.4\.4</a> + - <a href="#known-issues-1">Known Issues</a> +- <a href="#v3-4-5">v3\.4\.5</a> - <a href="#release-summary-12">Release Summary</a> - - <a href="#minor-changes-4">Minor Changes</a> + - <a href="#bugfixes-11">Bugfixes</a> +- <a href="#v3-4-4">v3\.4\.4</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="#release-summary-13">Release Summary</a> -- <a href="#v3-4-2">v3\.4\.2</a> - <a href="#release-summary-14">Release Summary</a> - - <a href="#bugfixes-11">Bugfixes</a> -- <a href="#v3-4-1">v3\.4\.1</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-0">v3\.4\.0</a> +- <a href="#v3-4-1">v3\.4\.1</a> - <a href="#release-summary-16">Release Summary</a> - - <a href="#minor-changes-5">Minor Changes</a> - <a href="#bugfixes-13">Bugfixes</a> - - <a href="#new-modules-2">New Modules</a> -- <a href="#v3-3-2">v3\.3\.2</a> +- <a href="#v3-4-0">v3\.4\.0</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="#v3-3-1">v3\.3\.1</a> + - <a href="#new-modules-2">New Modules</a> +- <a href="#v3-3-2">v3\.3\.2</a> - <a href="#release-summary-18">Release Summary</a> - <a href="#bugfixes-15">Bugfixes</a> -- <a href="#v3-3-0">v3\.3\.0</a> +- <a href="#v3-3-1">v3\.3\.1</a> - <a href="#release-summary-19">Release Summary</a> - - <a href="#minor-changes-6">Minor Changes</a> - <a href="#bugfixes-16">Bugfixes</a> -- <a href="#v3-2-2">v3\.2\.2</a> +- <a href="#v3-3-0">v3\.3\.0</a> - <a href="#release-summary-20">Release Summary</a> + - <a href="#minor-changes-7">Minor Changes</a> - <a href="#bugfixes-17">Bugfixes</a> -- <a href="#v3-2-1">v3\.2\.1</a> +- <a href="#v3-2-2">v3\.2\.2</a> - <a href="#release-summary-21">Release Summary</a> -- <a href="#v3-2-0">v3\.2\.0</a> + - <a href="#bugfixes-18">Bugfixes</a> +- <a href="#v3-2-1">v3\.2\.1</a> - <a href="#release-summary-22">Release Summary</a> - - <a href="#minor-changes-7">Minor Changes</a> - - <a href="#deprecated-features-1">Deprecated Features</a> -- <a href="#v3-1-0">v3\.1\.0</a> +- <a href="#v3-2-0">v3\.2\.0</a> - <a href="#release-summary-23">Release Summary</a> - <a href="#minor-changes-8">Minor Changes</a> -- <a href="#v3-0-2">v3\.0\.2</a> + - <a href="#deprecated-features-1">Deprecated Features</a> +- <a href="#v3-1-0">v3\.1\.0</a> - <a href="#release-summary-24">Release Summary</a> - - <a href="#bugfixes-18">Bugfixes</a> -- <a href="#v3-0-1">v3\.0\.1</a> + - <a href="#minor-changes-9">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="#v3-0-0">v3\.0\.0</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="#v3-0-0">v3\.0\.0</a> + - <a href="#release-summary-27">Release Summary</a> - <a href="#major-changes-1">Major Changes</a> - - <a href="#minor-changes-9">Minor Changes</a> + - <a href="#minor-changes-10">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-20">Bugfixes</a> -- <a href="#v2-7-0">v2\.7\.0</a> - - <a href="#release-summary-27">Release Summary</a> - - <a href="#minor-changes-10">Minor Changes</a> - - <a href="#deprecated-features-2">Deprecated Features</a> - <a href="#bugfixes-21">Bugfixes</a> -- <a href="#v2-6-0">v2\.6\.0</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-3">Deprecated Features</a> + - <a href="#deprecated-features-2">Deprecated Features</a> - <a href="#bugfixes-22">Bugfixes</a> -- <a href="#v2-5-1">v2\.5\.1</a> +- <a href="#v2-6-0">v2\.6\.0</a> - <a href="#release-summary-29">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-0">v2\.5\.0</a> +- <a href="#v2-5-1">v2\.5\.1</a> - <a href="#release-summary-30">Release Summary</a> - - <a href="#minor-changes-12">Minor Changes</a> -- <a href="#v2-4-0">v2\.4\.0</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="#bugfixes-24">Bugfixes</a> -- <a href="#v2-3-0">v2\.3\.0</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-2-1">v2\.2\.1</a> +- <a href="#v2-3-0">v2\.3\.0</a> - <a href="#release-summary-33">Release Summary</a> + - <a href="#minor-changes-15">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-34">Release Summary</a> - - <a href="#minor-changes-15">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-35">Release Summary</a> + - <a href="#minor-changes-16">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-36">Release Summary</a> - - <a href="#minor-changes-16">Minor Changes</a> - <a href="#bugfixes-29">Bugfixes</a> -- <a href="#v2-0-2">v2\.0\.2</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-30">Bugfixes</a> -- <a href="#v2-0-1">v2\.0\.1</a> +- <a href="#v2-0-2">v2\.0\.2</a> - <a href="#release-summary-38">Release Summary</a> -- <a href="#v2-0-0">v2\.0\.0</a> + - <a href="#bugfixes-31">Bugfixes</a> +- <a href="#v2-0-1">v2\.0\.1</a> - <a href="#release-summary-39">Release Summary</a> +- <a href="#v2-0-0">v2\.0\.0</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="#release-summary-40">Release Summary</a> - - <a href="#minor-changes-17">Minor Changes</a> -- <a href="#v1-9-1">v1\.9\.1</a> - <a href="#release-summary-41">Release Summary</a> - - <a href="#bugfixes-31">Bugfixes</a> -- <a href="#v1-9-0">v1\.9\.0</a> - - <a href="#release-summary-42">Release Summary</a> - <a href="#minor-changes-18">Minor Changes</a> - - <a href="#deprecated-features-5">Deprecated Features</a> +- <a href="#v1-9-1">v1\.9\.1</a> + - <a href="#release-summary-42">Release Summary</a> - <a href="#bugfixes-32">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="#v1-9-0">v1\.9\.0</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="#v1-7-0">v1\.7\.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-44">Release Summary</a> - <a href="#minor-changes-20">Minor Changes</a> -- <a href="#v1-6-1">v1\.6\.1</a> - - <a href="#release-summary-45">Release Summary</a> - <a href="#bugfixes-34">Bugfixes</a> -- <a href="#v1-6-0">v1\.6\.0</a> - - <a href="#release-summary-46">Release Summary</a> +- <a href="#v1-7-0">v1\.7\.0</a> + - <a href="#release-summary-45">Release Summary</a> - <a href="#minor-changes-21">Minor Changes</a> - - <a href="#deprecated-features-6">Deprecated Features</a> +- <a href="#v1-6-1">v1\.6\.1</a> + - <a href="#release-summary-46">Release Summary</a> - <a href="#bugfixes-35">Bugfixes</a> -- <a href="#v1-5-0">v1\.5\.0</a> +- <a href="#v1-6-0">v1\.6\.0</a> - <a href="#release-summary-47">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="#new-modules-3">New Modules</a> -- <a href="#v1-4-0">v1\.4\.0</a> +- <a href="#v1-5-0">v1\.5\.0</a> - <a href="#release-summary-48">Release Summary</a> - <a href="#minor-changes-23">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-37">Bugfixes</a> -- <a href="#v1-3-0">v1\.3\.0</a> + - <a href="#new-modules-3">New Modules</a> +- <a href="#v1-4-0">v1\.4\.0</a> - <a href="#release-summary-49">Release Summary</a> - <a href="#minor-changes-24">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="#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="#new-modules-4">New Modules</a> - <a href="#v1-2-2">v1\.2\.2</a> - - <a href="#release-summary-50">Release Summary</a> + - <a href="#release-summary-51">Release Summary</a> - <a href="#security-fixes-3">Security Fixes</a> - <a href="#v1-2-1">v1\.2\.1</a> - - <a href="#release-summary-51">Release Summary</a> - - <a href="#bugfixes-39">Bugfixes</a> -- <a href="#v1-2-0">v1\.2\.0</a> - <a href="#release-summary-52">Release Summary</a> - - <a href="#minor-changes-25">Minor Changes</a> - <a href="#bugfixes-40">Bugfixes</a> -- <a href="#v1-1-0">v1\.1\.0</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="#deprecated-features-7">Deprecated Features</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="#minor-changes-27">Minor Changes</a> + - <a href="#deprecated-features-7">Deprecated Features</a> + - <a href="#bugfixes-42">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-54">Release Summary</a> - - <a href="#bugfixes-42">Bugfixes</a> -- <a href="#v1-0-0">v1\.0\.0</a> - <a href="#release-summary-55">Release Summary</a> - - <a href="#minor-changes-27">Minor Changes</a> -- <a href="#v0-1-0">v0\.1\.0</a> + - <a href="#bugfixes-43">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="#minor-changes-29">Minor Changes</a> - <a href="#removed-features-previously-deprecated-2">Removed Features \(previously deprecated\)</a> - - <a href="#bugfixes-43">Bugfixes</a> + - <a href="#bugfixes-44">Bugfixes</a> + +<a id="v3-9-0"></a> +## v3\.9\.0 + +<a id="release-summary"></a> +### Release Summary + +Bugfix and feature release\. + +<a id="minor-changes"></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)\)\. +* docker\_compose\_v2\* \- the new option <code>check\_files\_existing</code> allows to disable the check for one of the files <code>compose\.yaml</code>\, <code>compose\.yml</code>\, <code>docker\-compose\.yaml</code>\, and <code>docker\-compose\.yml</code> in <code>project\_src</code> if <code>files</code> is not specified\. This is necessary if a non\-standard compose filename is specified through other means\, like the <code>COMPOSE\_FILE</code> environment variable \([https\://github\.com/ansible\-collections/community\.docker/issues/838](https\://github\.com/ansible\-collections/community\.docker/issues/838)\, [https\://github\.com/ansible\-collections/community\.docker/pull/839](https\://github\.com/ansible\-collections/community\.docker/pull/839)\)\. +* 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> +### 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)\)\. +* docker\_compose\_v2\* modules \- abort with a nice error message instead of crash when the Docker Compose CLI plugin version is <code>dev</code> \([https\://github\.com/ansible\-collections/community\.docker/issues/825](https\://github\.com/ansible\-collections/community\.docker/issues/825)\, [https\://github\.com/ansible\-collections/community\.docker/pull/826](https\://github\.com/ansible\-collections/community\.docker/pull/826)\)\. +* 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\.docker/pull/835](https\://github\.com/ansible\-collections/community\.docker/pull/835)\)\. <a id="v3-8-1"></a> ## v3\.8\.1 -<a id="release-summary"></a> +<a id="release-summary-1"></a> ### Release Summary Bugfix release @@ -237,7 +264,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"></a> +<a id="bugfixes-1"></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)\)\. @@ -248,19 +275,19 @@ Bugfix release <a id="v3-8-0"></a> ## v3\.8\.0 -<a id="release-summary-1"></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 * 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-1"></a> +<a id="bugfixes-2"></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)\)\. @@ -270,18 +297,18 @@ Bugfix and feature release\. <a id="v3-7-0"></a> ## v3\.7\.0 -<a id="release-summary-2"></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 * 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-2"></a> +<a id="bugfixes-3"></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)\)\. @@ -295,7 +322,7 @@ Bugfix and feature release\. <a id="v3-6-0"></a> ## v3\.6\.0 -<a id="release-summary-3"></a> +<a id="release-summary-4"></a> ### Release Summary Bugfix and feature release\. @@ -315,7 +342,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-2"></a> +<a id="minor-changes-3"></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)\)\. @@ -325,7 +352,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-3"></a> +<a id="bugfixes-4"></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)\)\. @@ -345,12 +372,12 @@ so the main difference is that instead of some Python requirements\, they depend <a id="v3-5-0"></a> ## v3\.5\.0 -<a id="release-summary-4"></a> +<a id="release-summary-5"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-3"></a> +<a id="minor-changes-4"></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)\)\. @@ -361,7 +388,7 @@ Bugfix and feature release\. * 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-4"></a> +<a id="bugfixes-5"></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)\)\. @@ -371,12 +398,12 @@ Bugfix and feature release\. <a id="v3-4-11"></a> ## v3\.4\.11 -<a id="release-summary-5"></a> +<a id="release-summary-6"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-5"></a> +<a id="bugfixes-6"></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)\)\. @@ -384,12 +411,12 @@ Bugfix release\. <a id="v3-4-10"></a> ## v3\.4\.10 -<a id="release-summary-6"></a> +<a id="release-summary-7"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-6"></a> +<a id="bugfixes-7"></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)\)\. @@ -397,12 +424,12 @@ Bugfix release\. <a id="v3-4-9"></a> ## v3\.4\.9 -<a id="release-summary-7"></a> +<a id="release-summary-8"></a> ### Release Summary Maintenance release with updated documentation and vendored Docker SDK for Python code\. -<a id="bugfixes-7"></a> +<a id="bugfixes-8"></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)\)\. @@ -410,7 +437,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-8"></a> +<a id="release-summary-9"></a> ### Release Summary Maintenance release with updated documentation\. @@ -431,12 +458,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-9"></a> +<a id="release-summary-10"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-8"></a> +<a id="bugfixes-9"></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)\)\. @@ -444,12 +471,12 @@ Bugfix release\. <a id="v3-4-6"></a> ## v3\.4\.6 -<a id="release-summary-10"></a> +<a id="release-summary-11"></a> ### Release Summary Bugfix release with documentation warnings about using certain functionality when connecting to the Docker daemon with TCP TLS\. -<a id="bugfixes-9"></a> +<a id="bugfixes-10"></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)\)\. @@ -466,12 +493,12 @@ Bugfix release with documentation warnings about using certain functionality whe <a id="v3-4-5"></a> ## v3\.4\.5 -<a id="release-summary-11"></a> +<a id="release-summary-12"></a> ### Release Summary Maintenance release which adds compatibility with requests 2\.29\.0 and 2\.30\.0 and urllib3 2\.0\. -<a id="bugfixes-10"></a> +<a id="bugfixes-11"></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)\)\. @@ -479,12 +506,12 @@ 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-12"></a> +<a id="release-summary-13"></a> ### Release Summary Maintenance release with updated EE requirements and updated documentation\. -<a id="minor-changes-4"></a> +<a id="minor-changes-5"></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)\)\. @@ -497,7 +524,7 @@ Maintenance release with updated EE requirements and updated documentation\. <a id="v3-4-3"></a> ## v3\.4\.3 -<a id="release-summary-13"></a> +<a id="release-summary-14"></a> ### Release Summary Maintenance release with improved documentation\. @@ -505,12 +532,12 @@ Maintenance release with improved documentation\. <a id="v3-4-2"></a> ## v3\.4\.2 -<a id="release-summary-14"></a> +<a id="release-summary-15"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-11"></a> +<a id="bugfixes-12"></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)\)\. @@ -518,12 +545,12 @@ Bugfix release\. <a id="v3-4-1"></a> ## v3\.4\.1 -<a id="release-summary-15"></a> +<a id="release-summary-16"></a> ### Release Summary Regular bugfix release\. -<a id="bugfixes-12"></a> +<a id="bugfixes-13"></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)\)\. @@ -533,18 +560,18 @@ Regular bugfix release\. <a id="v3-4-0"></a> ## v3\.4\.0 -<a id="release-summary-16"></a> +<a id="release-summary-17"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-5"></a> +<a id="minor-changes-6"></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-13"></a> +<a id="bugfixes-14"></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)\)\. @@ -560,12 +587,12 @@ Regular bugfix and feature release\. <a id="v3-3-2"></a> ## v3\.3\.2 -<a id="release-summary-17"></a> +<a id="release-summary-18"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-14"></a> +<a id="bugfixes-15"></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)\)\. @@ -573,12 +600,12 @@ Bugfix release\. <a id="v3-3-1"></a> ## v3\.3\.1 -<a id="release-summary-18"></a> +<a id="release-summary-19"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-15"></a> +<a id="bugfixes-16"></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)\)\. @@ -586,18 +613,18 @@ Bugfix release\. <a id="v3-3-0"></a> ## v3\.3\.0 -<a id="release-summary-19"></a> +<a id="release-summary-20"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-6"></a> +<a id="minor-changes-7"></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-16"></a> +<a id="bugfixes-17"></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)\)\. @@ -606,12 +633,12 @@ Feature and bugfix release\. <a id="v3-2-2"></a> ## v3\.2\.2 -<a id="release-summary-20"></a> +<a id="release-summary-21"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-17"></a> +<a id="bugfixes-18"></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)\)\. @@ -619,7 +646,7 @@ Bugfix release\. <a id="v3-2-1"></a> ## v3\.2\.1 -<a id="release-summary-21"></a> +<a id="release-summary-22"></a> ### Release Summary Maintenance release with improved documentation\. @@ -627,12 +654,12 @@ Maintenance release with improved documentation\. <a id="v3-2-0"></a> ## v3\.2\.0 -<a id="release-summary-22"></a> +<a id="release-summary-23"></a> ### Release Summary Feature and deprecation release\. -<a id="minor-changes-7"></a> +<a id="minor-changes-8"></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)\)\. @@ -646,12 +673,12 @@ Feature and deprecation release\. <a id="v3-1-0"></a> ## v3\.1\.0 -<a id="release-summary-23"></a> +<a id="release-summary-24"></a> ### Release Summary Feature release\. -<a id="minor-changes-8"></a> +<a id="minor-changes-9"></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)\)\. @@ -660,12 +687,12 @@ Feature release\. <a id="v3-0-2"></a> ## v3\.0\.2 -<a id="release-summary-24"></a> +<a id="release-summary-25"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-18"></a> +<a id="bugfixes-19"></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)\)\. @@ -673,12 +700,12 @@ Bugfix release\. <a id="v3-0-1"></a> ## v3\.0\.1 -<a id="release-summary-25"></a> +<a id="release-summary-26"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-19"></a> +<a id="bugfixes-20"></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)\)\. @@ -686,7 +713,7 @@ Bugfix release\. <a id="v3-0-0"></a> ## v3\.0\.0 -<a id="release-summary-26"></a> +<a id="release-summary-27"></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\. @@ -713,7 +740,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-9"></a> +<a id="minor-changes-10"></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)\)\. @@ -753,7 +780,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-20"></a> +<a id="bugfixes-21"></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)\)\. @@ -767,12 +794,12 @@ 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-27"></a> +<a id="release-summary-28"></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-10"></a> +<a id="minor-changes-11"></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)\)\. @@ -783,7 +810,7 @@ Bugfix and deprecation release\. The next 2\.x\.y releases will only be bugfix r * 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-21"></a> +<a id="bugfixes-22"></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)\)\. @@ -791,12 +818,12 @@ 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-28"></a> +<a id="release-summary-29"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-11"></a> +<a id="minor-changes-12"></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)\)\. @@ -809,7 +836,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-22"></a> +<a id="bugfixes-23"></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)\)\. @@ -818,12 +845,12 @@ Bugfix and feature release\. <a id="v2-5-1"></a> ## v2\.5\.1 -<a id="release-summary-29"></a> +<a id="release-summary-30"></a> ### Release Summary Maintenance release\. -<a id="bugfixes-23"></a> +<a id="bugfixes-24"></a> ### Bugfixes * Include <code>PSF\-license\.txt</code> file for <code>plugins/module\_utils/\_version\.py</code>\. @@ -831,12 +858,12 @@ Maintenance release\. <a id="v2-5-0"></a> ## v2\.5\.0 -<a id="release-summary-30"></a> +<a id="release-summary-31"></a> ### Release Summary Regular feature release\. -<a id="minor-changes-12"></a> +<a id="minor-changes-13"></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)\)\. @@ -845,19 +872,19 @@ Regular feature release\. <a id="v2-4-0"></a> ## v2\.4\.0 -<a id="release-summary-31"></a> +<a id="release-summary-32"></a> ### Release Summary Regular feature and bugfix release\. -<a id="minor-changes-13"></a> +<a id="minor-changes-14"></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-24"></a> +<a id="bugfixes-25"></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)\)\. @@ -865,12 +892,12 @@ Regular feature and bugfix release\. <a id="v2-3-0"></a> ## v2\.3\.0 -<a id="release-summary-32"></a> +<a id="release-summary-33"></a> ### Release Summary Regular feature and bugfix release\. -<a id="minor-changes-14"></a> +<a id="minor-changes-15"></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)\)\. @@ -879,7 +906,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-25"></a> +<a id="bugfixes-26"></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)\)\. @@ -888,12 +915,12 @@ Regular feature and bugfix release\. <a id="v2-2-1"></a> ## v2\.2\.1 -<a id="release-summary-33"></a> +<a id="release-summary-34"></a> ### Release Summary Regular bugfix release\. -<a id="bugfixes-26"></a> +<a id="bugfixes-27"></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)\)\. @@ -901,19 +928,19 @@ Regular bugfix release\. <a id="v2-2-0"></a> ## v2\.2\.0 -<a id="release-summary-34"></a> +<a id="release-summary-35"></a> ### Release Summary Regular feature and bugfix release\. -<a id="minor-changes-15"></a> +<a id="minor-changes-16"></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-27"></a> +<a id="bugfixes-28"></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)\)\. @@ -921,12 +948,12 @@ Regular feature and bugfix release\. <a id="v2-1-1"></a> ## v2\.1\.1 -<a id="release-summary-35"></a> +<a id="release-summary-36"></a> ### Release Summary Emergency release to amend breaking change in previous release\. -<a id="bugfixes-28"></a> +<a id="bugfixes-29"></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)\)\. @@ -934,18 +961,18 @@ Emergency release to amend breaking change in previous release\. <a id="v2-1-0"></a> ## v2\.1\.0 -<a id="release-summary-36"></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 * 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-29"></a> +<a id="bugfixes-30"></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)\)\. @@ -955,12 +982,12 @@ Feature and bugfix release\. <a id="v2-0-2"></a> ## v2\.0\.2 -<a id="release-summary-37"></a> +<a id="release-summary-38"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-30"></a> +<a id="bugfixes-31"></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)\)\. @@ -971,7 +998,7 @@ Bugfix release\. <a id="v2-0-1"></a> ## v2\.0\.1 -<a id="release-summary-38"></a> +<a id="release-summary-39"></a> ### Release Summary Maintenance release with some documentation fixes\. @@ -979,7 +1006,7 @@ Maintenance release with some documentation fixes\. <a id="v2-0-0"></a> ## v2\.0\.0 -<a id="release-summary-39"></a> +<a id="release-summary-40"></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\. @@ -987,7 +1014,7 @@ New major release with some deprecations removed and a breaking change in the <c <a id="breaking-changes--porting-guide-1"></a> ### Breaking Changes / Porting Guide -* 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 <em class="title-reference">timeout\`</em> is not specified \([https\://github\.com/ansible\-collections/community\.docker/pull/163](https\://github\.com/ansible\-collections/community\.docker/pull/163)\)\. +* 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> ### Deprecated Features @@ -1005,12 +1032,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-40"></a> +<a id="release-summary-41"></a> ### Release Summary Regular feature and bugfix release\. -<a id="minor-changes-17"></a> +<a id="minor-changes-18"></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)\)\. @@ -1020,12 +1047,12 @@ Regular feature and bugfix release\. <a id="v1-9-1"></a> ## v1\.9\.1 -<a id="release-summary-41"></a> +<a id="release-summary-42"></a> ### Release Summary Regular bugfix release\. -<a id="bugfixes-31"></a> +<a id="bugfixes-32"></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)\)\. @@ -1033,12 +1060,12 @@ Regular bugfix release\. <a id="v1-9-0"></a> ## v1\.9\.0 -<a id="release-summary-42"></a> +<a id="release-summary-43"></a> ### Release Summary New bugfixes and features release\. -<a id="minor-changes-18"></a> +<a id="minor-changes-19"></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)\)\. @@ -1052,7 +1079,7 @@ New bugfixes and features release\. * 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-32"></a> +<a id="bugfixes-33"></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)\)\. @@ -1071,12 +1098,12 @@ New bugfixes and features release\. <a id="v1-8-0"></a> ## v1\.8\.0 -<a id="release-summary-43"></a> +<a id="release-summary-44"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-19"></a> +<a id="minor-changes-20"></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)\)\. @@ -1085,7 +1112,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-33"></a> +<a id="bugfixes-34"></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)\)\. @@ -1093,12 +1120,12 @@ Regular bugfix and feature release\. <a id="v1-7-0"></a> ## v1\.7\.0 -<a id="release-summary-44"></a> +<a id="release-summary-45"></a> ### Release Summary Small feature and bugfix release\. -<a id="minor-changes-20"></a> +<a id="minor-changes-21"></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)\)\. @@ -1106,12 +1133,12 @@ Small feature and bugfix release\. <a id="v1-6-1"></a> ## v1\.6\.1 -<a id="release-summary-45"></a> +<a id="release-summary-46"></a> ### Release Summary Bugfix release to reduce deprecation warning spam\. -<a id="bugfixes-34"></a> +<a id="bugfixes-35"></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)\)\. @@ -1119,12 +1146,12 @@ Bugfix release to reduce deprecation warning spam\. <a id="v1-6-0"></a> ## v1\.6\.0 -<a id="release-summary-46"></a> +<a id="release-summary-47"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-21"></a> +<a id="minor-changes-22"></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)\)\. @@ -1135,7 +1162,7 @@ Regular bugfix and feature release\. * 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-35"></a> +<a id="bugfixes-36"></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)\)\. @@ -1145,17 +1172,17 @@ Regular bugfix and feature release\. <a id="v1-5-0"></a> ## v1\.5\.0 -<a id="release-summary-47"></a> +<a id="release-summary-48"></a> ### Release Summary Regular feature release\. -<a id="minor-changes-22"></a> +<a id="minor-changes-23"></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-36"></a> +<a id="bugfixes-37"></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)\)\. @@ -1168,12 +1195,12 @@ Regular feature release\. <a id="v1-4-0"></a> ## v1\.4\.0 -<a id="release-summary-48"></a> +<a id="release-summary-49"></a> ### Release Summary Security release to address another potential secret leak\. Also includes regular bugfixes and features\. -<a id="minor-changes-23"></a> +<a id="minor-changes-24"></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)\)\. @@ -1188,7 +1215,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-37"></a> +<a id="bugfixes-38"></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)\)\. @@ -1197,12 +1224,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-49"></a> +<a id="release-summary-50"></a> ### Release Summary Regular feature and bugfix release\. -<a id="minor-changes-24"></a> +<a id="minor-changes-25"></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)\)\. @@ -1210,7 +1237,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-38"></a> +<a id="bugfixes-39"></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)\)\. @@ -1228,7 +1255,7 @@ Regular feature and bugfix release\. <a id="v1-2-2"></a> ## v1\.2\.2 -<a id="release-summary-50"></a> +<a id="release-summary-51"></a> ### Release Summary Security bugfix release to address CVE\-2021\-20191\. @@ -1241,12 +1268,12 @@ Security bugfix release to address CVE\-2021\-20191\. <a id="v1-2-1"></a> ## v1\.2\.1 -<a id="release-summary-51"></a> +<a id="release-summary-52"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-39"></a> +<a id="bugfixes-40"></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)\)\. @@ -1254,17 +1281,17 @@ Bugfix release\. <a id="v1-2-0"></a> ## v1\.2\.0 -<a id="release-summary-52"></a> +<a id="release-summary-53"></a> ### Release Summary Feature release with one new feature and two bugfixes\. -<a id="minor-changes-25"></a> +<a id="minor-changes-26"></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-40"></a> +<a id="bugfixes-41"></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)\)\. @@ -1273,12 +1300,12 @@ Feature release with one new feature and two bugfixes\. <a id="v1-1-0"></a> ## v1\.1\.0 -<a id="release-summary-53"></a> +<a id="release-summary-54"></a> ### Release Summary Feature release with three new plugins and modules\. -<a id="minor-changes-26"></a> +<a id="minor-changes-27"></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)\)\. @@ -1290,7 +1317,7 @@ Feature release with three new plugins and modules\. * 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-41"></a> +<a id="bugfixes-42"></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)\)\. @@ -1318,12 +1345,12 @@ Feature release with three new plugins and modules\. <a id="v1-0-1"></a> ## v1\.0\.1 -<a id="release-summary-54"></a> +<a id="release-summary-55"></a> ### Release Summary Maintenance release with a bugfix for <code>docker\_container</code>\. -<a id="bugfixes-42"></a> +<a id="bugfixes-43"></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)\)\. @@ -1331,12 +1358,12 @@ Maintenance release with a bugfix for <code>docker\_container</code>\. <a id="v1-0-0"></a> ## v1\.0\.0 -<a id="release-summary-55"></a> +<a id="release-summary-56"></a> ### Release Summary This is the first production \(non\-prerelease\) release of <code>community\.docker</code>\. -<a id="minor-changes-27"></a> +<a id="minor-changes-28"></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)\)\. @@ -1346,14 +1373,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-56"></a> +<a id="release-summary-57"></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-28"></a> +<a id="minor-changes-29"></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)\)\. @@ -1384,7 +1411,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-43"></a> +<a id="bugfixes-44"></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 74e43714e..1e2ef58a6 100644 --- a/ansible_collections/community/docker/CHANGELOG.rst +++ b/ansible_collections/community/docker/CHANGELOG.rst @@ -4,6 +4,29 @@ Docker Community Collection Release Notes .. contents:: Topics +v3.9.0 +====== + +Release Summary +--------------- + +Bugfix and feature release. + +Minor Changes +------------- + +- The EE requirements now include PyYAML, since the ``docker_compose_v2*`` modules depend on it when the ``definition`` 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). +- docker_compose_v2* - the new option ``check_files_existing`` allows to disable the check for one of the files ``compose.yaml``, ``compose.yml``, ``docker-compose.yaml``, and ``docker-compose.yml`` in ``project_src`` if ``files`` is not specified. This is necessary if a non-standard compose filename is specified through other means, like the ``COMPOSE_FILE`` environment variable (https://github.com/ansible-collections/community.docker/issues/838, https://github.com/ansible-collections/community.docker/pull/839). +- docker_compose_v2* modules - allow to provide an inline definition of the compose content instead of having to provide a ``project_src`` directory with the compose file written into it (https://github.com/ansible-collections/community.docker/issues/829, 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). + +Bugfixes +-------- + +- docker_compose_v2* - allow ``project_src`` 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/pull/828). +- docker_compose_v2* modules - abort with a nice error message instead of crash when the Docker Compose CLI plugin version is ``dev`` (https://github.com/ansible-collections/community.docker/issues/825, https://github.com/ansible-collections/community.docker/pull/826). +- 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.docker/pull/835). + v3.8.1 ====== @@ -768,7 +791,7 @@ New major release with some deprecations removed and a breaking change in the `` Breaking Changes / Porting Guide -------------------------------- -- docker_compose - fixed ``timeout`` defaulting behavior so that ``stop_grace_period``, if defined in the compose file, will be used if `timeout`` is not specified (https://github.com/ansible-collections/community.docker/pull/163). +- docker_compose - fixed ``timeout`` defaulting behavior so that ``stop_grace_period``, if defined in the compose file, will be used if ``timeout`` is not specified (https://github.com/ansible-collections/community.docker/pull/163). Deprecated Features ------------------- diff --git a/ansible_collections/community/docker/FILES.json b/ansible_collections/community/docker/FILES.json index 9797df497..da52548f1 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": "4083b64eda9b5fdcbf472007a0a8edc921d46d7d2132b870ccddfc04b72aede1", + "chksum_sha256": "84dc585b738c2bfea68ee8e9cd6d4417f36627bd96a67f92b6f8073449b2d7af", "format": 1 }, { @@ -130,7 +130,7 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c1b9c8b20850a848ebb8c91cdb9382cc3e521658fb2bbe1bb62f6357565e044d", + "chksum_sha256": "4082845558609060198c2628d77b14eb18b28f48faf0fc08116fee817b4e056c", "format": 1 }, { @@ -242,7 +242,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "78b978f9536ee113fed773101c478a20057167e348c8d5b6cdb77f44e62d9b6f", + "chksum_sha256": "d3068c91410e1c891056bfdefa3812fb91ed3ccd41fe97b6aaa428debcd5b663", "format": 1 }, { @@ -291,7 +291,7 @@ "name": "docs/docsite/config.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a2d289e9f0e5f0151d1cd40963461f6427b69df33ba7dde69b950dc58912f016", + "chksum_sha256": "c2e717709f55bbeb87f08b2fe9722c91150c87f94a3245935becc186c5c8def4", "format": 1 }, { @@ -326,7 +326,7 @@ "name": "meta/ee-requirements.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1a36d9a4e747ef31cde1094f3d0805e912b142f9529f2332374bcb0ed34bd5c5", + "chksum_sha256": "d078015d25bf12defe85d0ca788cd997ce9fd8f71c08c96ab27c472346df378d", "format": 1 }, { @@ -410,7 +410,7 @@ "name": "plugins/doc_fragments/compose_v2.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9e42aa81006fe5a72ef9713d008b616da75c6dbb0bc359ff892ced2885545166", + "chksum_sha256": "b92c9446b36c3a2d8faa368a8036561d65cf5dae443d5f6a26f8d800a767a9a5", "format": 1 }, { @@ -431,21 +431,21 @@ "name": "plugins/inventory/docker_containers.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1d01e5f455339e704233d7df6597aae12be29a5fef4e6aef5fcb787cfb8030d2", + "chksum_sha256": "a4feea030c92ca0b3541d679ad49ae060430c0f5a3994fb589485a330613941a", "format": 1 }, { "name": "plugins/inventory/docker_machine.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "559ab252a16a63dc14a344be1f90ee66f976d8f3927f83dda2b3657fea0c1078", + "chksum_sha256": "3b3a1ef0f3d745a7b642777b7dd4126f153898a9c5f536091177442ed2d7c8ed", "format": 1 }, { "name": "plugins/inventory/docker_swarm.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a01b5a62dffc44a43c42dfacff3ee1430d39c43c0d313a4289a12526bca33109", + "chksum_sha256": "04e5cf494bac339905130787fbdfe0ca23ab7caad8fec2f784d014937f86eeb1", "format": 1 }, { @@ -480,7 +480,7 @@ "name": "plugins/module_utils/_api/api/daemon.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c3ff41f499911eba707f23fe05062adf3d5c7464138111c37d1afc30f913a2f8", + "chksum_sha256": "9a0d17ad9e1fc3ca2fe1d502273ad12442cfe46d32bcb19372f6bed32b1e0815", "format": 1 }, { @@ -648,7 +648,7 @@ "name": "plugins/module_utils/_api/utils/utils.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "951272b159d81117e35e73c6d67fce3ea9501b1edc6aace9580063a4a61936b4", + "chksum_sha256": "84d22ae2825223d88d2cc66386427828a3363cf549404a3be68880db91fc0bfa", "format": 1 }, { @@ -760,7 +760,7 @@ "name": "plugins/module_utils/compose_v2.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "60698c26cc1f0b0394ebd9ed2451d45681844d44c79c32b0e2921193feebc29f", + "chksum_sha256": "010f71093f38f18e9fcd1b5cd78a5babe601d2dd79ceb16642b999d299719b6f", "format": 1 }, { @@ -837,14 +837,14 @@ "name": "plugins/modules/docker_compose_v2.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "237adfe9c0e33461e576fe78fb2c5f82b089e9df202fa9e61ca5ab4bc39d4282", + "chksum_sha256": "299fc207fcda246f73bbb7213f0a3f1eca8c5ebf0a6344e571c867fff0eba258", "format": 1 }, { "name": "plugins/modules/docker_compose_v2_pull.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "16378b1ddf2c8914b0b9ec7adc4519f6b664787971ba46672b1ec05f593c1ca3", + "chksum_sha256": "a3171c449b56019853aaa8da3c6d8b54f2bf6fe03ce8da1ade87afcd32a07756", "format": 1 }, { @@ -1100,6 +1100,13 @@ "format": 1 }, { + "name": "plugins/plugin_utils/unsafe.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "93ccc2e18634405c7ff21a91a1df4f17261ac24b0f41bf3c46dbec2f254538c3", + "format": 1 + }, + { "name": "tests", "ftype": "dir", "chksum_type": null, @@ -1555,6 +1562,13 @@ "format": 1 }, { + "name": "tests/integration/targets/docker_compose_v2/tasks/tests/definition.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9a2483112e899562f769a66c3660d7d8fade379f6e2b7c09db7db578c59012a6", + "format": 1 + }, + { "name": "tests/integration/targets/docker_compose_v2/tasks/tests/pull.yml", "ftype": "file", "chksum_type": "sha256", @@ -5884,7 +5898,7 @@ "name": "tests/sanity/ignore-2.17.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "77e2580c039e9062bb354b79bad043392a7e343f11e1797b35b3d28b6955de79", + "chksum_sha256": "f52743569e64513bef9795bab6cf6ccfde9b70a8cd5b81a3fe28994379468877", "format": 1 }, { @@ -5895,6 +5909,20 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f52743569e64513bef9795bab6cf6ccfde9b70a8cd5b81a3fe28994379468877", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.18.txt.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "tests/unit", "ftype": "dir", "chksum_type": null, @@ -5996,7 +6024,7 @@ "name": "tests/unit/plugins/module_utils/_api/api/test_client.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5114474e56b443ac90b48d2ce7d140c825da8cf52cc9d12f1285fd868089a2d2", + "chksum_sha256": "9c9b531983d18111c1ae36320dead46e6a98637a258c5335e29e85915447a768", "format": 1 }, { @@ -6360,7 +6388,7 @@ "name": "CHANGELOG.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a454d168d730e40228bc1b635787e39f4f1dd9561117c1c0472203fb3850ea45", + "chksum_sha256": "b7838b371ac49712b398b2cc47e2959e020fbe727275fc1052c8e49489bc3596", "format": 1 }, { @@ -6374,7 +6402,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c0938e99f68c7ca4fce239f527e9a251a8c32562d4f89065fd2f4b53187f6408", + "chksum_sha256": "8593cb523e7f0bfece19e9dd82a25d06277269451d1334d15c15a868272bcb63", "format": 1 }, { @@ -6395,7 +6423,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f2ed87985a5ed9319821b58e4f4e124db2e06f1b6c60a28c9f50a2666d37ca6f", + "chksum_sha256": "18391f2b88eae674b860ad2cd1ac1426dc64299c91965aa4d30b69ff269aac5f", "format": 1 } ], diff --git a/ansible_collections/community/docker/MANIFEST.json b/ansible_collections/community/docker/MANIFEST.json index ac81cb0ff..447bfc1ce 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.8.1", + "version": "3.9.0", "authors": [ "Ansible Docker Working Group" ], @@ -28,7 +28,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b8f523a2e97dadfa557a707eca6cb96b06b64396f46e33fb6c9bfcb200345094", + "chksum_sha256": "f1b0cee31d5d2e869134e845593489c03632024171cd300f35688fb089e7bf2d", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/docker/README.md b/ansible_collections/community/docker/README.md index 1bee82833..0d169c54a 100644 --- a/ansible_collections/community/docker/README.md +++ b/ansible_collections/community/docker/README.md @@ -16,7 +16,7 @@ Please note that this collection does **not** support Windows targets. The conne ## Tested with Ansible -Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, and ansible-core 2.16 releases, and the current development version of ansible-core. Ansible/ansible-base versions before 2.11.0 are not supported. +Tested with the current 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/ansible-base versions before 2.11.0 are not supported. Please note that Ansible 2.9 and ansible-base 2.10 are no longer supported. If you need to use them, use community.docker 2.x.y. Also note that this collection does not work with ansible-core 2.11 (this includes ansible-base and Ansible 2.9) on Python 3.12+. diff --git a/ansible_collections/community/docker/changelogs/changelog.yaml b/ansible_collections/community/docker/changelogs/changelog.yaml index db03d2485..fc22ba446 100644 --- a/ansible_collections/community/docker/changelogs/changelog.yaml +++ b/ansible_collections/community/docker/changelogs/changelog.yaml @@ -436,7 +436,7 @@ releases: changes: breaking_changes: - docker_compose - fixed ``timeout`` defaulting behavior so that ``stop_grace_period``, - if defined in the compose file, will be used if `timeout`` is not specified + if defined in the compose file, will be used if ``timeout`` is not specified (https://github.com/ansible-collections/community.docker/pull/163). deprecated_features: - docker_container - using the special value ``all`` in ``published_ports`` @@ -1623,3 +1623,41 @@ releases: - 814-docker_compose_v2_pull-idem.yml - inventory-rce.yml release_date: '2024-03-16' + 3.9.0: + changes: + bugfixes: + - docker_compose_v2* - allow ``project_src`` 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/pull/828). + - docker_compose_v2* modules - abort with a nice error message instead of crash + when the Docker Compose CLI plugin version is ``dev`` (https://github.com/ansible-collections/community.docker/issues/825, + https://github.com/ansible-collections/community.docker/pull/826). + - 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.docker/pull/835). + minor_changes: + - The EE requirements now include PyYAML, since the ``docker_compose_v2*`` modules + depend on it when the ``definition`` 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). + - docker_compose_v2* - the new option ``check_files_existing`` allows to disable + the check for one of the files ``compose.yaml``, ``compose.yml``, ``docker-compose.yaml``, + and ``docker-compose.yml`` in ``project_src`` if ``files`` is not specified. + This is necessary if a non-standard compose filename is specified through + other means, like the ``COMPOSE_FILE`` environment variable (https://github.com/ansible-collections/community.docker/issues/838, + https://github.com/ansible-collections/community.docker/pull/839). + - docker_compose_v2* modules - allow to provide an inline definition of the + compose content instead of having to provide a ``project_src`` directory with + the compose file written into it (https://github.com/ansible-collections/community.docker/issues/829, + 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). + release_summary: Bugfix and feature release. + fragments: + - 3.9.0.yml + - 826-docker-compose-v2-version.yml + - 828-compose-project_src.yml + - 832-docker_compose_v2-definition.yml + - 834-datetime-depr.yml + - 835-unsafe.yml + - 839-compose_v2-check-file.yml + release_date: '2024-04-21' diff --git a/ansible_collections/community/docker/docs/docsite/config.yml b/ansible_collections/community/docker/docs/docsite/config.yml index 846b95f62..48eedc269 100644 --- a/ansible_collections/community/docker/docs/docsite/config.yml +++ b/ansible_collections/community/docker/docs/docsite/config.yml @@ -13,3 +13,6 @@ envvar_directives: - DOCKER_TLS - DOCKER_TLS_HOSTNAME - DOCKER_TLS_VERIFY + +changelog: + write_changelog: true diff --git a/ansible_collections/community/docker/meta/ee-requirements.txt b/ansible_collections/community/docker/meta/ee-requirements.txt index de03ff0fd..099dcf9a8 100644 --- a/ansible_collections/community/docker/meta/ee-requirements.txt +++ b/ansible_collections/community/docker/meta/ee-requirements.txt @@ -6,6 +6,7 @@ docker urllib3 requests paramiko +pyyaml # We assume that EEs are not based on Windows, and have Python >= 3.5. # (ansible-builder does not support conditionals, it will simply add diff --git a/ansible_collections/community/docker/plugins/doc_fragments/compose_v2.py b/ansible_collections/community/docker/plugins/doc_fragments/compose_v2.py index 4e21f974c..234a94fe2 100644 --- a/ansible_collections/community/docker/plugins/doc_fragments/compose_v2.py +++ b/ansible_collections/community/docker/plugins/doc_fragments/compose_v2.py @@ -18,20 +18,30 @@ options: - Path to a directory containing a Compose file (C(compose.yml), C(compose.yaml), C(docker-compose.yml), or C(docker-compose.yaml)). - If O(files) is provided, will look for these files in this directory instead. + - Mutually exclusive with O(definition). type: path - required: true project_name: description: - Provide a project name. If not provided, the project name is taken from the basename of O(project_src). + - Required when O(definition) is provided. type: str files: description: - List of Compose file names relative to O(project_src) to be used instead of the main Compose file (C(compose.yml), C(compose.yaml), C(docker-compose.yml), or C(docker-compose.yaml)). - Files are loaded and merged in the order given. + - Mutually exclusive with O(definition). type: list elements: path version_added: 3.7.0 + definition: + description: + - Compose file describing one or more services, networks and volumes. + - Mutually exclusive with O(project_src) and O(files). + - If provided, PyYAML must be available to this module, and O(project_name) must be specified. + - Note that a temporary directory will be created and deleted afterwards when using this option. + type: dict + version_added: 3.9.0 env_files: description: - By default environment files are loaded from a C(.env) file located directly under the O(project_src) directory. @@ -45,6 +55,19 @@ options: - Equivalent to C(docker compose --profile). type: list elements: str + check_files_existing: + description: + - If set to V(false), the module will not check whether one of the files + C(compose.yaml), C(compose.yml), C(docker-compose.yaml), or C(docker-compose.yml) + exists in O(project_src) if O(files) is not provided. + - This can be useful if environment files with C(COMPOSE_FILE) are used to configure a different + filename. The module currently does not check for C(COMPOSE_FILE) in environment files or the + current environment. + type: bool + default: true + version_added: 3.9.0 +requirements: + - "PyYAML if O(definition) is used" notes: - |- The Docker compose CLI plugin has no stable output format (see for example U(https://github.com/docker/compose/issues/10872)), diff --git a/ansible_collections/community/docker/plugins/inventory/docker_containers.py b/ansible_collections/community/docker/plugins/inventory/docker_containers.py index 75b49ff92..0cae05472 100644 --- a/ansible_collections/community/docker/plugins/inventory/docker_containers.py +++ b/ansible_collections/community/docker/plugins/inventory/docker_containers.py @@ -167,7 +167,6 @@ import re from ansible.errors import AnsibleError from ansible.module_utils.common.text.converters import to_native from ansible.plugins.inventory import BaseInventoryPlugin, Constructable -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe from ansible_collections.community.docker.plugins.module_utils.common_api import ( RequestException, @@ -180,6 +179,7 @@ from ansible_collections.community.docker.plugins.plugin_utils.common_api import ) from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, DockerException +from ansible_collections.community.docker.plugins.plugin_utils.unsafe import make_unsafe from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host MIN_DOCKER_API = None diff --git a/ansible_collections/community/docker/plugins/inventory/docker_machine.py b/ansible_collections/community/docker/plugins/inventory/docker_machine.py index e3330a339..984c9932b 100644 --- a/ansible_collections/community/docker/plugins/inventory/docker_machine.py +++ b/ansible_collections/community/docker/plugins/inventory/docker_machine.py @@ -96,8 +96,8 @@ from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.common.process import get_bin_path from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.utils.display import Display -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe +from ansible_collections.community.docker.plugins.plugin_utils.unsafe import make_unsafe from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host import json diff --git a/ansible_collections/community/docker/plugins/inventory/docker_swarm.py b/ansible_collections/community/docker/plugins/inventory/docker_swarm.py index 0d60033f9..acceac86c 100644 --- a/ansible_collections/community/docker/plugins/inventory/docker_swarm.py +++ b/ansible_collections/community/docker/plugins/inventory/docker_swarm.py @@ -159,8 +159,8 @@ from ansible_collections.community.docker.plugins.module_utils.common import get from ansible_collections.community.docker.plugins.module_utils.util import update_tls_hostname from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.parsing.utils.addresses import parse_address -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe +from ansible_collections.community.docker.plugins.plugin_utils.unsafe import make_unsafe from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host try: diff --git a/ansible_collections/community/docker/plugins/module_utils/_api/api/daemon.py b/ansible_collections/community/docker/plugins/module_utils/_api/api/daemon.py index 9e7adbf3f..16d1d1243 100644 --- a/ansible_collections/community/docker/plugins/module_utils/_api/api/daemon.py +++ b/ansible_collections/community/docker/plugins/module_utils/_api/api/daemon.py @@ -11,12 +11,9 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type import os -from datetime import datetime from .. import auth -from ..utils.utils import datetime_to_timestamp, convert_filters from ..utils.decorators import minimum_version -from ..types.daemon import CancellableStream class DaemonApiMixin(object): @@ -36,65 +33,6 @@ class DaemonApiMixin(object): url = self._url('/system/df') return self._result(self._get(url), True) - def events(self, since=None, until=None, filters=None, decode=None): - """ - Get real-time events from the server. Similar to the ``docker events`` - command. - - Args: - since (UTC datetime or int): Get events from this point - until (UTC datetime or int): Get events until this point - filters (dict): Filter the events by event time, container or image - decode (bool): If set to true, stream will be decoded into dicts on - the fly. False by default. - - Returns: - A :py:class:`docker.types.daemon.CancellableStream` generator - - Raises: - :py:class:`docker.errors.APIError` - If the server returns an error. - - Example: - - >>> for event in client.events(decode=True) - ... print(event) - {u'from': u'image/with:tag', - u'id': u'container-id', - u'status': u'start', - u'time': 1423339459} - ... - - or - - >>> events = client.events() - >>> for event in events: - ... print(event) - >>> # and cancel from another thread - >>> events.close() - """ - - if isinstance(since, datetime): - since = datetime_to_timestamp(since) - - if isinstance(until, datetime): - until = datetime_to_timestamp(until) - - if filters: - filters = convert_filters(filters) - - params = { - 'since': since, - 'until': until, - 'filters': filters - } - url = self._url('/events') - - response = self._get(url, params=params, stream=True, timeout=None) - stream = self._stream_helper(response, decode=decode) - - return CancellableStream(stream, response) - def info(self): """ Display system-wide information. Identical to the ``docker info`` diff --git a/ansible_collections/community/docker/plugins/module_utils/_api/utils/utils.py b/ansible_collections/community/docker/plugins/module_utils/_api/utils/utils.py index db3718d4d..cdf3eedd2 100644 --- a/ansible_collections/community/docker/plugins/module_utils/_api/utils/utils.py +++ b/ansible_collections/community/docker/plugins/module_utils/_api/utils/utils.py @@ -17,7 +17,6 @@ import os import os.path import shlex import string -from datetime import datetime from ansible_collections.community.docker.plugins.module_utils.version import StrictVersion from ansible.module_utils.six import PY2, PY3, binary_type, integer_types, iteritems, string_types, text_type @@ -421,12 +420,6 @@ def convert_filters(filters): return json.dumps(result) -def datetime_to_timestamp(dt): - """Convert a UTC datetime to a Unix timestamp""" - delta = dt - datetime.utcfromtimestamp(0) - return delta.seconds + delta.days * 24 * 3600 - - def parse_bytes(s): if isinstance(s, integer_types + (float,)): return s diff --git a/ansible_collections/community/docker/plugins/module_utils/compose_v2.py b/ansible_collections/community/docker/plugins/module_utils/compose_v2.py index 92f109269..85fbd5d80 100644 --- a/ansible_collections/community/docker/plugins/module_utils/compose_v2.py +++ b/ansible_collections/community/docker/plugins/module_utils/compose_v2.py @@ -9,8 +9,12 @@ __metaclass__ = type import os import re +import shutil +import tempfile +import traceback from collections import namedtuple +from ansible.module_utils.basic import missing_required_lib from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.six.moves import shlex_quote @@ -21,6 +25,19 @@ from ansible_collections.community.docker.plugins.module_utils._logfmt import ( parse_line as _parse_logfmt_line, ) +try: + import yaml + try: + # use C version if possible for speedup + from yaml import CSafeDumper as _SafeDumper + except ImportError: + from yaml import SafeDumper as _SafeDumper + HAS_PYYAML = True + PYYAML_IMPORT_ERROR = None +except ImportError: + HAS_PYYAML = False + PYYAML_IMPORT_ERROR = traceback.format_exc() + DOCKER_COMPOSE_FILES = ('compose.yaml', 'compose.yml', 'docker-compose.yaml', 'docker-compose.yml') @@ -484,11 +501,26 @@ def update_failed(result, events, args, stdout, stderr, rc, cli): def common_compose_argspec(): return dict( - project_src=dict(type='path', required=True), + project_src=dict(type='path'), project_name=dict(type='str'), files=dict(type='list', elements='path'), + definition=dict(type='dict'), env_files=dict(type='list', elements='path'), profiles=dict(type='list', elements='str'), + check_files_existing=dict(type='bool', default=True), + ) + + +def common_compose_argspec_ex(): + return dict( + argspec=common_compose_argspec(), + mutually_exclusive=[ + ('definition', 'project_src'), + ('definition', 'files') + ], + required_by={ + 'definition': ('project_name', ), + }, ) @@ -505,37 +537,67 @@ class BaseComposeManager(DockerBaseClass): super(BaseComposeManager, self).__init__() self.client = client self.check_mode = self.client.check_mode + self.cleanup_dirs = set() parameters = self.client.module.params - self.project_src = parameters['project_src'] + if parameters['definition'] is not None and not HAS_PYYAML: + self.fail( + missing_required_lib('PyYAML'), + exception=PYYAML_IMPORT_ERROR + ) + self.project_name = parameters['project_name'] + if parameters['definition'] is not None: + self.project_src = tempfile.mkdtemp(prefix='ansible') + self.cleanup_dirs.add(self.project_src) + compose_file = os.path.join(self.project_src, 'compose.yaml') + self.client.module.add_cleanup_file(compose_file) + try: + with open(compose_file, 'wb') as f: + yaml.dump(parameters['definition'], f, encoding="utf-8", Dumper=_SafeDumper) + except Exception as exc: + self.fail("Error writing to %s - %s" % (compose_file, to_native(exc))) + else: + self.project_src = os.path.abspath(parameters['project_src']) + self.files = parameters['files'] self.env_files = parameters['env_files'] self.profiles = parameters['profiles'] compose = self.client.get_client_plugin_info('compose') if compose is None: - self.client.fail('Docker CLI {0} does not have the compose plugin installed'.format(self.client.get_cli())) + self.fail('Docker CLI {0} does not have the compose plugin installed'.format(self.client.get_cli())) + if compose['Version'] == 'dev': + self.fail( + 'Docker CLI {0} has a compose plugin installed, but it reports version "dev".' + ' Please use a version of the plugin that returns a proper version.' + .format(self.client.get_cli()) + ) compose_version = compose['Version'].lstrip('v') self.compose_version = LooseVersion(compose_version) if self.compose_version < LooseVersion(min_version): - self.client.fail('Docker CLI {cli} has the compose plugin with version {version}; need version {min_version} or later'.format( + self.fail('Docker CLI {cli} has the compose plugin with version {version}; need version {min_version} or later'.format( cli=self.client.get_cli(), version=compose_version, min_version=min_version, )) if not os.path.isdir(self.project_src): - self.client.fail('"{0}" is not a directory'.format(self.project_src)) + self.fail('"{0}" is not a directory'.format(self.project_src)) + self.check_files_existing = parameters['check_files_existing'] if self.files: for file in self.files: path = os.path.join(self.project_src, file) if not os.path.exists(path): - self.client.fail('Cannot find Compose file "{0}" relative to project directory "{1}"'.format(file, self.project_src)) - elif all(not os.path.exists(os.path.join(self.project_src, f)) for f in DOCKER_COMPOSE_FILES): + self.fail('Cannot find Compose file "{0}" relative to project directory "{1}"'.format(file, self.project_src)) + elif self.check_files_existing and all(not os.path.exists(os.path.join(self.project_src, f)) for f in DOCKER_COMPOSE_FILES): filenames = ', '.join(DOCKER_COMPOSE_FILES[:-1]) - self.client.fail('"{0}" does not contain {1}, or {2}'.format(self.project_src, filenames, DOCKER_COMPOSE_FILES[-1])) + self.fail('"{0}" does not contain {1}, or {2}'.format(self.project_src, filenames, DOCKER_COMPOSE_FILES[-1])) + + def fail(self, msg, **kwargs): + self.cleanup() + self.client.fail(msg, **kwargs) def get_base_args(self): args = ['compose', '--ansi', 'never'] @@ -616,3 +678,11 @@ class BaseComposeManager(DockerBaseClass): for res in ('stdout', 'stderr'): if result.get(res) == '': result.pop(res) + + def cleanup(self): + for dir in self.cleanup_dirs: + try: + shutil.rmtree(dir, True) + except Exception: + # shouldn't happen, but simply ignore to be on the safe side + pass diff --git a/ansible_collections/community/docker/plugins/modules/docker_compose_v2.py b/ansible_collections/community/docker/plugins/modules/docker_compose_v2.py index 29bb81ad9..9972d45f6 100644 --- a/ansible_collections/community/docker/plugins/modules/docker_compose_v2.py +++ b/ansible_collections/community/docker/plugins/modules/docker_compose_v2.py @@ -409,7 +409,7 @@ from ansible_collections.community.docker.plugins.module_utils.common_cli import from ansible_collections.community.docker.plugins.module_utils.compose_v2 import ( BaseComposeManager, - common_compose_argspec, + common_compose_argspec_ex, is_failed, ) @@ -435,13 +435,13 @@ class ServicesManager(BaseComposeManager): for key, value in self.scale.items(): if not isinstance(key, string_types): - self.client.fail('The key %s for `scale` is not a string' % repr(key)) + self.fail('The key %s for `scale` is not a string' % repr(key)) try: value = check_type_int(value) except TypeError as exc: - self.client.fail('The value %s for `scale[%s]` is not an integer' % (repr(value), repr(key))) + self.fail('The value %s for `scale[%s]` is not an integer' % (repr(value), repr(key))) if value < 0: - self.client.fail('The value %s for `scale[%s]` is negative' % (repr(value), repr(key))) + self.fail('The value %s for `scale[%s]` is negative' % (repr(value), repr(key))) self.scale[key] = value def run(self): @@ -620,15 +620,19 @@ def main(): wait=dict(type='bool', default=False), wait_timeout=dict(type='int'), ) - argument_spec.update(common_compose_argspec()) + argspec_ex = common_compose_argspec_ex() + argument_spec.update(argspec_ex.pop('argspec')) client = AnsibleModuleDockerClient( argument_spec=argument_spec, supports_check_mode=True, + **argspec_ex ) try: - result = ServicesManager(client).run() + manager = ServicesManager(client) + result = manager.run() + manager.cleanup() client.module.exit_json(**result) except DockerException as e: client.fail('An unexpected docker error occurred: {0}'.format(to_native(e)), exception=traceback.format_exc()) diff --git a/ansible_collections/community/docker/plugins/modules/docker_compose_v2_pull.py b/ansible_collections/community/docker/plugins/modules/docker_compose_v2_pull.py index 2b1980bf6..6b091f9aa 100644 --- a/ansible_collections/community/docker/plugins/modules/docker_compose_v2_pull.py +++ b/ansible_collections/community/docker/plugins/modules/docker_compose_v2_pull.py @@ -102,7 +102,7 @@ from ansible_collections.community.docker.plugins.module_utils.common_cli import from ansible_collections.community.docker.plugins.module_utils.compose_v2 import ( BaseComposeManager, - common_compose_argspec, + common_compose_argspec_ex, ) from ansible_collections.community.docker.plugins.module_utils.version import LooseVersion @@ -117,7 +117,7 @@ class PullManager(BaseComposeManager): if self.policy != 'always' and self.compose_version < LooseVersion('2.22.0'): # https://github.com/docker/compose/pull/10981 - 2.22.0 - self.client.fail('A pull policy other than always is only supported since Docker Compose 2.22.0. {0} has version {1}'.format( + self.fail('A pull policy other than always is only supported since Docker Compose 2.22.0. {0} has version {1}'.format( self.client.get_cli(), self.compose_version)) def get_pull_cmd(self, dry_run, no_start=False): @@ -145,15 +145,19 @@ def main(): argument_spec = dict( policy=dict(type='str', choices=['always', 'missing'], default='always'), ) - argument_spec.update(common_compose_argspec()) + argspec_ex = common_compose_argspec_ex() + argument_spec.update(argspec_ex.pop('argspec')) client = AnsibleModuleDockerClient( argument_spec=argument_spec, supports_check_mode=True, + **argspec_ex ) try: - result = PullManager(client).run() + manager = PullManager(client) + result = manager.run() + manager.cleanup() client.module.exit_json(**result) except DockerException as e: client.fail('An unexpected docker error occurred: {0}'.format(to_native(e)), exception=traceback.format_exc()) diff --git a/ansible_collections/community/docker/plugins/plugin_utils/unsafe.py b/ansible_collections/community/docker/plugins/plugin_utils/unsafe.py new file mode 100644 index 000000000..1eb61bea0 --- /dev/null +++ b/ansible_collections/community/docker/plugins/plugin_utils/unsafe.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, 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 re + +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.common._collections_compat import Mapping, Set +from ansible.module_utils.common.collections import is_sequence +from ansible.utils.unsafe_proxy import ( + AnsibleUnsafe, + wrap_var as _make_unsafe, +) + +_RE_TEMPLATE_CHARS = re.compile(u'[{}]') +_RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]') + + +def make_unsafe(value): + if value is None or isinstance(value, AnsibleUnsafe): + return value + + if isinstance(value, Mapping): + return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) + elif isinstance(value, Set): + return set(make_unsafe(elt) for elt in value) + elif is_sequence(value): + return type(value)(make_unsafe(elt) for elt in value) + elif isinstance(value, binary_type): + if _RE_TEMPLATE_CHARS_BYTES.search(value): + value = _make_unsafe(value) + return value + elif isinstance(value, text_type): + if _RE_TEMPLATE_CHARS.search(value): + value = _make_unsafe(value) + return value + + return value diff --git a/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/tests/definition.yml b/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/tests/definition.yml new file mode 100644 index 000000000..4b88edcd1 --- /dev/null +++ b/ansible_collections/community/docker/tests/integration/targets/docker_compose_v2/tasks/tests/definition.yml @@ -0,0 +1,264 @@ +--- +# 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: + pname: "{{ name_prefix }}-definition" + cname: "{{ name_prefix }}-container" + test_service: | + services: + {{ cname }}: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + stop_grace_period: 1s + test_service_mod: | + services: + {{ cname }}: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 15m"' + stop_grace_period: 1s + + block: + - name: Registering container name + set_fact: + cnames: "{{ cnames + [pname ~ '-' ~ cname ~ '-1'] }}" + dnetworks: "{{ dnetworks + [pname ~ '_default'] }}" + +#################################################################### +## Present ######################################################### +#################################################################### + + - name: Present (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + check_mode: true + register: present_1_check + + - name: Present + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + register: present_1 + + - name: Present (idempotent check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + check_mode: true + register: present_2_check + + - name: Present (idempotent) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + register: present_2 + + - name: Present (changed check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service_mod | from_yaml }}' + state: present + check_mode: true + register: present_3_check + + - name: Present (changed) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service_mod | from_yaml }}' + state: present + register: present_3 + + - assert: + that: + - present_1_check is changed + - present_1 is changed + - present_1.containers | length == 1 + - present_1.containers[0].Name == pname ~ '-' ~ cname ~ '-1' + - present_1.containers[0].Image == docker_test_image_alpine + - present_1.images | length == 1 + - present_1.images[0].ContainerName == pname ~ '-' ~ cname ~ '-1' + - present_1.images[0].Repository == (docker_test_image_alpine | split(':') | first) + - present_1.images[0].Tag == (docker_test_image_alpine | split(':') | last) + - present_2_check is not changed + - present_2 is not changed + - present_3_check is changed + - present_3 is changed + +#################################################################### +## Absent ########################################################## +#################################################################### + + - name: Absent (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service_mod | from_yaml }}' + state: absent + check_mode: true + register: absent_1_check + + - name: Absent + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service_mod | from_yaml }}' + state: absent + register: absent_1 + + - name: Absent (idempotent check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service_mod | from_yaml }}' + state: absent + check_mode: true + register: absent_2_check + + - name: Absent (idempotent) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service_mod | from_yaml }}' + state: absent + register: absent_2 + + - assert: + that: + - absent_1_check is changed + - absent_1 is changed + - absent_2_check is not changed + - absent_2 is not changed + +#################################################################### +## Stopping and starting ########################################### +#################################################################### + + - name: Present stopped (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: stopped + check_mode: true + register: present_1_check + + - name: Present stopped + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: stopped + register: present_1 + + - name: Present stopped (idempotent check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: stopped + check_mode: true + register: present_2_check + + - name: Present stopped (idempotent) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: stopped + register: present_2 + + - name: Started (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + check_mode: true + register: present_3_check + + - name: Started + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + register: present_3 + + - name: Started (idempotent check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + check_mode: true + register: present_4_check + + - name: Started (idempotent) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: present + register: present_4 + + - name: Restarted (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: restarted + check_mode: true + register: present_5_check + + - name: Restarted + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: restarted + register: present_5 + + - name: Stopped (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: stopped + check_mode: true + register: present_6_check + + - name: Stopped + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: stopped + register: present_6 + + - name: Restarted (check) + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: restarted + check_mode: true + register: present_7_check + + - name: Restarted + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: restarted + register: present_7 + + - name: Cleanup + docker_compose_v2: + project_name: '{{ pname }}' + definition: '{{ test_service | from_yaml }}' + state: absent + + - assert: + that: + - present_1_check is changed + - present_1 is changed + - present_2_check is not changed + - present_2 is not changed + - present_3_check is changed + - present_3 is changed + - present_4_check is not changed + - present_4 is not changed + - present_5_check is changed + - present_5 is changed + - present_6_check is changed + - present_6 is changed + - present_7_check is changed + - present_7 is changed diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.17.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.17.txt index 12e0b26f9..f1974bd5e 100644 --- a/ansible_collections/community/docker/tests/sanity/ignore-2.17.txt +++ b/ansible_collections/community/docker/tests/sanity/ignore-2.17.txt @@ -1 +1,4 @@ plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin +plugins/module_utils/_api/api/client.py pylint:use-yield-from # suggested construct does not work with Python 2 +plugins/module_utils/_api/utils/build.py pylint:use-yield-from # suggested construct does not work with Python 2 +tests/unit/plugins/module_utils/test_copy.py pylint:use-yield-from # suggested construct does not work with Python 2 diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.18.txt b/ansible_collections/community/docker/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..f1974bd5e --- /dev/null +++ b/ansible_collections/community/docker/tests/sanity/ignore-2.18.txt @@ -0,0 +1,4 @@ +plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin +plugins/module_utils/_api/api/client.py pylint:use-yield-from # suggested construct does not work with Python 2 +plugins/module_utils/_api/utils/build.py pylint:use-yield-from # suggested construct does not work with Python 2 +tests/unit/plugins/module_utils/test_copy.py pylint:use-yield-from # suggested construct does not work with Python 2 diff --git a/ansible_collections/community/docker/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/docker/tests/sanity/ignore-2.18.txt.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/docker/tests/sanity/ignore-2.18.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/docker/tests/unit/plugins/module_utils/_api/api/test_client.py b/ansible_collections/community/docker/tests/unit/plugins/module_utils/_api/api/test_client.py index 57040b631..87769a3cd 100644 --- a/ansible_collections/community/docker/tests/unit/plugins/module_utils/_api/api/test_client.py +++ b/ansible_collections/community/docker/tests/unit/plugins/module_utils/_api/api/test_client.py @@ -35,7 +35,6 @@ if sys.version_info < (2, 7): from ansible_collections.community.docker.plugins.module_utils._api import constants, errors from ansible_collections.community.docker.plugins.module_utils._api.api.client import APIClient from ansible_collections.community.docker.plugins.module_utils._api.constants import DEFAULT_DOCKER_API_VERSION -from ansible_collections.community.docker.plugins.module_utils._api.utils.utils import convert_filters from requests.packages import urllib3 from .. import fake_api @@ -246,56 +245,6 @@ class DockerApiTest(BaseAPIClientTest): 'serveraddress': None, } - def test_events(self): - self.client.events() - - fake_request.assert_called_with( - 'GET', - url_prefix + 'events', - params={'since': None, 'until': None, 'filters': None}, - stream=True, - timeout=None - ) - - def test_events_with_since_until(self): - ts = 1356048000 - now = datetime.datetime.utcfromtimestamp(ts) - since = now - datetime.timedelta(seconds=10) - until = now + datetime.timedelta(seconds=10) - - self.client.events(since=since, until=until) - - fake_request.assert_called_with( - 'GET', - url_prefix + 'events', - params={ - 'since': ts - 10, - 'until': ts + 10, - 'filters': None - }, - stream=True, - timeout=None - ) - - def test_events_with_filters(self): - filters = {'event': ['die', 'stop'], - 'container': fake_api.FAKE_CONTAINER_ID} - - self.client.events(filters=filters) - - expected_filters = convert_filters(filters) - fake_request.assert_called_with( - 'GET', - url_prefix + 'events', - params={ - 'since': None, - 'until': None, - 'filters': expected_filters - }, - stream=True, - timeout=None - ) - def _socket_path_for_client_session(self, client): socket_adapter = client.get_adapter('http+docker://') return socket_adapter.socket_path diff --git a/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml index 163d71b62..be8f011bd 100644 --- a/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml +++ b/ansible_collections/community/general/.azure-pipelines/azure-pipelines.yml @@ -73,40 +73,40 @@ stages: - test: 3 - test: 4 - test: extra - - stage: Sanity_2_16 - displayName: Sanity 2.16 + - stage: Sanity_2_17 + displayName: Sanity 2.17 dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Test {0} - testFormat: 2.16/sanity/{0} + testFormat: 2.17/sanity/{0} targets: - test: 1 - test: 2 - test: 3 - test: 4 - - stage: Sanity_2_15 - displayName: Sanity 2.15 + - stage: Sanity_2_16 + displayName: Sanity 2.16 dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Test {0} - testFormat: 2.15/sanity/{0} + testFormat: 2.16/sanity/{0} targets: - test: 1 - test: 2 - test: 3 - test: 4 - - stage: Sanity_2_14 - displayName: Sanity 2.14 + - stage: Sanity_2_15 + displayName: Sanity 2.15 dependsOn: [] jobs: - template: templates/matrix.yml parameters: nameFormat: Test {0} - testFormat: 2.14/sanity/{0} + testFormat: 2.15/sanity/{0} targets: - test: 1 - test: 2 @@ -122,12 +122,22 @@ stages: nameFormat: Python {0} testFormat: devel/units/{0}/1 targets: - - test: 3.7 - test: 3.8 - test: 3.9 - test: '3.10' - test: '3.11' - test: '3.12' + - stage: Units_2_17 + displayName: Units 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + nameFormat: Python {0} + testFormat: 2.17/units/{0}/1 + targets: + - test: 3.7 + - test: "3.12" - stage: Units_2_16 displayName: Units 2.16 dependsOn: [] @@ -151,16 +161,6 @@ stages: targets: - test: 3.5 - test: "3.10" - - stage: Units_2_14 - displayName: Units 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - nameFormat: Python {0} - testFormat: 2.14/units/{0}/1 - targets: - - test: 3.9 ## Remote - stage: Remote_devel_extra_vms @@ -191,14 +191,26 @@ stages: test: macos/14.3 - name: RHEL 9.3 test: rhel/9.3 - - name: FreeBSD 13.3 - test: freebsd/13.3 - name: FreeBSD 14.0 test: freebsd/14.0 groups: - 1 - 2 - 3 + - stage: Remote_2_17 + displayName: Remote 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: 2.17/{0} + targets: + - name: FreeBSD 13.3 + test: freebsd/13.3 + groups: + - 1 + - 2 + - 3 - stage: Remote_2_16 displayName: Remote 2.16 dependsOn: [] @@ -241,24 +253,6 @@ stages: - 1 - 2 - 3 - - stage: Remote_2_14 - displayName: Remote 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.14/{0} - targets: - #- name: macOS 12.0 - # test: macos/12.0 - - name: RHEL 9.0 - test: rhel/9.0 - #- name: FreeBSD 12.4 - # test: freebsd/12.4 - groups: - - 1 - - 2 - - 3 ### Docker - stage: Docker_devel @@ -275,6 +269,18 @@ stages: test: ubuntu2004 - name: Ubuntu 22.04 test: ubuntu2204 + groups: + - 1 + - 2 + - 3 + - stage: Docker_2_17 + displayName: Docker 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: 2.17/linux/{0} + targets: - name: Alpine 3.19 test: alpine319 groups: @@ -315,20 +321,6 @@ stages: - 1 - 2 - 3 - - stage: Docker_2_14 - displayName: Docker 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.14/linux/{0} - targets: - - name: Alpine 3 - test: alpine3 - groups: - - 1 - - 2 - - 3 ### Community Docker - stage: Docker_community_devel @@ -360,6 +352,17 @@ stages: nameFormat: Python {0} testFormat: devel/generic/{0}/1 targets: + - test: '3.8' + - test: '3.11' + - stage: Generic_2_17 + displayName: Generic 2.17 + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + nameFormat: Python {0} + testFormat: 2.17/generic/{0}/1 + targets: - test: '3.7' - test: '3.12' - stage: Generic_2_16 @@ -384,42 +387,32 @@ stages: testFormat: 2.15/generic/{0}/1 targets: - test: '3.9' - - stage: Generic_2_14 - displayName: Generic 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - nameFormat: Python {0} - testFormat: 2.14/generic/{0}/1 - targets: - - test: '3.10' - stage: Summary condition: succeededOrFailed() dependsOn: - Sanity_devel + - Sanity_2_17 - Sanity_2_16 - Sanity_2_15 - - Sanity_2_14 - Units_devel + - Units_2_17 - Units_2_16 - Units_2_15 - - Units_2_14 - Remote_devel_extra_vms - Remote_devel + - Remote_2_17 - Remote_2_16 - Remote_2_15 - - Remote_2_14 - Docker_devel + - Docker_2_17 - Docker_2_16 - Docker_2_15 - - Docker_2_14 - Docker_community_devel # Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled. # - Generic_devel +# - Generic_2_17 # - Generic_2_16 # - Generic_2_15 -# - Generic_2_14 jobs: - template: templates/coverage.yml diff --git a/ansible_collections/community/general/.github/BOTMETA.yml b/ansible_collections/community/general/.github/BOTMETA.yml index 64cbc7021..e21d0c81c 100644 --- a/ansible_collections/community/general/.github/BOTMETA.yml +++ b/ansible_collections/community/general/.github/BOTMETA.yml @@ -780,6 +780,8 @@ files: maintainers: laurpaum $modules/keycloak_component_info.py: maintainers: desand01 + $modules/keycloak_client_rolescope.py: + maintainers: desand01 $modules/keycloak_user_rolemapping.py: maintainers: bratwurzt $modules/keycloak_realm_rolemapping.py: @@ -1445,6 +1447,8 @@ files: ignore: matze labels: zypper maintainers: $team_suse + $plugin_utils/unsafe.py: + maintainers: felixfontein $tests/a_module.py: maintainers: felixfontein $tests/fqdn_valid.py: @@ -1501,7 +1505,6 @@ macros: becomes: plugins/become caches: plugins/cache callbacks: plugins/callback - cliconfs: plugins/cliconf connections: plugins/connection doc_fragments: plugins/doc_fragments filters: plugins/filter @@ -1509,7 +1512,7 @@ macros: lookups: plugins/lookup module_utils: plugins/module_utils modules: plugins/modules - terminals: plugins/terminal + plugin_utils: plugins/plugin_utils tests: plugins/test team_ansible_core: team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross diff --git a/ansible_collections/community/general/.github/workflows/ansible-test.yml b/ansible_collections/community/general/.github/workflows/ansible-test.yml index bc9daaa43..ecfc36565 100644 --- a/ansible_collections/community/general/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/general/.github/workflows/ansible-test.yml @@ -30,6 +30,7 @@ jobs: matrix: ansible: - '2.13' + - '2.14' # 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 @@ -72,6 +73,8 @@ jobs: python: '2.7' - ansible: '2.13' python: '3.8' + - ansible: '2.14' + python: '3.9' steps: - name: >- @@ -148,11 +151,29 @@ jobs: docker: alpine3 python: '' target: azp/posix/3/ + # 2.14 + - ansible: '2.14' + docker: alpine3 + python: '' + target: azp/posix/1/ + - ansible: '2.14' + docker: alpine3 + python: '' + target: azp/posix/2/ + - ansible: '2.14' + docker: alpine3 + python: '' + target: azp/posix/3/ # Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled. # - ansible: '2.13' # docker: default # python: '3.9' # target: azp/generic/1/ + # Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled. + # - ansible: '2.14' + # docker: default + # python: '3.10' + # target: azp/generic/1/ steps: - name: >- diff --git a/ansible_collections/community/general/CHANGELOG.md b/ansible_collections/community/general/CHANGELOG.md index 08cac8a97..8f23931fe 100644 --- a/ansible_collections/community/general/CHANGELOG.md +++ b/ansible_collections/community/general/CHANGELOG.md @@ -2,71 +2,131 @@ **Topics** -- <a href="#v8-5-0">v8\.5\.0</a> +- <a href="#v8-6-0">v8\.6\.0</a> - <a href="#release-summary">Release Summary</a> - <a href="#minor-changes">Minor Changes</a> - - <a href="#security-fixes">Security Fixes</a> + - <a href="#deprecated-features">Deprecated Features</a> - <a href="#bugfixes">Bugfixes</a> - <a href="#new-modules">New Modules</a> -- <a href="#v8-4-0">v8\.4\.0</a> +- <a href="#v8-5-0">v8\.5\.0</a> - <a href="#release-summary-1">Release Summary</a> - <a href="#minor-changes-1">Minor Changes</a> + - <a href="#security-fixes">Security Fixes</a> - <a href="#bugfixes-1">Bugfixes</a> - - <a href="#new-plugins">New Plugins</a> - - <a href="#callback">Callback</a> - - <a href="#filter">Filter</a> - <a href="#new-modules-1">New Modules</a> -- <a href="#v8-3-0">v8\.3\.0</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="#deprecated-features">Deprecated Features</a> - <a href="#bugfixes-2">Bugfixes</a> + - <a href="#new-plugins">New Plugins</a> + - <a href="#callback">Callback</a> + - <a href="#filter">Filter</a> - <a href="#new-modules-2">New Modules</a> -- <a href="#v8-2-0">v8\.2\.0</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="#lookup">Lookup</a> - - <a href="#new-modules-3">New Modules</a> + - <a href="#new-modules-4">New Modules</a> - <a href="#v8-1-0">v8\.1\.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="#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-4">New Modules</a> + - <a href="#new-modules-5">New Modules</a> - <a href="#v8-0-2">v8\.0\.2</a> - - <a href="#release-summary-5">Release Summary</a> - - <a href="#bugfixes-5">Bugfixes</a> -- <a href="#v8-0-1">v8\.0\.1</a> - <a href="#release-summary-6">Release Summary</a> - <a href="#bugfixes-6">Bugfixes</a> -- <a href="#v8-0-0">v8\.0\.0</a> +- <a href="#v8-0-1">v8\.0\.1</a> - <a href="#release-summary-7">Release Summary</a> - - <a href="#minor-changes-5">Minor Changes</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-1">Deprecated Features</a> + - <a href="#deprecated-features-2">Deprecated Features</a> - <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a> - - <a href="#bugfixes-7">Bugfixes</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-5">New Modules</a> + - <a href="#new-modules-6">New Modules</a> This changelog describes changes after version 7\.0\.0\. +<a id="v8-6-0"></a> +## v8\.6\.0 + +<a id="release-summary"></a> +### Release Summary + +Regular bugfix and features release\. + +<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)\)\. + +<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 -<a id="release-summary"></a> +<a id="release-summary-1"></a> ### Release Summary Regular feature and bugfix release with security fixes\. -<a id="minor-changes"></a> +<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)\)\. @@ -84,7 +144,7 @@ Regular feature and bugfix release with 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"></a> +<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)\)\. @@ -98,7 +158,7 @@ Regular feature and bugfix release with security fixes\. * 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"></a> +<a id="new-modules-1"></a> ### New Modules * usb\_facts \- Allows listing information about USB devices @@ -106,12 +166,12 @@ Regular feature and bugfix release with security fixes\. <a id="v8-4-0"></a> ## v8\.4\.0 -<a id="release-summary-1"></a> +<a id="release-summary-2"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-1"></a> +<a id="minor-changes-2"></a> ### Minor Changes * 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)\)\. @@ -124,7 +184,7 @@ Regular bugfix and feature release\. * 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-1"></a> +<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)\)\. @@ -153,7 +213,7 @@ Regular bugfix and feature release\. * lists\_symmetric\_difference \- Symmetric Difference of lists with a predictive order * lists\_union \- Union of lists with a predictive order -<a id="new-modules-1"></a> +<a id="new-modules-2"></a> ### New Modules * gitlab\_group\_access\_token \- Manages GitLab group access tokens @@ -162,12 +222,12 @@ Regular bugfix and feature release\. <a id="v8-3-0"></a> ## v8\.3\.0 -<a id="release-summary-2"></a> +<a id="release-summary-3"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-2"></a> +<a id="minor-changes-3"></a> ### Minor Changes * 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)\)\. @@ -180,12 +240,12 @@ Regular bugfix and feature release\. * 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"></a> +<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-2"></a> +<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)\)\. @@ -196,7 +256,7 @@ Regular bugfix and feature release\. * 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-2"></a> +<a id="new-modules-3"></a> ### New Modules * consul\_acl\_bootstrap \- Bootstrap ACLs in Consul @@ -209,12 +269,12 @@ Regular bugfix and feature release\. <a id="v8-2-0"></a> ## v8\.2\.0 -<a id="release-summary-3"></a> +<a id="release-summary-4"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-3"></a> +<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)\)\. @@ -230,7 +290,7 @@ Regular bugfix and feature release\. * 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-3"></a> +<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)\)\. @@ -258,7 +318,7 @@ Regular bugfix and feature release\. * github\_app\_access\_token \- Obtain short\-lived Github App Access tokens -<a id="new-modules-3"></a> +<a id="new-modules-4"></a> ### New Modules * dnf\_config\_manager \- Enable or disable dnf repositories using config\-manager @@ -270,12 +330,12 @@ Regular bugfix and feature release\. <a id="v8-1-0"></a> ## v8\.1\.0 -<a id="release-summary-4"></a> +<a id="release-summary-5"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-4"></a> +<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)\)\. @@ -312,7 +372,7 @@ Regular bugfix and feature release\. * 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)\)\. * 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)\)\. -<a id="bugfixes-4"></a> +<a id="bugfixes-5"></a> ### 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](https\://github\.com/ansible\-collections/community\.general/issues/7414)\)\. @@ -343,7 +403,7 @@ Regular bugfix and feature release\. * fqdn\_valid \- Validates fully\-qualified domain names against RFC 1123 -<a id="new-modules-4"></a> +<a id="new-modules-5"></a> ### New Modules * git\_config\_info \- Read git configuration @@ -353,12 +413,12 @@ Regular bugfix and feature release\. <a id="v8-0-2"></a> ## v8\.0\.2 -<a id="release-summary-5"></a> +<a id="release-summary-6"></a> ### Release Summary Bugfix release for inclusion in Ansible 9\.0\.0rc1\. -<a id="bugfixes-5"></a> +<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)\)\. @@ -367,12 +427,12 @@ Bugfix release for inclusion in Ansible 9\.0\.0rc1\. <a id="v8-0-1"></a> ## v8\.0\.1 -<a id="release-summary-6"></a> +<a id="release-summary-7"></a> ### Release Summary Bugfix release for inclusion in Ansible 9\.0\.0b1\. -<a id="bugfixes-6"></a> +<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)\)\. @@ -385,12 +445,12 @@ Bugfix release for inclusion in Ansible 9\.0\.0b1\. <a id="v8-0-0"></a> ## v8\.0\.0 -<a id="release-summary-7"></a> +<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-5"></a> +<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)\)\. @@ -529,7 +589,7 @@ This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-1 * 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="deprecated-features-1"></a> +<a id="deprecated-features-2"></a> ### Deprecated Features * 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)\)\. @@ -589,7 +649,7 @@ This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-1 * 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-7"></a> +<a id="bugfixes-8"></a> ### 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](https\://github\.com/ansible\-collections/community\.general/pull/7200)\)\. @@ -684,7 +744,7 @@ This is release 8\.0\.0 of <code>community\.general</code>\, released on 2023\-1 * bitwarden\_secrets\_manager \- Retrieve secrets from Bitwarden Secrets Manager -<a id="new-modules-5"></a> +<a id="new-modules-6"></a> ### New Modules * consul\_policy \- Manipulate Consul policies diff --git a/ansible_collections/community/general/CHANGELOG.rst b/ansible_collections/community/general/CHANGELOG.rst index da10a021b..5a5a0cb7c 100644 --- a/ansible_collections/community/general/CHANGELOG.rst +++ b/ansible_collections/community/general/CHANGELOG.rst @@ -6,6 +6,60 @@ Community General Release Notes This changelog describes changes after version 7.0.0. +v8.6.0 +====== + +Release Summary +--------------- + +Regular bugfix and features release. + +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 ====== diff --git a/ansible_collections/community/general/FILES.json b/ansible_collections/community/general/FILES.json index c84d62a88..cbe1d8808 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": "3a0a3c682a3f4926434b08f73ab1d362629d17db898358d8970c0a78d6195a74", + "chksum_sha256": "370fe873607691433d32772c07c53712f66f3745026442838d9d7ca9af953e48", "format": 1 }, { @@ -165,7 +165,7 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "881d33effb01a3b9c94026a3720af4fc2cc3f1c7fa93d48d4ffd2584b9e2db9d", + "chksum_sha256": "ef0a066aa753e5667b6b1d4e2887f13add9b692f6373bbac695bcbe43e73e73f", "format": 1 }, { @@ -193,7 +193,7 @@ "name": ".github/BOTMETA.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2f3ee06f8b6dad417086bf9cc5e0e7ff4519aa65139373c43e3fbe7cff572f3b", + "chksum_sha256": "5d44cab4aa242ff60409d95adf43c4be0bc3d4eace180b0f04da04bcf2d0e119", "format": 1 }, { @@ -312,7 +312,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cabe396ff93a6bc5327c16686af1c75f29d1b239ce7ceb6e25930f33690da3da", + "chksum_sha256": "cc2e8e92892d291b60d26135122e9017acb600db7f386a6ccd71d77846436776", "format": 1 }, { @@ -771,6 +771,13 @@ "format": 1 }, { + "name": "docs/docsite/config.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0c5ec9ff76cf4db33b5d3f771419ef50d448e5d510cb7a98fc07dd9ecee69c4e", + "format": 1 + }, + { "name": "docs/docsite/extra-docs.yml", "ftype": "file", "chksum_type": "sha256", @@ -795,7 +802,7 @@ "name": "meta/runtime.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "893ee2f56034e3e8ac5b9a73e689fef80921b692ba6da0e5db2fd330aad2a617", + "chksum_sha256": "7aed4acf161705fece142c2d79ed08c7a5fdf3239644406203cb494b2e74c7a2", "format": 1 }, { @@ -991,7 +998,7 @@ "name": "plugins/callback/hipchat.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "987c2a8b697623f30f2de2d4e70b027096190c0a4a6c99703db36ce0b1b9bb63", + "chksum_sha256": "3b5b9a0b3bf7fa339aff42b2d8e0695fd7c596c252b9773b3373863ff8cab720", "format": 1 }, { @@ -1012,7 +1019,7 @@ "name": "plugins/callback/loganalytics.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "41ee07d1e548f4d03475f0001e084645124d77d850e031c17d78d81b5bfc2e31", + "chksum_sha256": "33b365b6aa6ede1129ab535c212d87828c933ecb1ba6aa9875e5e4e449dcd397", "format": 1 }, { @@ -1033,7 +1040,7 @@ "name": "plugins/callback/logstash.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "411199e9f8925c20601b623056b6288f02000815efcb0c25254e69051a826aee", + "chksum_sha256": "cd3dc96b5ad3fbd489739967e1ca022cacd1e54d760d78ed7e777ed35387895d", "format": 1 }, { @@ -1089,14 +1096,14 @@ "name": "plugins/callback/splunk.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "552c6c10b5ceed03a4728c8dee70d6211a1b208095c4ff4748ebf8c2110f4bf9", + "chksum_sha256": "e275389d7786a2a693ea6b313686dee7da6c1b7afc3c25e4ed7538efca6c157e", "format": 1 }, { "name": "plugins/callback/sumologic.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3265907f5d62128170d48eefda9901eb1f3d6bc36d9f93e5f900403850724d73", + "chksum_sha256": "de3553075bbf8bb7bc9c91efcea1ad418ea0a2e908d47cc90f975ba3889b054e", "format": 1 }, { @@ -1537,7 +1544,7 @@ "name": "plugins/filter/from_ini.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "aa388a5cdd894e1c3d1e66580dbd2947abc2a60b8a30b05fee1a5fb8bb8cc642", + "chksum_sha256": "eeb40072eda1075f377f210310a0a74f3ab81618575b1bfec3e9bc6ca42896c5", "format": 1 }, { @@ -1656,7 +1663,7 @@ "name": "plugins/filter/to_ini.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d1012ffb9f4d8626c948dc52bf36a4c42287e1deaf65eca1ecf954170d61fdc0", + "chksum_sha256": "40e4926d88132be0f03c6857df46789931a450a8107cf248bee01c9725310d7b", "format": 1 }, { @@ -1733,91 +1740,91 @@ "name": "plugins/inventory/cobbler.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2a6cd6114bae928361af7ec60e99a4e85f9ed3b437c943bc60e23f4c21401c64", + "chksum_sha256": "f061ed54c78be6b39aed094d77480d8a90148a5b5cd92fd3167f23482d93226d", "format": 1 }, { "name": "plugins/inventory/gitlab_runners.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1fd2de379dbf83ba5fddafeb3fecb693ef5d35157ef5a8f0e9718d984ca4b9f4", + "chksum_sha256": "2c4e173a50c5838eb3b1a7b0525a60eeddbc8aad3a31f53af6087a53323f68a3", "format": 1 }, { "name": "plugins/inventory/icinga2.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f9bdc281508bc222fd6e1f19c34575cd9dc5056ca3ca1d7a8f4481de1d24cf27", + "chksum_sha256": "9a9bcca6fa0b8fb673ae533d8a5455317a131294ec69ac292512a07ba5047e77", "format": 1 }, { "name": "plugins/inventory/linode.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d2375902a364f0c8b8cc9d6f88512be7b4371d6dbfcda4e5707df404b5336ae2", + "chksum_sha256": "fe2339ec5b8572f3e9c9c1414c961068ebf1e968ba255110d3fc882740ba2015", "format": 1 }, { "name": "plugins/inventory/lxd.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6f501b691589f29ad2cf5954d98e2576e2944f88f9d23d74cece0f0850c77888", + "chksum_sha256": "1aee550b5e6222dadc8ed4a6950a4b471f40892627d92badba12dc3208163585", "format": 1 }, { "name": "plugins/inventory/nmap.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "76f3c42cba7bb30fa841ba9193a71c9ce857303c9d83d9d8d1ff04dfc4f1c726", + "chksum_sha256": "81d1bc141fc09acddf6da7500ea3834c252b097aacaa13dd38205b04cbe2250b", "format": 1 }, { "name": "plugins/inventory/online.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "533c5edf6b17e4b25628aad13fc5d7aba7c9ea1ae86e12d091c50aef12a8f775", + "chksum_sha256": "f6af33b129af56d23bc8bf66072f656e336b0cf7fb5dab958c992f2392fcdf9d", "format": 1 }, { "name": "plugins/inventory/opennebula.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "76f28fa3696a031e014d66ea1617fb5d98319dc6809dac3218f7a4d800ceff45", + "chksum_sha256": "954bb22612557fbe3be3510d3ebc7e230164cb3dcb689345a287270b85234970", "format": 1 }, { "name": "plugins/inventory/proxmox.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "01313ffb0af966b9a4e2b6f95c1497359a98ae5847be4b9c324aae3c5e412f9c", + "chksum_sha256": "a4ceafbac13b19794a5ee15b778407fc0e7879ec56dccc13c9affa9008f9a81c", "format": 1 }, { "name": "plugins/inventory/scaleway.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5663c4b332dda4720df71285671ef999c8eaa3e4e3335bca1e8e376e65585c46", + "chksum_sha256": "2a8adf3084473bf8a7f7f6983ecbbac1a7f18ccfe073b018ea939d933fefa095", "format": 1 }, { "name": "plugins/inventory/stackpath_compute.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "38003a1f85c8781d73ae5352d461c87c5a66db67810aa3113d5f15b1e07d3e06", + "chksum_sha256": "5ee8154d186e72b3cbbd0b4ce8232f18b06e028010779a6d2ea3d494aed2774f", "format": 1 }, { "name": "plugins/inventory/virtualbox.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0547e7940ec2940cb9ef4bd07b321b45a458792e6b2d572c2abceb72c4e78d26", + "chksum_sha256": "40f8697615b3e767265ef7e0c24735fdb4d6bc8d354d6bb2296c12f4e7a99a5b", "format": 1 }, { "name": "plugins/inventory/xen_orchestra.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d9b079b0215b6775490192fffae78fe46f088675348ae4129d7825aeda59bb0a", + "chksum_sha256": "4622368d48743bb29d2d42c70956bc953265c062a2a9e33d03d7635bbd0bcb0b", "format": 1 }, { @@ -1831,14 +1838,14 @@ "name": "plugins/lookup/bitwarden.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5f0e069d8c299d2bb3087726049d7df8d03a4e545ba3d8df9fd429ed6767125d", + "chksum_sha256": "e894798a425bfd34301056e5cdf03ce61d18c82d03db8c95dcd7778d15707923", "format": 1 }, { "name": "plugins/lookup/bitwarden_secrets_manager.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5453a43746aad1262ded5a08d8ebad62f32f26ca22d1dd873320b3ba042345b3", + "chksum_sha256": "0e1034a5fcf7fa8646b9b606efd34b709a99b64dcb418bc5d3d4f2ab8edc451a", "format": 1 }, { @@ -2013,7 +2020,7 @@ "name": "plugins/lookup/passwordstore.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bf39d1661bdd94a94996a594cb00c55adc3bfa44e0041cf9c859f4125442565e", + "chksum_sha256": "37381b1f5be5edd85f5d3fd29ab95c05b728b11adb4f236c2face2f3d9f4af53", "format": 1 }, { @@ -2090,7 +2097,7 @@ "name": "plugins/module_utils/identity/keycloak/keycloak.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b3f1080b3b46444e8eebd03321d1bba8a599b845b8d8bbc846ae2225ee2a33fe", + "chksum_sha256": "05a7911218ce6acf0cdcb2d0f0b251c07aaa6fa10ebbd45fa6bdaa7157ef0376", "format": 1 }, { @@ -2346,6 +2353,13 @@ "format": 1 }, { + "name": "plugins/module_utils/datetime.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "49ede572b9ee1cd97b75cae58ea5ed573a91978ffc1853e6c1b6be2c78b28075", + "format": 1 + }, + { "name": "plugins/module_utils/deps.py", "ftype": "file", "chksum_type": "sha256", @@ -2384,7 +2398,7 @@ "name": "plugins/module_utils/gitlab.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "11504e0b1cc93424e0ab0c496737eb412537558268624b36ab7860ca0a89e6ec", + "chksum_sha256": "f0edcbd8ae4a68f9c003e48360e3c4247768a801e34580ed035d04f15d6857a4", "format": 1 }, { @@ -2426,7 +2440,7 @@ "name": "plugins/module_utils/ipa.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2fbe8b6da9a2d3be12640df88c4ce8907f52706e0175228a8f2e03aacf0f0f60", + "chksum_sha256": "e2739a328e34cbfea207e502fb2b1a6e95a6062b5dd64f81cee00b5d7eec8bc3", "format": 1 }, { @@ -2552,7 +2566,7 @@ "name": "plugins/module_utils/puppet.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3e1957ab2d41bb194a5f100737467e054580c8e48b4997757c484b99fc02ab27", + "chksum_sha256": "d0c7e2106d6247342b11f2de422240b828a122acd98d9c4ffe5b91899b8893ff", "format": 1 }, { @@ -2573,7 +2587,7 @@ "name": "plugins/module_utils/redfish_utils.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bc9400ba787e5570d9344c685596e7c3e04013ce32215c3874d168f2af57d980", + "chksum_sha256": "ce4679e15df51fc1a102f5f6f8ef1cb8f8153cfb5a896786c5531829d76ce0e2", "format": 1 }, { @@ -2608,7 +2622,7 @@ "name": "plugins/module_utils/scaleway.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bf3a6babbac970f45b6c9473704684b0980330f7e8cfc71e45513e9fa22aea35", + "chksum_sha256": "5a86772778ddfbaca5cc50138f33ac5ed259da4f365925d1f7032b3f0d65beff", "format": 1 }, { @@ -2713,7 +2727,7 @@ "name": "plugins/modules/aix_filesystem.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "76c6c1b52220f8808fd8c2c4a06a9a0e9be8cff0f8abc5336cdc49a5d9ae52f3", + "chksum_sha256": "e8e4d96b11af1dcdcf0cdd5ff1eee2efec0619ee6639563fa93b9dd3e0046647", "format": 1 }, { @@ -2804,7 +2818,7 @@ "name": "plugins/modules/apt_rpm.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0b60fc7bf785127673dd9eac1396da1d3cb759efe84e9f30b98530b82e5980c9", + "chksum_sha256": "f0570e79b53c66ebfb69e175ff0edb87f3ea9c10ce4efc791ed0720644459350", "format": 1 }, { @@ -3056,14 +3070,14 @@ "name": "plugins/modules/cobbler_sync.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "69bc8b3cd61a7d22073eaa6944e645ffd8133c7ed858b5cd130fc343d074b5ea", + "chksum_sha256": "8f888f082b8266fbe3eb76212b06fdcb8d3e95cadccb1cd2a6d7e4138a5e0293", "format": 1 }, { "name": "plugins/modules/cobbler_system.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "de819b4c8494a9aa92e04609c29027c3357fc682aa4903f4fc3569289b088b02", + "chksum_sha256": "0e12cad44f5adf1f3c33242bce11e90b6b94f63159f83df3352dbbaee775fb53", "format": 1 }, { @@ -3336,14 +3350,14 @@ "name": "plugins/modules/filesystem.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5c68cc92970f2e756d3f153b6724d53413819f13bd87967fba8c723779f0fbf5", + "chksum_sha256": "ba0eb413952ad67723b8d06b82adfe05ee7fe63274d0b78bbb1df246a272df0f", "format": 1 }, { "name": "plugins/modules/flatpak.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6a1ff04ef312b0acec7ec57c654bc462201dfd026f73bab41dd585ad726d00f4", + "chksum_sha256": "083768938533021fb5ad0e92ea8b7a1cf859c68a365b0d21c16df6c53905f728", "format": 1 }, { @@ -3427,7 +3441,7 @@ "name": "plugins/modules/github_key.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "79de6029d98cea3b3b2c2591e8c59168de2cc3395ef397c58b89dac9fc0df6a2", + "chksum_sha256": "5981c162d708eaca4be13a165ae2cd89492a5a2f1d50df1e87963ed0781a0cc6", "format": 1 }, { @@ -3518,14 +3532,14 @@ "name": "plugins/modules/gitlab_issue.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c862d68cc3e2201f3bc3af96f67bf17a3780786c7f76e59544a3386a88c5c468", + "chksum_sha256": "0c60e0a22b6e72cc1983ac526ddb856e314e2abe24b4007e278d8e242bef39b8", "format": 1 }, { "name": "plugins/modules/gitlab_label.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "25fff68c8d2541d8ef914428987a9a8141d66938694fa56693fc1309215361c3", + "chksum_sha256": "85d923d3db2f0381470a430df78c8bb3edeb91f20e70108904b800cae04f9bce", "format": 1 }, { @@ -3539,7 +3553,7 @@ "name": "plugins/modules/gitlab_milestone.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3c6d14ab0a6c17a49e557946de3fbf80aa7dd07d9345a9aab2b1a11769978f80", + "chksum_sha256": "4d869613511d223e21b3173aa16b7131cb4058badd6645bc553832f5a2e9355c", "format": 1 }, { @@ -3616,7 +3630,7 @@ "name": "plugins/modules/haproxy.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "816d15aa1df4f09211a1e2e194609db779f32a9c1ae7f12c37fc52895c0e1a1a", + "chksum_sha256": "3c574e4b671db22e9176bbfe1a772e7de68dacb3f67d555f521fdfe5c48473bf", "format": 1 }, { @@ -3889,7 +3903,7 @@ "name": "plugins/modules/imc_rest.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3b212b98cbc6821f9f079ad0d28596d375f1da710bc9d8110bc6a6f754a77ede", + "chksum_sha256": "eb18b5c19057c4aed0548b9cbf0277fd4b666d5aab2638ca03ca1488a542a967", "format": 1 }, { @@ -3945,7 +3959,7 @@ "name": "plugins/modules/ini_file.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "37638878ed3b6e5c2860382a8b2940eb20906b12da727c67c4c1e04f38e68255", + "chksum_sha256": "c1fbd2a5aa3de2746f9b894b312e7c27542c98dd3cd8cbb7fd5ed22a4c92d56f", "format": 1 }, { @@ -4183,7 +4197,7 @@ "name": "plugins/modules/java_cert.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f325def87c1b6ab8e1e1acf9829b9e0f7b22c773a35e5a9eee2116f1b4f37d9b", + "chksum_sha256": "dc5ddeb9830187191cf78572ee079e8abf7ca8dda7a0d34a710d3c4079db6730", "format": 1 }, { @@ -4309,7 +4323,7 @@ "name": "plugins/modules/keycloak_client.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d1c5ee5cfeaaa3ea1653e2a3a43c642e95d6e837269a8f5bb967ae9f74e26139", + "chksum_sha256": "9065934124dc12b01077cd9c2caea2640c2f76a5d00541af2a1b1500cbbcba57", "format": 1 }, { @@ -4320,10 +4334,17 @@ "format": 1 }, { + "name": "plugins/modules/keycloak_client_rolescope.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "24ddf67b981ad224debe4cc8eff03a9afb8924e9e3ab8da474569e4cb73889f1", + "format": 1 + }, + { "name": "plugins/modules/keycloak_clientscope.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "944a9d01857144ae760d704e124b4dd3da31121358efd17058bf4024e3e111d5", + "chksum_sha256": "c712e8e6d6b9d27297f7fbed371d7338aea6c92c6fc940fea1cf9e8c4b897c71", "format": 1 }, { @@ -4351,7 +4372,7 @@ "name": "plugins/modules/keycloak_clienttemplate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "51ae2bb14c80773bc7dbfe159a9fda0337609ebea371904f0ac75010ce64e689", + "chksum_sha256": "84508ab4b96dbb81f9fa4cd94c4babb45ad01065a434a62d96d9dca7518d1609", "format": 1 }, { @@ -4379,7 +4400,7 @@ "name": "plugins/modules/keycloak_realm.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ded26fe5a5bd4422a8f91c31a266d502c23653087128af2753347601d4178391", + "chksum_sha256": "9ec1ddefe1b7badaf842680f2799f343c6e4d1c7cb8aec769a002e7383b14e6f", "format": 1 }, { @@ -4610,7 +4631,7 @@ "name": "plugins/modules/lxd_container.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "232e7553c192bd73a35bd0689e9d47a6eb29ca60690d4da6e763cf81dc079ee9", + "chksum_sha256": "3421f907d434f83dd6a346507a607c5ad7cc0b727673b74badf5003841974b4d", "format": 1 }, { @@ -4876,7 +4897,7 @@ "name": "plugins/modules/nmcli.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "04fef80fc4f380de8caa7d9b81a40b1ad6e224b9a34b7d384d82f0982ab0dad6", + "chksum_sha256": "963b12d10e1bd6f4ec0bdc01aa6527074381b6f6ba7ab57fe0aa8307f324b033", "format": 1 }, { @@ -5212,7 +5233,7 @@ "name": "plugins/modules/osx_defaults.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "25083c7e2f8c702fd3c2739fe6527c69f3976e9bcef0263c3f8bdfd4a28746a0", + "chksum_sha256": "bc7858ccd08df77b492c2c54c38dc67b75706abda671e7bc619d9933cf1ccd8e", "format": 1 }, { @@ -5303,7 +5324,7 @@ "name": "plugins/modules/pagerduty.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6da5163291f420d74945b2723ed5bf0acf0e43f9280793c17554143bbef6cb75", + "chksum_sha256": "515d603cd19dcd4d102ab907148930c08383906eede2029c5e8605642518c709", "format": 1 }, { @@ -5317,7 +5338,7 @@ "name": "plugins/modules/pagerduty_change.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "13f3a20302ece4ae73d94292180ea986b8d24cf05c5c5c587481dd3fc55cdd2c", + "chksum_sha256": "26d9bd41d8fd2c404b93fd60812e0f0c5e9776afa1d5387e0b4fe03a581cf3fd", "format": 1 }, { @@ -5443,7 +5464,7 @@ "name": "plugins/modules/portage.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "70474d22e85a3d8d191e870dce4ef4c4e0804ded42e6cb258454a313ef2f4155", + "chksum_sha256": "5c207e389af0f727d74e2402c099eaafe29afba44e9bd1fd91da053714fa38e3", "format": 1 }, { @@ -5646,7 +5667,7 @@ "name": "plugins/modules/puppet.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "853adf09fa19769befaa28faf6c986ecfe5d85890a4db71fa0a0e64f08f9ec42", + "chksum_sha256": "2e8fa36104ad52a85bcbfffadfe873b1dadf91eb5e9f5e1fe843e712ec972708", "format": 1 }, { @@ -5863,7 +5884,7 @@ "name": "plugins/modules/redfish_command.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e6875f2566585e7029e4d21f8f0dab3532c2032e95d907a248c71a4c15159f74", + "chksum_sha256": "38a449fe1a3ce5e62028e851bece4137f2f919f2ab6869f0fc23dc09dfd735f2", "format": 1 }, { @@ -5961,7 +5982,7 @@ "name": "plugins/modules/riak.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c657448de8067ae71413bf74587e2df9dedbd923b9f13ba97bc977b14b2632ed", + "chksum_sha256": "8011c6e8cd40eedbbeb157ad8cf9f069a98d59fd91cefb570dddc1f48af2ac2f", "format": 1 }, { @@ -6031,7 +6052,7 @@ "name": "plugins/modules/scaleway_compute.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "325e4bdbe81c4c280e847a290cd5b972d37ce11bb9cef0e25b152e17f4284f67", + "chksum_sha256": "cace7cc6514792ce6a84aa709fabcbc15989d722df346c60827863c6741f845d", "format": 1 }, { @@ -6087,7 +6108,7 @@ "name": "plugins/modules/scaleway_database_backup.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c4f6d4e9fffcf2964debd7d40703841b7c841bd4f3335155698b548ab7f42ad1", + "chksum_sha256": "04512a57c17deadde4b7e2eb233185d8dad896b0d75348e40f6185f2b64ef6ca", "format": 1 }, { @@ -6143,7 +6164,7 @@ "name": "plugins/modules/scaleway_lb.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c405f1d1f0e8763657353c861b5d99dbb7468c355f4723abbdba3ebdccbe33ac", + "chksum_sha256": "541e2627c7a3d18554053f9da1002b73f3d33baf61d6d381c54080f8e64752ed", "format": 1 }, { @@ -6409,7 +6430,7 @@ "name": "plugins/modules/ssh_config.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "233e53db7d3b7cdd61178d3c7b5fccb2ca8e8afff7bd3113ee116e72b7b3ecd2", + "chksum_sha256": "ec6d57292e4a58ac53f919a274a66667d570e9143016d4b6a273e2b148059ccc", "format": 1 }, { @@ -6437,7 +6458,7 @@ "name": "plugins/modules/statusio_maintenance.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "afd8833c6c9896e742a7492aca76799e42d2a2a819efc511caade8a2d2091746", + "chksum_sha256": "7b1a8122e644afafe445900e99f5a6452133fa927e3b18e5b56f19ea3d56634b", "format": 1 }, { @@ -6899,7 +6920,7 @@ "name": "plugins/modules/xml.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "801820433ca4c1410b22055ae52a7ab438787a232462e0d8125d43b180edd870", + "chksum_sha256": "a25e92ac7a5d3b78282387f8f00d08fd55b29afb4f8e6b886b86309d68f81a8e", "format": 1 }, { @@ -6966,6 +6987,20 @@ "format": 1 }, { + "name": "plugins/plugin_utils", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/plugin_utils/unsafe.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "93ccc2e18634405c7ff21a91a1df4f17261ac24b0f41bf3c46dbec2f254538c3", + "format": 1 + }, + { "name": "plugins/test", "ftype": "dir", "chksum_type": null, @@ -8950,7 +8985,7 @@ "name": "tests/integration/targets/filesystem/defaults/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "08185326e7b809ec8248cc5bf8276368f27b14a8cb0131cc2ae95676871ff8cc", + "chksum_sha256": "18cbba57e5defc719b0fe8a22a5de6bd5cc5d13ebb813adfd94379ba02e22f50", "format": 1 }, { @@ -8999,7 +9034,7 @@ "name": "tests/integration/targets/filesystem/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6a587d4489a54a86e204cbef30a808fe543fef4be6e9e9f475b22287fd2d4f58", + "chksum_sha256": "57a0f04cc772d3e0b3c958b070d15fce52c780c6caeeb908b0485406de97fa74", "format": 1 }, { @@ -9041,7 +9076,7 @@ "name": "tests/integration/targets/filesystem/tasks/setup.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "abcc4f8bf8d6df58581ff4f19e47a6afed3bcd456a7f04a66687069389c6d8a3", + "chksum_sha256": "4fb6cd4374447a8e54ea9b6cc924806b6e91cb2fdbacde34616e6c4c4113d93d", "format": 1 }, { @@ -9216,7 +9251,7 @@ "name": "tests/integration/targets/filter_from_ini/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a07f8a902771d4130fb6735fb0acff4a9f8aead0f123cb43a539406e54184a59", + "chksum_sha256": "1b8aaecd2d2f86721c17c2981cf6ab0170d1df72540f8dda076973e8fc8999ff", "format": 1 }, { @@ -9643,7 +9678,7 @@ "name": "tests/integration/targets/filter_to_ini/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7e22a177f1018cb3fb7d33f211b3d67febfdf94c4ad3a473a5b4d94ce608e696", + "chksum_sha256": "64a9ad21479d050a38d966ace64d5d43574d3dbd065cff2a02655c5eff398e65", "format": 1 }, { @@ -9776,7 +9811,7 @@ "name": "tests/integration/targets/flatpak/tasks/check_mode.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "daec12df262fbf5c01327d4ce20cb2c2c92670d222ba6164ea2b205c1e1b6166", + "chksum_sha256": "70231a939f8cd69e757fb8b5cc1e1ccf92b9a8b98359945d3ae8386a05c52152", "format": 1 }, { @@ -9797,7 +9832,7 @@ "name": "tests/integration/targets/flatpak/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "07cb037e4f5c2d08971d4af2b80d2cd6a03de40e4b41ff02779e84d002131fcd", + "chksum_sha256": "2f212b96c1d3bf7577b2d8b1cde180aac1e99f541c4d01090fbd36d43678df1d", "format": 1 }, { @@ -11957,10 +11992,17 @@ "format": 1 }, { + "name": "tests/integration/targets/ini_file/tasks/tests/08-section.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1eb82965442fa3fe06af0bdad8e66cf7d86e182b1d3b42ce613d116aec5b2df1", + "format": 1 + }, + { "name": "tests/integration/targets/ini_file/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3747adf416c4b3fa837c686860ec828985edd6a3b7e0c5993dd9da892085e7d6", + "chksum_sha256": "4e85805c4a6a145f06ef0b95dfd764becb92080deffd0be4ae5a8315ef99a60c", "format": 1 }, { @@ -13140,6 +13182,55 @@ "format": 1 }, { + "name": "tests/integration/targets/keycloak_client_rolescope", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/keycloak_client_rolescope/tasks", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/keycloak_client_rolescope/tasks/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "91f554dc3a0d7573b135d56866e499e09265fb5f3a2e7ccafe293c427f251634", + "format": 1 + }, + { + "name": "tests/integration/targets/keycloak_client_rolescope/vars", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/integration/targets/keycloak_client_rolescope/vars/main.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "69645aad3b700fb61a727383e30d7e8bbaf0a56a36e60d9013508e5b4a1d0698", + "format": 1 + }, + { + "name": "tests/integration/targets/keycloak_client_rolescope/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f643953e308b8c565cfa4514f126995c37225d1dd9b7dc6b72f1cb00de90c3aa", + "format": 1 + }, + { + "name": "tests/integration/targets/keycloak_client_rolescope/aliases", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "efa136c759c51db61ae085d265a6d6402c567e9bb00875292d45dbb00c1ed892", + "format": 1 + }, + { "name": "tests/integration/targets/keycloak_clientscope_type", "ftype": "dir", "chksum_type": null, @@ -14543,7 +14634,7 @@ "name": "tests/integration/targets/lookup_lmdb_kv/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1cedf373477c36de601ffdc2d8335d4536fa1d4927376c149a1c7c2a3fe46109", + "chksum_sha256": "f5a7ee1f47774aa767f2184faad85470c6ebe98b40b1db202f5f1acbdc72e2ea", "format": 1 }, { @@ -22408,6 +22499,20 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4aa6d180dd919a19b80a38b282923231f636556e4bf343b2cf36527d999b2124", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.18.txt.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "tests/unit", "ftype": "dir", "chksum_type": null, @@ -22600,7 +22705,7 @@ "name": "tests/unit/plugins/callback/test_loganalytics.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "45af49a11f9253655c2ae1b0ddde646ec20f4fbce8a5e8bddf468c4bb438a70c", + "chksum_sha256": "558bb03fa8ba17c60eb1afb30bb224f4b1b4c8db47a0f078a779304e3fdff713", "format": 1 }, { @@ -22614,7 +22719,7 @@ "name": "tests/unit/plugins/callback/test_splunk.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "561373bea8138ef0cc8901b4d9ce1f80ff841f3cec112a4449b89ecc49a235fd", + "chksum_sha256": "e0acc6f91db31e76594b6ec362752373167d4417033053ccf6fa6671616dc483", "format": 1 }, { @@ -22887,7 +22992,7 @@ "name": "tests/unit/plugins/lookup/test_bitwarden.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bc4558d979772df76cea11362731e59a669327b817f91be20e43f5619d1a1a22", + "chksum_sha256": "3acd0fbfd344baa81cbc868642f74e3c276164877c83cb073064459c9f873fdc", "format": 1 }, { @@ -27640,7 +27745,7 @@ "name": "CHANGELOG.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8ac8a8d20d770c47d3d6d743711f948dc353bab92ee076a1a915ea8fbb939110", + "chksum_sha256": "aa9310c1dd52b555a85d449e50a3ba1bc9de9e5a3474c66e156488463be1cc36", "format": 1 }, { @@ -27654,7 +27759,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1754aca18ee20d425f062cab756afaf70000861eb78cd1c885e2387048c87d56", + "chksum_sha256": "7192b128389810ee514466d24b34c430fd3e044eafc1db4c3b092a3a630d9985", "format": 1 }, { @@ -27682,7 +27787,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "af93da2f8ac939f7b71c6ed23caeb602a0601924282f8de07616270113c99e16", + "chksum_sha256": "980347a93d90e0b8f8507f59be3be73f0f3026521be645861f2b30880c7ee9fe", "format": 1 }, { diff --git a/ansible_collections/community/general/MANIFEST.json b/ansible_collections/community/general/MANIFEST.json index 715cd85ea..4d700a4c7 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.5.0", + "version": "8.6.0", "authors": [ "Ansible (https://github.com/ansible)" ], @@ -23,7 +23,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a5ae0318b05662e01298f7e11a607b9d674196586dfa5665caccb08b58fc5f69", + "chksum_sha256": "42be361f601f0df607b62621323c3fb70f485cd57cd2d7eecca85d6590836b01", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/general/README.md b/ansible_collections/community/general/README.md index a63ae3201..162cc06b0 100644 --- a/ansible_collections/community/general/README.md +++ b/ansible_collections/community/general/README.md @@ -24,7 +24,7 @@ If you encounter abusive behavior violating the [Ansible Code of Conduct](https: ## Tested with Ansible -Tested with the current ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16 releases and the current development version of ansible-core. Ansible-core versions before 2.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases. +Tested with the current ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, ansible-core 2.17 releases and the current development version of ansible-core. Ansible-core versions before 2.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases. ## External requirements diff --git a/ansible_collections/community/general/changelogs/changelog.yaml b/ansible_collections/community/general/changelogs/changelog.yaml index 411df6ed2..b45d41276 100644 --- a/ansible_collections/community/general/changelogs/changelog.yaml +++ b/ansible_collections/community/general/changelogs/changelog.yaml @@ -1320,3 +1320,115 @@ releases: 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 + - 8151-fix-lsvg_cmd-failed.yml + - 8153-java_cert-add-cert_content-arg.yml + - 8154-add-ovs-commands-to-nmcli-module.yml + - 8158-gitlab-version-check.yml + - 8163-redfish-implementing-reset-to-defaults.yml + - 8166-password-store-lookup-missing-subkey.yml + - 8169-lxml.yml + - 8173-osx_defaults-check_type.yml + - 8175-get_ipa_version_regex.yml + - 8183-from_ini_to_ini.yml + - 8188-bitwarden-add-organization_id.yml + - 8194-redfish-add-multipart-to-capabilities.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 + - 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 + - hipchat.yml + - puppet_lang_force.yml + modules: + - 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' diff --git a/ansible_collections/community/general/docs/docsite/config.yml b/ansible_collections/community/general/docs/docsite/config.yml new file mode 100644 index 000000000..1d6cf8554 --- /dev/null +++ b/ansible_collections/community/general/docs/docsite/config.yml @@ -0,0 +1,7 @@ +--- +# 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 + +changelog: + write_changelog: true diff --git a/ansible_collections/community/general/meta/runtime.yml b/ansible_collections/community/general/meta/runtime.yml index 4fe80ca25..a9354aab3 100644 --- a/ansible_collections/community/general/meta/runtime.yml +++ b/ansible_collections/community/general/meta/runtime.yml @@ -13,6 +13,28 @@ action_groups: - consul_session - consul_token plugin_routing: + callback: + actionable: + tombstone: + removal_version: 2.0.0 + warning_text: Use the 'default' callback plugin with 'display_skipped_hosts + = no' and 'display_ok_hosts = no' options. + full_skip: + tombstone: + removal_version: 2.0.0 + warning_text: Use the 'default' callback plugin with 'display_skipped_hosts + = no' option. + hipchat: + deprecation: + removal_version: 10.0.0 + warning_text: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. + osx_say: + redirect: community.general.say + stderr: + tombstone: + removal_version: 2.0.0 + warning_text: Use the 'default' callback plugin with 'display_failed_stderr + = yes' option. connection: docker: redirect: community.docker.docker @@ -4707,24 +4729,6 @@ plugin_routing: redirect: dellemc.openmanage.dellemc_idrac remote_management.dellemc.ome: redirect: dellemc.openmanage.ome - callback: - actionable: - tombstone: - removal_version: 2.0.0 - warning_text: Use the 'default' callback plugin with 'display_skipped_hosts - = no' and 'display_ok_hosts = no' options. - full_skip: - tombstone: - removal_version: 2.0.0 - warning_text: Use the 'default' callback plugin with 'display_skipped_hosts - = no' option. - osx_say: - redirect: community.general.say - stderr: - tombstone: - removal_version: 2.0.0 - warning_text: Use the 'default' callback plugin with 'display_failed_stderr - = yes' option. inventory: docker_machine: redirect: community.docker.docker_machine diff --git a/ansible_collections/community/general/plugins/callback/hipchat.py b/ansible_collections/community/general/plugins/callback/hipchat.py index 3e10b69e7..afd9e2055 100644 --- a/ansible_collections/community/general/plugins/callback/hipchat.py +++ b/ansible_collections/community/general/plugins/callback/hipchat.py @@ -18,6 +18,10 @@ DOCUMENTATION = ''' description: - This callback plugin sends status updates to a HipChat channel during playbook execution. - Before 2.4 only environment variables were available for configuring this plugin. + deprecated: + removed_in: 10.0.0 + why: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. + alternative: There is none. options: token: description: HipChat API token for v1 or v2 API. diff --git a/ansible_collections/community/general/plugins/callback/loganalytics.py b/ansible_collections/community/general/plugins/callback/loganalytics.py index fbcdc6f89..ed7e47b2e 100644 --- a/ansible_collections/community/general/plugins/callback/loganalytics.py +++ b/ansible_collections/community/general/plugins/callback/loganalytics.py @@ -59,13 +59,16 @@ import uuid import socket import getpass -from datetime import datetime from os.path import basename from ansible.module_utils.urls import open_url from ansible.parsing.ajson import AnsibleJSONEncoder from ansible.plugins.callback import CallbackBase +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + class AzureLogAnalyticsSource(object): def __init__(self): @@ -93,7 +96,7 @@ class AzureLogAnalyticsSource(object): return "https://{0}.ods.opinsights.azure.com/api/logs?api-version=2016-04-01".format(workspace_id) def __rfc1123date(self): - return datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') + return now().strftime('%a, %d %b %Y %H:%M:%S GMT') def send_event(self, workspace_id, shared_key, state, result, runtime): if result._task_fields['args'].get('_ansible_check_mode') is True: @@ -167,7 +170,7 @@ class CallbackModule(CallbackBase): def _seconds_since_start(self, result): return ( - datetime.utcnow() - + now() - self.start_datetimes[result._task._uuid] ).total_seconds() @@ -185,10 +188,10 @@ class CallbackModule(CallbackBase): self.loganalytics.ansible_playbook = basename(playbook._file_name) def v2_playbook_on_task_start(self, task, is_conditional): - self.start_datetimes[task._uuid] = datetime.utcnow() + self.start_datetimes[task._uuid] = now() def v2_playbook_on_handler_task_start(self, task): - self.start_datetimes[task._uuid] = datetime.utcnow() + self.start_datetimes[task._uuid] = now() def v2_runner_on_ok(self, result, **kwargs): self.loganalytics.send_event( diff --git a/ansible_collections/community/general/plugins/callback/logstash.py b/ansible_collections/community/general/plugins/callback/logstash.py index 144e1f991..f3725e465 100644 --- a/ansible_collections/community/general/plugins/callback/logstash.py +++ b/ansible_collections/community/general/plugins/callback/logstash.py @@ -99,7 +99,6 @@ from ansible import context import socket import uuid import logging -from datetime import datetime try: import logstash @@ -109,6 +108,10 @@ except ImportError: from ansible.plugins.callback import CallbackBase +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + class CallbackModule(CallbackBase): @@ -126,7 +129,7 @@ class CallbackModule(CallbackBase): "pip install python-logstash for Python 2" "pip install python3-logstash for Python 3") - self.start_time = datetime.utcnow() + self.start_time = now() def _init_plugin(self): if not self.disabled: @@ -185,7 +188,7 @@ class CallbackModule(CallbackBase): self.logger.info("ansible start", extra=data) def v2_playbook_on_stats(self, stats): - end_time = datetime.utcnow() + end_time = now() runtime = end_time - self.start_time summarize_stat = {} for host in stats.processed.keys(): diff --git a/ansible_collections/community/general/plugins/callback/splunk.py b/ansible_collections/community/general/plugins/callback/splunk.py index d15547f44..a3e401bc2 100644 --- a/ansible_collections/community/general/plugins/callback/splunk.py +++ b/ansible_collections/community/general/plugins/callback/splunk.py @@ -88,13 +88,16 @@ import uuid import socket import getpass -from datetime import datetime from os.path import basename from ansible.module_utils.urls import open_url from ansible.parsing.ajson import AnsibleJSONEncoder from ansible.plugins.callback import CallbackBase +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + class SplunkHTTPCollectorSource(object): def __init__(self): @@ -134,7 +137,7 @@ class SplunkHTTPCollectorSource(object): else: time_format = '%Y-%m-%d %H:%M:%S +0000' - data['timestamp'] = datetime.utcnow().strftime(time_format) + data['timestamp'] = now().strftime(time_format) data['host'] = self.host data['ip_address'] = self.ip_address data['user'] = self.user @@ -181,7 +184,7 @@ class CallbackModule(CallbackBase): def _runtime(self, result): return ( - datetime.utcnow() - + now() - self.start_datetimes[result._task._uuid] ).total_seconds() @@ -220,10 +223,10 @@ class CallbackModule(CallbackBase): self.splunk.ansible_playbook = basename(playbook._file_name) def v2_playbook_on_task_start(self, task, is_conditional): - self.start_datetimes[task._uuid] = datetime.utcnow() + self.start_datetimes[task._uuid] = now() def v2_playbook_on_handler_task_start(self, task): - self.start_datetimes[task._uuid] = datetime.utcnow() + self.start_datetimes[task._uuid] = now() def v2_runner_on_ok(self, result, **kwargs): self.splunk.send_event( diff --git a/ansible_collections/community/general/plugins/callback/sumologic.py b/ansible_collections/community/general/plugins/callback/sumologic.py index 46ab3f0f7..0304b9de5 100644 --- a/ansible_collections/community/general/plugins/callback/sumologic.py +++ b/ansible_collections/community/general/plugins/callback/sumologic.py @@ -46,13 +46,16 @@ import uuid import socket import getpass -from datetime import datetime from os.path import basename from ansible.module_utils.urls import open_url from ansible.parsing.ajson import AnsibleJSONEncoder from ansible.plugins.callback import CallbackBase +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + class SumologicHTTPCollectorSource(object): def __init__(self): @@ -84,8 +87,7 @@ class SumologicHTTPCollectorSource(object): data['uuid'] = result._task._uuid data['session'] = self.session data['status'] = state - data['timestamp'] = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S ' - '+0000') + data['timestamp'] = now().strftime('%Y-%m-%d %H:%M:%S +0000') data['host'] = self.host data['ip_address'] = self.ip_address data['user'] = self.user @@ -123,7 +125,7 @@ class CallbackModule(CallbackBase): def _runtime(self, result): return ( - datetime.utcnow() - + now() - self.start_datetimes[result._task._uuid] ).total_seconds() @@ -144,10 +146,10 @@ class CallbackModule(CallbackBase): self.sumologic.ansible_playbook = basename(playbook._file_name) def v2_playbook_on_task_start(self, task, is_conditional): - self.start_datetimes[task._uuid] = datetime.utcnow() + self.start_datetimes[task._uuid] = now() def v2_playbook_on_handler_task_start(self, task): - self.start_datetimes[task._uuid] = datetime.utcnow() + self.start_datetimes[task._uuid] = now() def v2_runner_on_ok(self, result, **kwargs): self.sumologic.send_event( diff --git a/ansible_collections/community/general/plugins/filter/from_ini.py b/ansible_collections/community/general/plugins/filter/from_ini.py index d68b51092..6fe83875e 100644 --- a/ansible_collections/community/general/plugins/filter/from_ini.py +++ b/ansible_collections/community/general/plugins/filter/from_ini.py @@ -57,7 +57,7 @@ class IniParser(ConfigParser): ''' Implements a configparser which is able to return a dict ''' def __init__(self): - super().__init__() + super().__init__(interpolation=None) self.optionxform = str def as_dict(self): diff --git a/ansible_collections/community/general/plugins/filter/to_ini.py b/ansible_collections/community/general/plugins/filter/to_ini.py index 22ef16d72..bdf2dde27 100644 --- a/ansible_collections/community/general/plugins/filter/to_ini.py +++ b/ansible_collections/community/general/plugins/filter/to_ini.py @@ -63,7 +63,7 @@ class IniParser(ConfigParser): ''' Implements a configparser which sets the correct optionxform ''' def __init__(self): - super().__init__() + super().__init__(interpolation=None) self.optionxform = str diff --git a/ansible_collections/community/general/plugins/inventory/cobbler.py b/ansible_collections/community/general/plugins/inventory/cobbler.py index 8ca36f426..cdef9944a 100644 --- a/ansible_collections/community/general/plugins/inventory/cobbler.py +++ b/ansible_collections/community/general/plugins/inventory/cobbler.py @@ -117,7 +117,8 @@ from ansible.errors import AnsibleError from ansible.module_utils.common.text.converters import to_text from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name from ansible.module_utils.six import text_type -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe # xmlrpc try: diff --git a/ansible_collections/community/general/plugins/inventory/gitlab_runners.py b/ansible_collections/community/general/plugins/inventory/gitlab_runners.py index 536f4bb1b..bd29e8d31 100644 --- a/ansible_collections/community/general/plugins/inventory/gitlab_runners.py +++ b/ansible_collections/community/general/plugins/inventory/gitlab_runners.py @@ -83,7 +83,8 @@ keyed_groups: from ansible.errors import AnsibleError, AnsibleParserError from ansible.module_utils.common.text.converters import to_native from ansible.plugins.inventory import BaseInventoryPlugin, Constructable -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe try: import gitlab diff --git a/ansible_collections/community/general/plugins/inventory/icinga2.py b/ansible_collections/community/general/plugins/inventory/icinga2.py index 6746bb8e0..d1f2bc617 100644 --- a/ansible_collections/community/general/plugins/inventory/icinga2.py +++ b/ansible_collections/community/general/plugins/inventory/icinga2.py @@ -102,7 +102,8 @@ from ansible.errors import AnsibleParserError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.module_utils.urls import open_url from ansible.module_utils.six.moves.urllib.error import HTTPError -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe class InventoryModule(BaseInventoryPlugin, Constructable): diff --git a/ansible_collections/community/general/plugins/inventory/linode.py b/ansible_collections/community/general/plugins/inventory/linode.py index fc79f12c5..e161e086e 100644 --- a/ansible_collections/community/general/plugins/inventory/linode.py +++ b/ansible_collections/community/general/plugins/inventory/linode.py @@ -122,7 +122,8 @@ compose: from ansible.errors import AnsibleError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe try: diff --git a/ansible_collections/community/general/plugins/inventory/lxd.py b/ansible_collections/community/general/plugins/inventory/lxd.py index c803f47dd..cf64f4ee8 100644 --- a/ansible_collections/community/general/plugins/inventory/lxd.py +++ b/ansible_collections/community/general/plugins/inventory/lxd.py @@ -175,7 +175,7 @@ from ansible.module_utils.six import raise_from from ansible.errors import AnsibleError, AnsibleParserError from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe try: import ipaddress diff --git a/ansible_collections/community/general/plugins/inventory/nmap.py b/ansible_collections/community/general/plugins/inventory/nmap.py index 3a28007a3..2ca474a1f 100644 --- a/ansible_collections/community/general/plugins/inventory/nmap.py +++ b/ansible_collections/community/general/plugins/inventory/nmap.py @@ -126,7 +126,8 @@ from ansible.errors import AnsibleParserError from ansible.module_utils.common.text.converters import to_native, to_text from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.module_utils.common.process import get_bin_path -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): diff --git a/ansible_collections/community/general/plugins/inventory/online.py b/ansible_collections/community/general/plugins/inventory/online.py index b3a9ecd37..9355d9d41 100644 --- a/ansible_collections/community/general/plugins/inventory/online.py +++ b/ansible_collections/community/general/plugins/inventory/online.py @@ -68,7 +68,8 @@ from ansible.plugins.inventory import BaseInventoryPlugin from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.ansible_release import __version__ as ansible_version from ansible.module_utils.six.moves.urllib.parse import urljoin -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe class InventoryModule(BaseInventoryPlugin): diff --git a/ansible_collections/community/general/plugins/inventory/opennebula.py b/ansible_collections/community/general/plugins/inventory/opennebula.py index 3babfa232..b097307c3 100644 --- a/ansible_collections/community/general/plugins/inventory/opennebula.py +++ b/ansible_collections/community/general/plugins/inventory/opennebula.py @@ -97,7 +97,8 @@ except ImportError: from ansible.errors import AnsibleError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.module_utils.common.text.converters import to_native -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe from collections import namedtuple import os diff --git a/ansible_collections/community/general/plugins/inventory/proxmox.py b/ansible_collections/community/general/plugins/inventory/proxmox.py index ed55ef1b6..774833c48 100644 --- a/ansible_collections/community/general/plugins/inventory/proxmox.py +++ b/ansible_collections/community/general/plugins/inventory/proxmox.py @@ -226,9 +226,9 @@ from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.six import string_types from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.utils.display import Display -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe from ansible_collections.community.general.plugins.module_utils.version import LooseVersion +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe # 3rd party imports try: diff --git a/ansible_collections/community/general/plugins/inventory/scaleway.py b/ansible_collections/community/general/plugins/inventory/scaleway.py index 601129f56..dc24a17da 100644 --- a/ansible_collections/community/general/plugins/inventory/scaleway.py +++ b/ansible_collections/community/general/plugins/inventory/scaleway.py @@ -121,10 +121,10 @@ else: from ansible.errors import AnsibleError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, parse_pagination_link +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe from ansible.module_utils.urls import open_url from ansible.module_utils.common.text.converters import to_native, to_text from ansible.module_utils.six import raise_from -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe import ansible.module_utils.six.moves.urllib.parse as urllib_parse diff --git a/ansible_collections/community/general/plugins/inventory/stackpath_compute.py b/ansible_collections/community/general/plugins/inventory/stackpath_compute.py index 9a556d39e..6b48a49f1 100644 --- a/ansible_collections/community/general/plugins/inventory/stackpath_compute.py +++ b/ansible_collections/community/general/plugins/inventory/stackpath_compute.py @@ -72,7 +72,8 @@ from ansible.plugins.inventory import ( Cacheable ) from ansible.utils.display import Display -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe display = Display() diff --git a/ansible_collections/community/general/plugins/inventory/virtualbox.py b/ansible_collections/community/general/plugins/inventory/virtualbox.py index 8604808e1..79b04ec72 100644 --- a/ansible_collections/community/general/plugins/inventory/virtualbox.py +++ b/ansible_collections/community/general/plugins/inventory/virtualbox.py @@ -62,7 +62,8 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_ from ansible.module_utils.common._collections_compat import MutableMapping from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.module_utils.common.process import get_bin_path -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe + +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): diff --git a/ansible_collections/community/general/plugins/inventory/xen_orchestra.py b/ansible_collections/community/general/plugins/inventory/xen_orchestra.py index 96dd99770..4094af246 100644 --- a/ansible_collections/community/general/plugins/inventory/xen_orchestra.py +++ b/ansible_collections/community/general/plugins/inventory/xen_orchestra.py @@ -82,9 +82,9 @@ from time import sleep from ansible.errors import AnsibleError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe from ansible_collections.community.general.plugins.module_utils.version import LooseVersion +from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe # 3rd party imports try: diff --git a/ansible_collections/community/general/plugins/lookup/bitwarden.py b/ansible_collections/community/general/plugins/lookup/bitwarden.py index 2cb2d19a1..7584cd98a 100644 --- a/ansible_collections/community/general/plugins/lookup/bitwarden.py +++ b/ansible_collections/community/general/plugins/lookup/bitwarden.py @@ -29,7 +29,7 @@ DOCUMENTATION = """ - Field to retrieve, for example V(name) or V(id). - If set to V(id), only zero or one element can be returned. Use the Jinja C(first) filter to get the only list element. - - When O(collection_id) is set, this field can be undefined to retrieve the whole collection records. + - If set to V(None) or V(''), or if O(_terms) is empty, records are not filtered by fields. type: str default: name version_added: 5.7.0 @@ -40,6 +40,10 @@ DOCUMENTATION = """ description: Collection ID to filter results by collection. Leave unset to skip filtering. type: str version_added: 6.3.0 + organization_id: + description: Organization ID to filter results by organization. Leave unset to skip filtering. + type: str + version_added: 8.5.0 bw_session: description: Pass session key instead of reading from env. type: str @@ -142,45 +146,44 @@ class Bitwarden(object): raise BitwardenException(err) return to_text(out, errors='surrogate_or_strict'), to_text(err, errors='surrogate_or_strict') - def _get_matches(self, search_value, search_field, collection_id=None): + def _get_matches(self, search_value, search_field, collection_id=None, organization_id=None): """Return matching records whose search_field is equal to key. """ # Prepare set of params for Bitwarden CLI - if search_value: - if search_field == 'id': - params = ['get', 'item', search_value] - else: - params = ['list', 'items', '--search', search_value] - if collection_id: - params.extend(['--collectionid', collection_id]) + if search_field == 'id': + params = ['get', 'item', search_value] else: - if not collection_id: - raise AnsibleError("search_value is required if collection_id is not set.") + params = ['list', 'items'] + if search_value: + params.extend(['--search', search_value]) - params = ['list', 'items', '--collectionid', collection_id] + if collection_id: + params.extend(['--collectionid', collection_id]) + if organization_id: + params.extend(['--organizationid', organization_id]) out, err = self._run(params) # This includes things that matched in different fields. initial_matches = AnsibleJSONDecoder().raw_decode(out)[0] - if search_field == 'id' or not search_value: + if search_field == 'id': if initial_matches is None: initial_matches = [] else: initial_matches = [initial_matches] # Filter to only include results from the right field. - return [item for item in initial_matches if item[search_field] == search_value] + return [item for item in initial_matches if not search_value or item[search_field] == search_value] - def get_field(self, field, search_value=None, search_field="name", collection_id=None): + def get_field(self, field, search_value, search_field="name", collection_id=None, organization_id=None): """Return a list of the specified field for records whose search_field match search_value and filtered by collection if collection has been provided. If field is None, return the whole record for each match. """ - matches = self._get_matches(search_value, search_field, collection_id) + matches = self._get_matches(search_value, search_field, collection_id, organization_id) if not field: return matches field_matches = [] @@ -215,15 +218,16 @@ class LookupModule(LookupBase): field = self.get_option('field') search_field = self.get_option('search') collection_id = self.get_option('collection_id') + organization_id = self.get_option('organization_id') _bitwarden.session = self.get_option('bw_session') if not _bitwarden.unlocked: raise AnsibleError("Bitwarden Vault locked. Run 'bw unlock'.") if not terms: - return [_bitwarden.get_field(field, None, search_field, collection_id)] + terms = [None] - return [_bitwarden.get_field(field, term, search_field, collection_id) for term in terms] + return [_bitwarden.get_field(field, term, search_field, collection_id, organization_id) for term in terms] _bitwarden = Bitwarden() diff --git a/ansible_collections/community/general/plugins/lookup/bitwarden_secrets_manager.py b/ansible_collections/community/general/plugins/lookup/bitwarden_secrets_manager.py index 2d6706bee..8cabc693f 100644 --- a/ansible_collections/community/general/plugins/lookup/bitwarden_secrets_manager.py +++ b/ansible_collections/community/general/plugins/lookup/bitwarden_secrets_manager.py @@ -70,6 +70,7 @@ RETURN = """ """ from subprocess import Popen, PIPE +from time import sleep from ansible.errors import AnsibleLookupError from ansible.module_utils.common.text.converters import to_text @@ -84,11 +85,29 @@ class BitwardenSecretsManagerException(AnsibleLookupError): class BitwardenSecretsManager(object): def __init__(self, path='bws'): self._cli_path = path + self._max_retries = 3 + self._retry_delay = 1 @property def cli_path(self): return self._cli_path + def _run_with_retry(self, args, stdin=None, retries=0): + out, err, rc = self._run(args, stdin) + + if rc != 0: + if retries >= self._max_retries: + raise BitwardenSecretsManagerException("Max retries exceeded. Unable to retrieve secret.") + + if "Too many requests" in err: + delay = self._retry_delay * (2 ** retries) + sleep(delay) + return self._run_with_retry(args, stdin, retries + 1) + else: + raise BitwardenSecretsManagerException(f"Command failed with return code {rc}: {err}") + + return out, err, rc + def _run(self, args, stdin=None): p = Popen([self.cli_path] + args, stdout=PIPE, stderr=PIPE, stdin=PIPE) out, err = p.communicate(stdin) @@ -107,7 +126,7 @@ class BitwardenSecretsManager(object): 'get', 'secret', secret_id ] - out, err, rc = self._run(params) + out, err, rc = self._run_with_retry(params) if rc != 0: raise BitwardenSecretsManagerException(to_text(err)) diff --git a/ansible_collections/community/general/plugins/lookup/passwordstore.py b/ansible_collections/community/general/plugins/lookup/passwordstore.py index 7a6fca7a0..9814fe133 100644 --- a/ansible_collections/community/general/plugins/lookup/passwordstore.py +++ b/ansible_collections/community/general/plugins/lookup/passwordstore.py @@ -139,6 +139,21 @@ DOCUMENTATION = ''' type: bool default: true version_added: 8.1.0 + missing_subkey: + description: + - Preference about what to do if the password subkey is missing. + - If set to V(error), the lookup will error out if the subkey does not exist. + - If set to V(empty) or V(warn), will return a V(none) in case the subkey does not exist. + version_added: 8.6.0 + type: str + default: empty + choices: + - error + - warn + - empty + ini: + - section: passwordstore_lookup + key: missing_subkey notes: - The lookup supports passing all options as lookup parameters since community.general 6.0.0. ''' @@ -147,6 +162,7 @@ ansible.cfg: | [passwordstore_lookup] lock=readwrite locktimeout=45s + missing_subkey=warn tasks.yml: | --- @@ -432,6 +448,20 @@ class LookupModule(LookupBase): if self.paramvals['subkey'] in self.passdict: return self.passdict[self.paramvals['subkey']] else: + if self.paramvals["missing_subkey"] == "error": + raise AnsibleError( + "passwordstore: subkey {0} for passname {1} not found and missing_subkey=error is set".format( + self.paramvals["subkey"], self.passname + ) + ) + + if self.paramvals["missing_subkey"] == "warn": + display.warning( + "passwordstore: subkey {0} for passname {1} not found".format( + self.paramvals["subkey"], self.passname + ) + ) + return None @contextmanager @@ -481,6 +511,7 @@ class LookupModule(LookupBase): 'umask': self.get_option('umask'), 'timestamp': self.get_option('timestamp'), 'preserve': self.get_option('preserve'), + "missing_subkey": self.get_option("missing_subkey"), } def run(self, terms, variables, **kwargs): diff --git a/ansible_collections/community/general/plugins/module_utils/datetime.py b/ansible_collections/community/general/plugins/module_utils/datetime.py new file mode 100644 index 000000000..c7899f68d --- /dev/null +++ b/ansible_collections/community/general/plugins/module_utils/datetime.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2023 Felix Fontein <felix@fontein.de> +# 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 datetime as _datetime +import sys + + +_USE_TIMEZONE = sys.version_info >= (3, 6) + + +def ensure_timezone_info(value): + if not _USE_TIMEZONE or value.tzinfo is not None: + return value + return value.astimezone(_datetime.timezone.utc) + + +def fromtimestamp(value): + if _USE_TIMEZONE: + return _datetime.fromtimestamp(value, tz=_datetime.timezone.utc) + return _datetime.utcfromtimestamp(value) + + +def now(): + if _USE_TIMEZONE: + return _datetime.datetime.now(tz=_datetime.timezone.utc) + return _datetime.datetime.utcnow() diff --git a/ansible_collections/community/general/plugins/module_utils/gitlab.py b/ansible_collections/community/general/plugins/module_utils/gitlab.py index f9872b877..b1354d8a9 100644 --- a/ansible_collections/community/general/plugins/module_utils/gitlab.py +++ b/ansible_collections/community/general/plugins/module_utils/gitlab.py @@ -81,16 +81,23 @@ def find_group(gitlab_instance, identifier): return group -def ensure_gitlab_package(module): +def ensure_gitlab_package(module, min_version=None): if not HAS_GITLAB_PACKAGE: module.fail_json( msg=missing_required_lib("python-gitlab", url='https://python-gitlab.readthedocs.io/en/stable/'), exception=GITLAB_IMP_ERR ) + gitlab_version = gitlab.__version__ + if min_version is not None and LooseVersion(gitlab_version) < LooseVersion(min_version): + module.fail_json( + msg="This module requires python-gitlab Python module >= %s " + "(installed version: %s). Please upgrade python-gitlab to version %s or above." + % (min_version, gitlab_version, min_version) + ) -def gitlab_authentication(module): - ensure_gitlab_package(module) +def gitlab_authentication(module, min_version=None): + ensure_gitlab_package(module, min_version=min_version) gitlab_url = module.params['api_url'] validate_certs = module.params['validate_certs'] diff --git a/ansible_collections/community/general/plugins/module_utils/identity/keycloak/keycloak.py b/ansible_collections/community/general/plugins/module_utils/identity/keycloak/keycloak.py index 9e1c3f4d9..b2a189250 100644 --- a/ansible_collections/community/general/plugins/module_utils/identity/keycloak/keycloak.py +++ b/ansible_collections/community/general/plugins/module_utils/identity/keycloak/keycloak.py @@ -28,6 +28,9 @@ URL_CLIENT_ROLES = "{url}/admin/realms/{realm}/clients/{id}/roles" URL_CLIENT_ROLE = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}" URL_CLIENT_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}/composites" +URL_CLIENT_ROLE_SCOPE_CLIENTS = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/clients/{scopeid}" +URL_CLIENT_ROLE_SCOPE_REALM = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/realm" + URL_REALM_ROLES = "{url}/admin/realms/{realm}/roles" URL_REALM_ROLE = "{url}/admin/realms/{realm}/roles/{name}" URL_REALM_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm" @@ -3049,6 +3052,105 @@ class KeycloakAPI(object): except Exception: return False + def get_client_role_scope_from_client(self, clientid, clientscopeid, realm="master"): + """ Fetch the roles associated with the client's scope for a specific client on the Keycloak server. + :param clientid: ID of the client from which to obtain the associated roles. + :param clientscopeid: ID of the client who owns the roles. + :param realm: Realm from which to obtain the scope. + :return: The client scope of roles from specified client. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid) + try: + return json.loads(to_native(open_url(client_role_scope_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg='Could not fetch roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + def update_client_role_scope_from_client(self, payload, clientid, clientscopeid, realm="master"): + """ Update and fetch the roles associated with the client's scope on the Keycloak server. + :param payload: List of roles to be added to the scope. + :param clientid: ID of the client to update scope. + :param clientscopeid: ID of the client who owns the roles. + :param realm: Realm from which to obtain the clients. + :return: The client scope of roles from specified client. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid) + try: + open_url(client_role_scope_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not update roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_client(clientid, clientscopeid, realm) + + def delete_client_role_scope_from_client(self, payload, clientid, clientscopeid, realm="master"): + """ Delete the roles contains in the payload from the client's scope on the Keycloak server. + :param payload: List of roles to be deleted. + :param clientid: ID of the client to delete roles from scope. + :param clientscopeid: ID of the client who owns the roles. + :param realm: Realm from which to obtain the clients. + :return: The client scope of roles from specified client. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid) + try: + open_url(client_role_scope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not delete roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_client(clientid, clientscopeid, realm) + + def get_client_role_scope_from_realm(self, clientid, realm="master"): + """ Fetch the realm roles from the client's scope on the Keycloak server. + :param clientid: ID of the client from which to obtain the associated realm roles. + :param realm: Realm from which to obtain the clients. + :return: The client realm roles scope. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid) + try: + return json.loads(to_native(open_url(client_role_scope_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg='Could not fetch roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + def update_client_role_scope_from_realm(self, payload, clientid, realm="master"): + """ Update and fetch the realm roles from the client's scope on the Keycloak server. + :param payload: List of realm roles to add. + :param clientid: ID of the client to update scope. + :param realm: Realm from which to obtain the clients. + :return: The client realm roles scope. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid) + try: + open_url(client_role_scope_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not update roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_realm(clientid, realm) + + def delete_client_role_scope_from_realm(self, payload, clientid, realm="master"): + """ Delete the realm roles contains in the payload from the client's scope on the Keycloak server. + :param payload: List of realm roles to delete. + :param clientid: ID of the client to delete roles from scope. + :param realm: Realm from which to obtain the clients. + :return: The client realm roles scope. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid) + try: + open_url(client_role_scope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not delete roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_realm(clientid, realm) + def fail_open_url(self, e, msg, **kwargs): try: if isinstance(e, HTTPError): diff --git a/ansible_collections/community/general/plugins/module_utils/ipa.py b/ansible_collections/community/general/plugins/module_utils/ipa.py index eda9b4132..fb63d5556 100644 --- a/ansible_collections/community/general/plugins/module_utils/ipa.py +++ b/ansible_collections/community/general/plugins/module_utils/ipa.py @@ -104,7 +104,7 @@ class IPAClient(object): def get_ipa_version(self): response = self.ping()['summary'] - ipa_ver_regex = re.compile(r'IPA server version (\d\.\d\.\d).*') + ipa_ver_regex = re.compile(r'IPA server version (\d+\.\d+\.\d+).*') version_match = ipa_ver_regex.match(response) ipa_version = None if version_match: diff --git a/ansible_collections/community/general/plugins/module_utils/puppet.py b/ansible_collections/community/general/plugins/module_utils/puppet.py index 8d553a2d2..f05b0673f 100644 --- a/ansible_collections/community/general/plugins/module_utils/puppet.py +++ b/ansible_collections/community/general/plugins/module_utils/puppet.py @@ -107,5 +107,6 @@ def puppet_runner(module): verbose=cmd_runner_fmt.as_bool("--verbose"), ), check_rc=False, + force_lang=module.params["environment_lang"], ) return runner diff --git a/ansible_collections/community/general/plugins/module_utils/redfish_utils.py b/ansible_collections/community/general/plugins/module_utils/redfish_utils.py index 4c2057129..6935573d0 100644 --- a/ansible_collections/community/general/plugins/module_utils/redfish_utils.py +++ b/ansible_collections/community/general/plugins/module_utils/redfish_utils.py @@ -1149,6 +1149,54 @@ class RedfishUtils(object): return response return {'ret': True, 'changed': True} + def manager_reset_to_defaults(self, command): + return self.reset_to_defaults(command, self.manager_uri, + '#Manager.ResetToDefaults') + + def reset_to_defaults(self, command, resource_uri, action_name): + key = "Actions" + reset_type_values = ['ResetAll', + 'PreserveNetworkAndUsers', + 'PreserveNetwork'] + + if command not in reset_type_values: + return {'ret': False, 'msg': 'Invalid Command (%s)' % command} + + # read the resource and get the current power state + response = self.get_request(self.root_uri + resource_uri) + if response['ret'] is False: + return response + data = response['data'] + + # get the reset Action and target URI + if key not in data or action_name not in data[key]: + return {'ret': False, 'msg': 'Action %s not found' % action_name} + reset_action = data[key][action_name] + if 'target' not in reset_action: + return {'ret': False, + 'msg': 'target URI missing from Action %s' % action_name} + action_uri = reset_action['target'] + + # get AllowableValues + ai = self._get_all_action_info_values(reset_action) + allowable_values = ai.get('ResetType', {}).get('AllowableValues', []) + + # map ResetType to an allowable value if needed + if allowable_values and command not in allowable_values: + return {'ret': False, + 'msg': 'Specified reset type (%s) not supported ' + 'by service. Supported types: %s' % + (command, allowable_values)} + + # define payload + payload = {'ResetType': command} + + # POST to Action URI + response = self.post_request(self.root_uri + action_uri, payload) + if response['ret'] is False: + return response + return {'ret': True, 'changed': True} + def _find_account_uri(self, username=None, acct_id=None): if not any((username, acct_id)): return {'ret': False, 'msg': @@ -1549,6 +1597,8 @@ class RedfishUtils(object): data = response['data'] + result['multipart_supported'] = 'MultipartHttpPushUri' in data + if "Actions" in data: actions = data['Actions'] if len(actions) > 0: diff --git a/ansible_collections/community/general/plugins/module_utils/scaleway.py b/ansible_collections/community/general/plugins/module_utils/scaleway.py index 67b821103..1310ba560 100644 --- a/ansible_collections/community/general/plugins/module_utils/scaleway.py +++ b/ansible_collections/community/general/plugins/module_utils/scaleway.py @@ -17,6 +17,10 @@ from ansible.module_utils.basic import env_fallback, missing_required_lib from ansible.module_utils.urls import fetch_url from ansible.module_utils.six.moves.urllib.parse import urlencode +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + SCALEWAY_SECRET_IMP_ERR = None try: from passlib.hash import argon2 @@ -306,10 +310,10 @@ class Scaleway(object): # Prevent requesting the resource status too soon time.sleep(wait_sleep_time) - start = datetime.datetime.utcnow() + start = now() end = start + datetime.timedelta(seconds=wait_timeout) - while datetime.datetime.utcnow() < end: + while now() < end: self.module.debug("We are going to wait for the resource to finish its transition") state = self.fetch_state(resource) diff --git a/ansible_collections/community/general/plugins/modules/aix_filesystem.py b/ansible_collections/community/general/plugins/modules/aix_filesystem.py index 6abf6317f..4a3775c67 100644 --- a/ansible_collections/community/general/plugins/modules/aix_filesystem.py +++ b/ansible_collections/community/general/plugins/modules/aix_filesystem.py @@ -242,7 +242,7 @@ def _validate_vg(module, vg): if rc != 0: module.fail_json(msg="Failed executing %s command." % lsvg_cmd) - rc, current_all_vgs, err = module.run_command([lsvg_cmd, "%s"]) + rc, current_all_vgs, err = module.run_command([lsvg_cmd]) if rc != 0: module.fail_json(msg="Failed executing %s command." % lsvg_cmd) diff --git a/ansible_collections/community/general/plugins/modules/apt_rpm.py b/ansible_collections/community/general/plugins/modules/apt_rpm.py index de1b57411..03b87e78f 100644 --- a/ansible_collections/community/general/plugins/modules/apt_rpm.py +++ b/ansible_collections/community/general/plugins/modules/apt_rpm.py @@ -37,7 +37,17 @@ options: state: description: - Indicates the desired package state. - choices: [ absent, present, installed, removed ] + - Please note that V(present) and V(installed) are equivalent to V(latest) right now. + This will change in the future. To simply ensure that a package is installed, without upgrading + it, use the V(present_not_latest) state. + - The states V(latest) and V(present_not_latest) have been added in community.general 8.6.0. + choices: + - absent + - present + - present_not_latest + - installed + - removed + - latest default: present type: str update_cache: @@ -180,7 +190,7 @@ def check_package_version(module, name): return False -def query_package_provides(module, name): +def query_package_provides(module, name, allow_upgrade=False): # rpm -q returns 0 if the package is installed, # 1 if it is not installed if name.endswith('.rpm'): @@ -195,10 +205,11 @@ def query_package_provides(module, name): rc, out, err = module.run_command("%s -q --provides %s" % (RPM_PATH, name)) if rc == 0: + if not allow_upgrade: + return True if check_package_version(module, name): return True - else: - return False + return False def update_package_db(module): @@ -255,14 +266,14 @@ def remove_packages(module, packages): return (False, "package(s) already absent") -def install_packages(module, pkgspec): +def install_packages(module, pkgspec, allow_upgrade=False): if pkgspec is None: return (False, "Empty package list") packages = "" for package in pkgspec: - if not query_package_provides(module, package): + if not query_package_provides(module, package, allow_upgrade=allow_upgrade): packages += "'%s' " % package if len(packages) != 0: @@ -270,8 +281,8 @@ def install_packages(module, pkgspec): rc, out, err = module.run_command("%s -y install %s" % (APT_PATH, packages), environ_update={"LANG": "C"}) installed = True - for packages in pkgspec: - if not query_package_provides(module, package): + for package in pkgspec: + if not query_package_provides(module, package, allow_upgrade=False): installed = False # apt-rpm always have 0 for exit code if --force is used @@ -286,7 +297,7 @@ def install_packages(module, pkgspec): def main(): module = AnsibleModule( argument_spec=dict( - state=dict(type='str', default='present', choices=['absent', 'installed', 'present', 'removed']), + state=dict(type='str', default='present', choices=['absent', 'installed', 'present', 'removed', 'present_not_latest', 'latest']), update_cache=dict(type='bool', default=False), clean=dict(type='bool', default=False), dist_upgrade=dict(type='bool', default=False), @@ -320,8 +331,8 @@ def main(): output += out packages = p['package'] - if p['state'] in ['installed', 'present']: - (m, out) = install_packages(module, packages) + if p['state'] in ['installed', 'present', 'present_not_latest', 'latest']: + (m, out) = install_packages(module, packages, allow_upgrade=p['state'] != 'present_not_latest') modified = modified or m output += out diff --git a/ansible_collections/community/general/plugins/modules/cobbler_sync.py b/ansible_collections/community/general/plugins/modules/cobbler_sync.py index 4ec87c96c..27f57028b 100644 --- a/ansible_collections/community/general/plugins/modules/cobbler_sync.py +++ b/ansible_collections/community/general/plugins/modules/cobbler_sync.py @@ -75,13 +75,16 @@ RETURN = r''' # Default return values ''' -import datetime import ssl from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six.moves import xmlrpc_client from ansible.module_utils.common.text.converters import to_text +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + def main(): module = AnsibleModule( @@ -110,7 +113,7 @@ def main(): changed=True, ) - start = datetime.datetime.utcnow() + start = now() ssl_context = None if not validate_certs: @@ -142,7 +145,7 @@ def main(): except Exception as e: module.fail_json(msg="Failed to sync Cobbler. {error}".format(error=to_text(e))) - elapsed = datetime.datetime.utcnow() - start + elapsed = now() - start module.exit_json(elapsed=elapsed.seconds, **result) diff --git a/ansible_collections/community/general/plugins/modules/cobbler_system.py b/ansible_collections/community/general/plugins/modules/cobbler_system.py index cecc02f71..a327ede84 100644 --- a/ansible_collections/community/general/plugins/modules/cobbler_system.py +++ b/ansible_collections/community/general/plugins/modules/cobbler_system.py @@ -152,7 +152,6 @@ system: type: dict ''' -import datetime import ssl from ansible.module_utils.basic import AnsibleModule @@ -160,6 +159,10 @@ from ansible.module_utils.six import iteritems from ansible.module_utils.six.moves import xmlrpc_client from ansible.module_utils.common.text.converters import to_text +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + IFPROPS_MAPPING = dict( bondingopts='bonding_opts', bridgeopts='bridge_opts', @@ -232,7 +235,7 @@ def main(): changed=False, ) - start = datetime.datetime.utcnow() + start = now() ssl_context = None if not validate_certs: @@ -340,7 +343,7 @@ def main(): if module._diff: result['diff'] = dict(before=system, after=result['system']) - elapsed = datetime.datetime.utcnow() - start + elapsed = now() - start module.exit_json(elapsed=elapsed.seconds, **result) diff --git a/ansible_collections/community/general/plugins/modules/filesystem.py b/ansible_collections/community/general/plugins/modules/filesystem.py index ec361245b..73e8c79c6 100644 --- a/ansible_collections/community/general/plugins/modules/filesystem.py +++ b/ansible_collections/community/general/plugins/modules/filesystem.py @@ -40,11 +40,12 @@ options: default: present version_added: 1.3.0 fstype: - choices: [ btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap, ufs ] + choices: [ bcachefs, btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap, ufs ] description: - Filesystem type to be created. This option is required with O(state=present) (or if O(state) is omitted). - ufs support has been added in community.general 3.4.0. + - bcachefs support has been added in community.general 8.6.0. type: str aliases: [type] dev: @@ -67,7 +68,7 @@ options: resizefs: description: - If V(true), if the block device and filesystem size differ, grow the filesystem into the space. - - Supported for C(btrfs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs), C(ufs) and C(vfat) filesystems. + - Supported for C(bcachefs), C(btrfs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs), C(ufs) and C(vfat) filesystems. Attempts to resize other filesystem types will fail. - XFS Will only grow if mounted. Currently, the module is based on commands from C(util-linux) package to perform operations, so resizing of XFS is @@ -86,7 +87,7 @@ options: - The UUID options specified in O(opts) take precedence over this value. - See xfs_admin(8) (C(xfs)), tune2fs(8) (C(ext2), C(ext3), C(ext4), C(ext4dev)) for possible values. - For O(fstype=lvm) the value is ignored, it resets the PV UUID if set. - - Supported for O(fstype) being one of C(ext2), C(ext3), C(ext4), C(ext4dev), C(lvm), or C(xfs). + - Supported for O(fstype) being one of C(bcachefs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(lvm), or C(xfs). - This is B(not idempotent). Specifying this option will always result in a change. - Mutually exclusive with O(resizefs). type: str @@ -405,6 +406,48 @@ class Reiserfs(Filesystem): MKFS_FORCE_FLAGS = ['-q'] +class Bcachefs(Filesystem): + MKFS = 'mkfs.bcachefs' + MKFS_FORCE_FLAGS = ['--force'] + MKFS_SET_UUID_OPTIONS = ['-U', '--uuid'] + INFO = 'bcachefs' + GROW = 'bcachefs' + GROW_MAX_SPACE_FLAGS = ['device', 'resize'] + + def get_fs_size(self, dev): + """Return size in bytes of filesystem on device (integer).""" + dummy, stdout, dummy = self.module.run_command([self.module.get_bin_path(self.INFO), + 'show-super', str(dev)], check_rc=True) + + for line in stdout.splitlines(): + if "Size: " in line: + parts = line.split() + unit = parts[2] + + base = None + exp = None + + units_2 = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"] + units_10 = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] + + try: + exp = units_2.index(unit) + base = 1024 + except ValueError: + exp = units_10.index(unit) + base = 1000 + + if exp == 0: + value = int(parts[1]) + else: + value = float(parts[1]) + + if base is not None and exp is not None: + return int(value * pow(base, exp)) + + raise ValueError(repr(stdout)) + + class Btrfs(Filesystem): MKFS = 'mkfs.btrfs' INFO = 'btrfs' @@ -567,6 +610,7 @@ class UFS(Filesystem): FILESYSTEMS = { + 'bcachefs': Bcachefs, 'ext2': Ext2, 'ext3': Ext3, 'ext4': Ext4, diff --git a/ansible_collections/community/general/plugins/modules/flatpak.py b/ansible_collections/community/general/plugins/modules/flatpak.py index 80dbabdfa..15e404d45 100644 --- a/ansible_collections/community/general/plugins/modules/flatpak.py +++ b/ansible_collections/community/general/plugins/modules/flatpak.py @@ -26,7 +26,9 @@ extends_documentation_fragment: - community.general.attributes attributes: check_mode: - support: full + support: partial + details: + - If O(state=latest), the module will always return C(changed=true). diff_mode: support: none options: @@ -53,12 +55,12 @@ options: - Both C(https://) and C(http://) URLs are supported. - When supplying a reverse DNS name, you can use the O(remote) option to specify on what remote to look for the flatpak. An example for a reverse DNS name is C(org.gnome.gedit). - - When used with O(state=absent), it is recommended to specify the name in the reverse DNS - format. - - When supplying a URL with O(state=absent), the module will try to match the - installed flatpak based on the name of the flatpakref to remove it. However, there is no - guarantee that the names of the flatpakref file and the reverse DNS name of the installed - flatpak do match. + - When used with O(state=absent) or O(state=latest), it is recommended to specify the name in + the reverse DNS format. + - When supplying a URL with O(state=absent) or O(state=latest), the module will try to match the + installed flatpak based on the name of the flatpakref to remove or update it. However, there + is no guarantee that the names of the flatpakref file and the reverse DNS name of the + installed flatpak do match. type: list elements: str required: true @@ -82,7 +84,8 @@ options: state: description: - Indicates the desired package state. - choices: [ absent, present ] + - The value V(latest) is supported since community.general 8.6.0. + choices: [ absent, present, latest ] type: str default: present ''' @@ -118,6 +121,37 @@ EXAMPLES = r''' - org.inkscape.Inkscape - org.mozilla.firefox +- name: Update the spotify flatpak + community.general.flatpak: + name: https://s3.amazonaws.com/alexlarsson/spotify-repo/spotify.flatpakref + state: latest + +- name: Update the gedit flatpak package without dependencies (not recommended) + community.general.flatpak: + name: https://git.gnome.org/browse/gnome-apps-nightly/plain/gedit.flatpakref + state: latest + no_dependencies: true + +- name: Update the gedit package from flathub for current user + community.general.flatpak: + name: org.gnome.gedit + state: latest + method: user + +- name: Update the Gnome Calendar flatpak from the gnome remote system-wide + community.general.flatpak: + name: org.gnome.Calendar + state: latest + remote: gnome + +- name: Update multiple packages + community.general.flatpak: + name: + - org.gimp.GIMP + - org.inkscape.Inkscape + - org.mozilla.firefox + state: latest + - name: Remove the gedit flatpak community.general.flatpak: name: org.gnome.gedit @@ -195,6 +229,28 @@ def install_flat(module, binary, remote, names, method, no_dependencies): result['changed'] = True +def update_flat(module, binary, names, method, no_dependencies): + """Update existing flatpaks.""" + global result # pylint: disable=global-variable-not-assigned + installed_flat_names = [ + _match_installed_flat_name(module, binary, name, method) + for name in names + ] + command = [binary, "update", "--{0}".format(method)] + flatpak_version = _flatpak_version(module, binary) + if LooseVersion(flatpak_version) < LooseVersion('1.1.3'): + command += ["-y"] + else: + command += ["--noninteractive"] + if no_dependencies: + command += ["--no-deps"] + command += installed_flat_names + stdout = _flatpak_command(module, module.check_mode, command) + result["changed"] = ( + True if module.check_mode else stdout.find("Nothing to do.") == -1 + ) + + def uninstall_flat(module, binary, names, method): """Remove existing flatpaks.""" global result # pylint: disable=global-variable-not-assigned @@ -313,7 +369,7 @@ def main(): method=dict(type='str', default='system', choices=['user', 'system']), state=dict(type='str', default='present', - choices=['absent', 'present']), + choices=['absent', 'present', 'latest']), no_dependencies=dict(type='bool', default=False), executable=dict(type='path', default='flatpak') ), @@ -338,10 +394,13 @@ def main(): module.fail_json(msg="Executable '%s' was not found on the system." % executable, **result) installed, not_installed = flatpak_exists(module, binary, name, method) - if state == 'present' and not_installed: - install_flat(module, binary, remote, not_installed, method, no_dependencies) - elif state == 'absent' and installed: + if state == 'absent' and installed: uninstall_flat(module, binary, installed, method) + else: + if state == 'latest' and installed: + update_flat(module, binary, installed, method, no_dependencies) + if state in ('present', 'latest') and not_installed: + install_flat(module, binary, remote, not_installed, method, no_dependencies) module.exit_json(**result) diff --git a/ansible_collections/community/general/plugins/modules/github_key.py b/ansible_collections/community/general/plugins/modules/github_key.py index fa3a0a01f..a74ead984 100644 --- a/ansible_collections/community/general/plugins/modules/github_key.py +++ b/ansible_collections/community/general/plugins/modules/github_key.py @@ -91,12 +91,17 @@ EXAMPLES = ''' pubkey: "{{ lookup('ansible.builtin.file', '/home/foo/.ssh/id_rsa.pub') }}" ''' +import datetime import json import re from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import fetch_url +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + API_BASE = 'https://api.github.com' @@ -151,14 +156,13 @@ def get_all_keys(session): def create_key(session, name, pubkey, check_mode): if check_mode: - from datetime import datetime - now = datetime.utcnow() + now_t = now() return { 'id': 0, 'key': pubkey, 'title': name, 'url': 'http://example.com/CHECK_MODE_GITHUB_KEY', - 'created_at': datetime.strftime(now, '%Y-%m-%dT%H:%M:%SZ'), + 'created_at': datetime.strftime(now_t, '%Y-%m-%dT%H:%M:%SZ'), 'read_only': False, 'verified': False } diff --git a/ansible_collections/community/general/plugins/modules/gitlab_issue.py b/ansible_collections/community/general/plugins/modules/gitlab_issue.py index 6d95bf6cf..3277c4f1a 100644 --- a/ansible_collections/community/general/plugins/modules/gitlab_issue.py +++ b/ansible_collections/community/general/plugins/modules/gitlab_issue.py @@ -143,7 +143,6 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.api import basic_auth_argument_spec from ansible.module_utils.common.text.converters import to_native, to_text -from ansible_collections.community.general.plugins.module_utils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.gitlab import ( auth_argument_spec, gitlab_authentication, gitlab, find_project, find_group ) @@ -330,13 +329,8 @@ def main(): state_filter = module.params['state_filter'] title = module.params['title'] - gitlab_version = gitlab.__version__ - if LooseVersion(gitlab_version) < LooseVersion('2.3.0'): - module.fail_json(msg="community.general.gitlab_issue requires python-gitlab Python module >= 2.3.0 (installed version: [%s])." - " Please upgrade python-gitlab to version 2.3.0 or above." % gitlab_version) - # check prerequisites and connect to gitlab server - gitlab_instance = gitlab_authentication(module) + gitlab_instance = gitlab_authentication(module, min_version='2.3.0') this_project = find_project(gitlab_instance, project) if this_project is None: diff --git a/ansible_collections/community/general/plugins/modules/gitlab_label.py b/ansible_collections/community/general/plugins/modules/gitlab_label.py index f2c8393f2..635033ab6 100644 --- a/ansible_collections/community/general/plugins/modules/gitlab_label.py +++ b/ansible_collections/community/general/plugins/modules/gitlab_label.py @@ -222,9 +222,8 @@ labels_obj: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.api import basic_auth_argument_spec -from ansible_collections.community.general.plugins.module_utils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.gitlab import ( - auth_argument_spec, gitlab_authentication, ensure_gitlab_package, find_group, find_project, gitlab + auth_argument_spec, gitlab_authentication, ensure_gitlab_package, find_group, find_project ) @@ -450,14 +449,7 @@ def main(): label_list = module.params['labels'] state = module.params['state'] - gitlab_version = gitlab.__version__ - _min_gitlab = '3.2.0' - if LooseVersion(gitlab_version) < LooseVersion(_min_gitlab): - module.fail_json(msg="community.general.gitlab_label requires python-gitlab Python module >= %s " - "(installed version: [%s]). Please upgrade " - "python-gitlab to version %s or above." % (_min_gitlab, gitlab_version, _min_gitlab)) - - gitlab_instance = gitlab_authentication(module) + gitlab_instance = gitlab_authentication(module, min_version='3.2.0') # find_project can return None, but the other must exist gitlab_project_id = find_project(gitlab_instance, gitlab_project) diff --git a/ansible_collections/community/general/plugins/modules/gitlab_milestone.py b/ansible_collections/community/general/plugins/modules/gitlab_milestone.py index 0a616ea47..4b8b933cc 100644 --- a/ansible_collections/community/general/plugins/modules/gitlab_milestone.py +++ b/ansible_collections/community/general/plugins/modules/gitlab_milestone.py @@ -206,9 +206,8 @@ milestones_obj: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.api import basic_auth_argument_spec -from ansible_collections.community.general.plugins.module_utils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.gitlab import ( - auth_argument_spec, gitlab_authentication, ensure_gitlab_package, find_group, find_project, gitlab + auth_argument_spec, gitlab_authentication, ensure_gitlab_package, find_group, find_project ) from datetime import datetime @@ -452,14 +451,7 @@ def main(): milestone_list = module.params['milestones'] state = module.params['state'] - gitlab_version = gitlab.__version__ - _min_gitlab = '3.2.0' - if LooseVersion(gitlab_version) < LooseVersion(_min_gitlab): - module.fail_json(msg="community.general.gitlab_milestone requires python-gitlab Python module >= %s " - "(installed version: [%s]). Please upgrade " - "python-gitlab to version %s or above." % (_min_gitlab, gitlab_version, _min_gitlab)) - - gitlab_instance = gitlab_authentication(module) + gitlab_instance = gitlab_authentication(module, min_version='3.2.0') # find_project can return None, but the other must exist gitlab_project_id = find_project(gitlab_instance, gitlab_project) diff --git a/ansible_collections/community/general/plugins/modules/haproxy.py b/ansible_collections/community/general/plugins/modules/haproxy.py index 05f52d55c..cbaa43833 100644 --- a/ansible_collections/community/general/plugins/modules/haproxy.py +++ b/ansible_collections/community/general/plugins/modules/haproxy.py @@ -343,7 +343,7 @@ class HAProxy(object): if state is not None: self.execute(Template(cmd).substitute(pxname=backend, svname=svname)) - if self.wait: + if self.wait and not (wait_for_status == "DRAIN" and state == "DOWN"): self.wait_until_status(backend, svname, wait_for_status) def get_state_for(self, pxname, svname): diff --git a/ansible_collections/community/general/plugins/modules/imc_rest.py b/ansible_collections/community/general/plugins/modules/imc_rest.py index 113d341e8..7f5a5e081 100644 --- a/ansible_collections/community/general/plugins/modules/imc_rest.py +++ b/ansible_collections/community/general/plugins/modules/imc_rest.py @@ -268,7 +268,6 @@ output: errorDescr="XML PARSING ERROR: Element 'computeRackUnit', attribute 'admin_Power': The attribute 'admin_Power' is not allowed.\n"/> ''' -import datetime import os import traceback @@ -292,6 +291,10 @@ from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.six.moves import zip_longest from ansible.module_utils.urls import fetch_url +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + def imc_response(module, rawoutput, rawinput=''): ''' Handle IMC returned data ''' @@ -375,14 +378,14 @@ def main(): else: module.fail_json(msg='Cannot find/access path:\n%s' % path) - start = datetime.datetime.utcnow() + start = now() # Perform login first url = '%s://%s/nuova' % (protocol, hostname) data = '<aaaLogin inName="%s" inPassword="%s"/>' % (username, password) resp, auth = fetch_url(module, url, data=data, method='POST', timeout=timeout) if resp is None or auth['status'] != 200: - result['elapsed'] = (datetime.datetime.utcnow() - start).seconds + result['elapsed'] = (now() - start).seconds module.fail_json(msg='Task failed with error %(status)s: %(msg)s' % auth, **result) result.update(imc_response(module, resp.read())) @@ -415,7 +418,7 @@ def main(): # Perform actual request resp, info = fetch_url(module, url, data=data, method='POST', timeout=timeout) if resp is None or info['status'] != 200: - result['elapsed'] = (datetime.datetime.utcnow() - start).seconds + result['elapsed'] = (now() - start).seconds module.fail_json(msg='Task failed with error %(status)s: %(msg)s' % info, **result) # Merge results with previous results @@ -431,7 +434,7 @@ def main(): result['changed'] = ('modified' in results) # Report success - result['elapsed'] = (datetime.datetime.utcnow() - start).seconds + result['elapsed'] = (now() - start).seconds module.exit_json(**result) finally: logout(module, url, cookie, timeout) diff --git a/ansible_collections/community/general/plugins/modules/ini_file.py b/ansible_collections/community/general/plugins/modules/ini_file.py index ec71a9473..affee2a4f 100644 --- a/ansible_collections/community/general/plugins/modules/ini_file.py +++ b/ansible_collections/community/general/plugins/modules/ini_file.py @@ -44,6 +44,30 @@ options: - If being omitted, the O(option) will be placed before the first O(section). - Omitting O(section) is also required if the config format does not support sections. type: str + section_has_values: + type: list + elements: dict + required: false + suboptions: + option: + type: str + description: Matching O(section) must contain this option. + required: true + value: + type: str + description: Matching O(section_has_values[].option) must have this specific value. + values: + description: + - The string value to be associated with an O(section_has_values[].option). + - Mutually exclusive with O(section_has_values[].value). + - O(section_has_values[].value=v) is equivalent to O(section_has_values[].values=[v]). + type: list + elements: str + description: + - Among possibly multiple sections of the same name, select the first one that contains matching options and values. + - With O(state=present), if a suitable section is not found, a new section will be added, including the required options. + - With O(state=absent), at most one O(section) is removed if it contains the values. + version_added: 8.6.0 option: description: - If set (required for changing a O(value)), this is the name of the option. @@ -182,6 +206,57 @@ EXAMPLES = r''' option: beverage value: lemon juice state: present + +- name: Remove the peer configuration for 10.128.0.11/32 + community.general.ini_file: + path: /etc/wireguard/wg0.conf + section: Peer + section_has_values: + - option: AllowedIps + value: 10.128.0.11/32 + mode: '0600' + state: absent + +- name: Add "beverage=lemon juice" outside a section in specified file + community.general.ini_file: + path: /etc/conf + option: beverage + value: lemon juice + state: present + +- name: Update the public key for peer 10.128.0.12/32 + community.general.ini_file: + path: /etc/wireguard/wg0.conf + section: Peer + section_has_values: + - option: AllowedIps + value: 10.128.0.12/32 + option: PublicKey + value: xxxxxxxxxxxxxxxxxxxx + mode: '0600' + state: present + +- name: Remove the peer configuration for 10.128.0.11/32 + community.general.ini_file: + path: /etc/wireguard/wg0.conf + section: Peer + section_has_values: + - option: AllowedIps + value: 10.4.0.11/32 + mode: '0600' + state: absent + +- name: Update the public key for peer 10.128.0.12/32 + community.general.ini_file: + path: /etc/wireguard/wg0.conf + section: Peer + section_has_values: + - option: AllowedIps + value: 10.4.0.12/32 + option: PublicKey + value: xxxxxxxxxxxxxxxxxxxx + mode: '0600' + state: present ''' import io @@ -222,7 +297,19 @@ def update_section_line(option, changed, section_lines, index, changed_lines, ig return (changed, msg) -def do_ini(module, filename, section=None, option=None, values=None, +def check_section_has_values(section_has_values, section_lines): + if section_has_values is not None: + for condition in section_has_values: + for line in section_lines: + match = match_opt(condition["option"], line) + if match and (len(condition["values"]) == 0 or match.group(7) in condition["values"]): + break + else: + return False + return True + + +def do_ini(module, filename, section=None, section_has_values=None, option=None, values=None, state='present', exclusive=True, backup=False, no_extra_spaces=False, ignore_spaces=False, create=True, allow_no_value=False, modify_inactive_option=True, follow=False): @@ -307,14 +394,22 @@ def do_ini(module, filename, section=None, option=None, values=None, section_pattern = re.compile(to_text(r'^\[\s*%s\s*]' % re.escape(section.strip()))) for index, line in enumerate(ini_lines): + # end of section: + if within_section and line.startswith(u'['): + if check_section_has_values( + section_has_values, ini_lines[section_start:index] + ): + section_end = index + break + else: + # look for another section + within_section = False + section_start = section_end = 0 + # find start and end of section if section_pattern.match(line): within_section = True section_start = index - elif line.startswith(u'['): - if within_section: - section_end = index - break before = ini_lines[0:section_start] section_lines = ini_lines[section_start:section_end] @@ -435,6 +530,18 @@ def do_ini(module, filename, section=None, option=None, values=None, if not within_section and state == 'present': ini_lines.append(u'[%s]\n' % section) msg = 'section and option added' + if section_has_values: + for condition in section_has_values: + if condition['option'] != option: + if len(condition['values']) > 0: + for value in condition['values']: + ini_lines.append(assignment_format % (condition['option'], value)) + elif allow_no_value: + ini_lines.append(u'%s\n' % condition['option']) + elif not exclusive: + for value in condition['values']: + if value not in values: + values.append(value) if option and values: for value in values: ini_lines.append(assignment_format % (option, value)) @@ -476,6 +583,11 @@ def main(): argument_spec=dict( path=dict(type='path', required=True, aliases=['dest']), section=dict(type='str'), + section_has_values=dict(type='list', elements='dict', options=dict( + option=dict(type='str', required=True), + value=dict(type='str'), + values=dict(type='list', elements='str') + ), default=None, mutually_exclusive=[['value', 'values']]), option=dict(type='str'), value=dict(type='str'), values=dict(type='list', elements='str'), @@ -498,6 +610,7 @@ def main(): path = module.params['path'] section = module.params['section'] + section_has_values = module.params['section_has_values'] option = module.params['option'] value = module.params['value'] values = module.params['values'] @@ -519,8 +632,16 @@ def main(): elif values is None: values = [] + if section_has_values: + for condition in section_has_values: + if condition['value'] is not None: + condition['values'] = [condition['value']] + elif condition['values'] is None: + condition['values'] = [] +# raise Exception("section_has_values: {}".format(section_has_values)) + (changed, backup_file, diff, msg) = do_ini( - module, path, section, option, values, state, exclusive, backup, + module, path, section, section_has_values, option, values, state, exclusive, backup, no_extra_spaces, ignore_spaces, create, allow_no_value, modify_inactive_option, follow) if not module.check_mode and os.path.exists(path): diff --git a/ansible_collections/community/general/plugins/modules/java_cert.py b/ansible_collections/community/general/plugins/modules/java_cert.py index 72302b12c..e2d04b71e 100644 --- a/ansible_collections/community/general/plugins/modules/java_cert.py +++ b/ansible_collections/community/general/plugins/modules/java_cert.py @@ -28,7 +28,7 @@ options: cert_url: description: - Basic URL to fetch SSL certificate from. - - Exactly one of O(cert_url), O(cert_path), or O(pkcs12_path) is required to load certificate. + - Exactly one of O(cert_url), O(cert_path), O(cert_content), or O(pkcs12_path) is required to load certificate. type: str cert_port: description: @@ -39,8 +39,14 @@ options: cert_path: description: - Local path to load certificate from. - - Exactly one of O(cert_url), O(cert_path), or O(pkcs12_path) is required to load certificate. + - Exactly one of O(cert_url), O(cert_path), O(cert_content), or O(pkcs12_path) is required to load certificate. type: path + cert_content: + description: + - Content of the certificate used to create the keystore. + - Exactly one of O(cert_url), O(cert_path), O(cert_content), or O(pkcs12_path) is required to load certificate. + type: str + version_added: 8.6.0 cert_alias: description: - Imported certificate alias. @@ -55,10 +61,10 @@ options: pkcs12_path: description: - Local path to load PKCS12 keystore from. - - Unlike O(cert_url) and O(cert_path), the PKCS12 keystore embeds the private key matching + - Unlike O(cert_url), O(cert_path) and O(cert_content), the PKCS12 keystore embeds the private key matching the certificate, and is used to import both the certificate and its private key into the java keystore. - - Exactly one of O(cert_url), O(cert_path), or O(pkcs12_path) is required to load certificate. + - Exactly one of O(cert_url), O(cert_path), O(cert_content), or O(pkcs12_path) is required to load certificate. type: path pkcs12_password: description: @@ -149,6 +155,19 @@ EXAMPLES = r''' cert_alias: LE_RootCA trust_cacert: true +- name: Import trusted CA from the SSL certificate stored in the cert_content variable + community.general.java_cert: + cert_content: | + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + keystore_path: /tmp/cacerts + keystore_pass: changeit + keystore_create: true + state: present + cert_alias: LE_RootCA + trust_cacert: true + - name: Import SSL certificate from google.com to a keystore, create it if it doesn't exist community.general.java_cert: cert_url: google.com @@ -487,6 +506,7 @@ def main(): argument_spec = dict( cert_url=dict(type='str'), cert_path=dict(type='path'), + cert_content=dict(type='str'), pkcs12_path=dict(type='path'), pkcs12_password=dict(type='str', no_log=True), pkcs12_alias=dict(type='str'), @@ -503,11 +523,11 @@ def main(): module = AnsibleModule( argument_spec=argument_spec, - required_if=[['state', 'present', ('cert_path', 'cert_url', 'pkcs12_path'), True], + required_if=[['state', 'present', ('cert_path', 'cert_url', 'cert_content', 'pkcs12_path'), True], ['state', 'absent', ('cert_url', 'cert_alias'), True]], required_together=[['keystore_path', 'keystore_pass']], mutually_exclusive=[ - ['cert_url', 'cert_path', 'pkcs12_path'] + ['cert_url', 'cert_path', 'cert_content', 'pkcs12_path'] ], supports_check_mode=True, add_file_common_args=True, @@ -515,6 +535,7 @@ def main(): url = module.params.get('cert_url') path = module.params.get('cert_path') + content = module.params.get('cert_content') port = module.params.get('cert_port') pkcs12_path = module.params.get('pkcs12_path') @@ -582,6 +603,10 @@ def main(): # certificate to stdout so we don't need to do any transformations. new_certificate = path + elif content: + with open(new_certificate, "w") as f: + f.write(content) + elif url: # Getting the X509 digest from a URL is the same as from a path, we just have # to download the cert first diff --git a/ansible_collections/community/general/plugins/modules/keycloak_client.py b/ansible_collections/community/general/plugins/modules/keycloak_client.py index b151e4541..cd9c60bac 100644 --- a/ansible_collections/community/general/plugins/modules/keycloak_client.py +++ b/ansible_collections/community/general/plugins/modules/keycloak_client.py @@ -248,8 +248,9 @@ options: description: - Type of client. - At creation only, default value will be V(openid-connect) if O(protocol) is omitted. + - The V(docker-v2) value was added in community.general 8.6.0. type: str - choices: ['openid-connect', 'saml'] + choices: ['openid-connect', 'saml', 'docker-v2'] full_scope_allowed: description: @@ -393,7 +394,7 @@ options: protocol: description: - This specifies for which protocol this protocol mapper is active. - choices: ['openid-connect', 'saml'] + choices: ['openid-connect', 'saml', 'docker-v2'] type: str protocolMapper: @@ -724,6 +725,7 @@ import copy PROTOCOL_OPENID_CONNECT = 'openid-connect' PROTOCOL_SAML = 'saml' +PROTOCOL_DOCKER_V2 = 'docker-v2' CLIENT_META_DATA = ['authorizationServicesEnabled'] @@ -742,6 +744,12 @@ def normalise_cr(clientrep, remove_ids=False): if 'attributes' in clientrep: clientrep['attributes'] = list(sorted(clientrep['attributes'])) + if 'defaultClientScopes' in clientrep: + clientrep['defaultClientScopes'] = list(sorted(clientrep['defaultClientScopes'])) + + if 'optionalClientScopes' in clientrep: + clientrep['optionalClientScopes'] = list(sorted(clientrep['optionalClientScopes'])) + if 'redirectUris' in clientrep: clientrep['redirectUris'] = list(sorted(clientrep['redirectUris'])) @@ -785,7 +793,7 @@ def main(): consentText=dict(type='str'), id=dict(type='str'), name=dict(type='str'), - protocol=dict(type='str', choices=[PROTOCOL_OPENID_CONNECT, PROTOCOL_SAML]), + protocol=dict(type='str', choices=[PROTOCOL_OPENID_CONNECT, PROTOCOL_SAML, PROTOCOL_DOCKER_V2]), protocolMapper=dict(type='str'), config=dict(type='dict'), ) @@ -819,7 +827,7 @@ def main(): authorization_services_enabled=dict(type='bool', aliases=['authorizationServicesEnabled']), public_client=dict(type='bool', aliases=['publicClient']), frontchannel_logout=dict(type='bool', aliases=['frontchannelLogout']), - protocol=dict(type='str', choices=[PROTOCOL_OPENID_CONNECT, PROTOCOL_SAML]), + protocol=dict(type='str', choices=[PROTOCOL_OPENID_CONNECT, PROTOCOL_SAML, PROTOCOL_DOCKER_V2]), attributes=dict(type='dict'), full_scope_allowed=dict(type='bool', aliases=['fullScopeAllowed']), node_re_registration_timeout=dict(type='int', aliases=['nodeReRegistrationTimeout']), diff --git a/ansible_collections/community/general/plugins/modules/keycloak_client_rolescope.py b/ansible_collections/community/general/plugins/modules/keycloak_client_rolescope.py new file mode 100644 index 000000000..cca72f0dd --- /dev/null +++ b/ansible_collections/community/general/plugins/modules/keycloak_client_rolescope.py @@ -0,0 +1,280 @@ +#!/usr/bin/python +# -*- coding: utf-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 + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_client_rolescope + +short_description: Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications. + +version_added: 8.6.0 + +description: + - This module allows you to add or remove Keycloak roles from clients scope via the Keycloak REST API. + It requires access to the REST API via OpenID Connect; the user connecting and the client being + used must have the requisite access rights. In a default Keycloak installation, admin-cli + and an admin user would work, as would a separate client definition with the scope tailored + to your needs and a user having the expected roles. + + - Client O(client_id) must have O(community.general.keycloak_client#module:full_scope_allowed) set to V(false). + + - Attributes are multi-valued in the Keycloak API. All attributes are lists of individual values and will + be returned that way by this module. You may pass single values for attributes when calling the module, + and this will be translated into a list suitable for the API. + +attributes: + check_mode: + support: full + diff_mode: + support: full + +options: + state: + description: + - State of the role mapping. + - On V(present), all roles in O(role_names) will be mapped if not exists yet. + - On V(absent), all roles mapping in O(role_names) will be removed if it exists. + default: 'present' + type: str + choices: + - present + - absent + + realm: + type: str + description: + - The Keycloak realm under which clients resides. + default: 'master' + + client_id: + type: str + required: true + description: + - Roles provided in O(role_names) while be added to this client scope. + + client_scope_id: + type: str + description: + - If the O(role_names) are client role, the client ID under which it resides. + - If this parameter is absent, the roles are considered a realm role. + role_names: + required: true + type: list + elements: str + description: + - Names of roles to manipulate. + - If O(client_scope_id) is present, all roles must be under this client. + - If O(client_scope_id) is absent, all roles must be under the realm. + + +extends_documentation_fragment: + - community.general.keycloak + - community.general.attributes + +author: + - Andre Desrosiers (@desand01) +''' + +EXAMPLES = ''' +- name: Add roles to public client scope + community.general.keycloak_client_rolescope: + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + realm: MyCustomRealm + client_id: frontend-client-public + client_scope_id: backend-client-private + role_names: + - backend-role-admin + - backend-role-user + +- name: Remove roles from public client scope + community.general.keycloak_client_rolescope: + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + realm: MyCustomRealm + client_id: frontend-client-public + client_scope_id: backend-client-private + role_names: + - backend-role-admin + state: absent + +- name: Add realm roles to public client scope + community.general.keycloak_client_rolescope: + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + realm: MyCustomRealm + client_id: frontend-client-public + role_names: + - realm-role-admin + - realm-role-user +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + sample: "Client role scope for frontend-client-public has been updated" + +end_state: + description: Representation of role role scope after module execution. + returned: on success + type: list + elements: dict + sample: [ + { + "clientRole": false, + "composite": false, + "containerId": "MyCustomRealm", + "id": "47293104-59a6-46f0-b460-2e9e3c9c424c", + "name": "backend-role-admin" + }, + { + "clientRole": false, + "composite": false, + "containerId": "MyCustomRealm", + "id": "39c62a6d-542c-4715-92d2-41021eb33967", + "name": "backend-role-user" + } + ] +''' + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, \ + keycloak_argument_spec, get_token, KeycloakError +from ansible.module_utils.basic import AnsibleModule + + +def main(): + """ + Module execution + + :return: + """ + argument_spec = keycloak_argument_spec() + + meta_args = dict( + client_id=dict(type='str', required=True), + client_scope_id=dict(type='str'), + realm=dict(type='str', default='master'), + role_names=dict(type='list', elements='str', required=True), + state=dict(type='str', default='present', choices=['present', 'absent']), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + result = dict(changed=False, msg='', diff={}, end_state={}) + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + realm = module.params.get('realm') + clientid = module.params.get('client_id') + client_scope_id = module.params.get('client_scope_id') + role_names = module.params.get('role_names') + state = module.params.get('state') + + objRealm = kc.get_realm_by_id(realm) + if not objRealm: + module.fail_json(msg="Failed to retrive realm '{realm}'".format(realm=realm)) + + objClient = kc.get_client_by_clientid(clientid, realm) + if not objClient: + module.fail_json(msg="Failed to retrive client '{realm}.{clientid}'".format(realm=realm, clientid=clientid)) + if objClient["fullScopeAllowed"] and state == "present": + module.fail_json(msg="FullScopeAllowed is active for Client '{realm}.{clientid}'".format(realm=realm, clientid=clientid)) + + if client_scope_id: + objClientScope = kc.get_client_by_clientid(client_scope_id, realm) + if not objClientScope: + module.fail_json(msg="Failed to retrive client '{realm}.{client_scope_id}'".format(realm=realm, client_scope_id=client_scope_id)) + before_role_mapping = kc.get_client_role_scope_from_client(objClient["id"], objClientScope["id"], realm) + else: + before_role_mapping = kc.get_client_role_scope_from_realm(objClient["id"], realm) + + if client_scope_id: + # retrive all role from client_scope + client_scope_roles_by_name = kc.get_client_roles_by_id(objClientScope["id"], realm) + else: + # retrive all role from realm + client_scope_roles_by_name = kc.get_realm_roles(realm) + + # convert to indexed Dict by name + client_scope_roles_by_name = {role["name"]: role for role in client_scope_roles_by_name} + role_mapping_by_name = {role["name"]: role for role in before_role_mapping} + role_mapping_to_manipulate = [] + + if state == "present": + # update desired + for role_name in role_names: + if role_name not in client_scope_roles_by_name: + if client_scope_id: + module.fail_json(msg="Failed to retrive role '{realm}.{client_scope_id}.{role_name}'" + .format(realm=realm, client_scope_id=client_scope_id, role_name=role_name)) + else: + module.fail_json(msg="Failed to retrive role '{realm}.{role_name}'".format(realm=realm, role_name=role_name)) + if role_name not in role_mapping_by_name: + role_mapping_to_manipulate.append(client_scope_roles_by_name[role_name]) + role_mapping_by_name[role_name] = client_scope_roles_by_name[role_name] + else: + # remove role if present + for role_name in role_names: + if role_name in role_mapping_by_name: + role_mapping_to_manipulate.append(role_mapping_by_name[role_name]) + del role_mapping_by_name[role_name] + + before_role_mapping = sorted(before_role_mapping, key=lambda d: d['name']) + desired_role_mapping = sorted(role_mapping_by_name.values(), key=lambda d: d['name']) + + result['changed'] = len(role_mapping_to_manipulate) > 0 + + if result['changed']: + result['diff'] = dict(before=before_role_mapping, after=desired_role_mapping) + + if not result['changed']: + # no changes + result['end_state'] = before_role_mapping + result['msg'] = "No changes required for client role scope {name}.".format(name=clientid) + elif state == "present": + # doing update + if module.check_mode: + result['end_state'] = desired_role_mapping + elif client_scope_id: + result['end_state'] = kc.update_client_role_scope_from_client(role_mapping_to_manipulate, objClient["id"], objClientScope["id"], realm) + else: + result['end_state'] = kc.update_client_role_scope_from_realm(role_mapping_to_manipulate, objClient["id"], realm) + result['msg'] = "Client role scope for {name} has been updated".format(name=clientid) + else: + # doing delete + if module.check_mode: + result['end_state'] = desired_role_mapping + elif client_scope_id: + result['end_state'] = kc.delete_client_role_scope_from_client(role_mapping_to_manipulate, objClient["id"], objClientScope["id"], realm) + else: + result['end_state'] = kc.delete_client_role_scope_from_realm(role_mapping_to_manipulate, objClient["id"], realm) + result['msg'] = "Client role scope for {name} has been deleted".format(name=clientid) + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/ansible_collections/community/general/plugins/modules/keycloak_clientscope.py b/ansible_collections/community/general/plugins/modules/keycloak_clientscope.py index d37af5f0c..d24e0f1f2 100644 --- a/ansible_collections/community/general/plugins/modules/keycloak_clientscope.py +++ b/ansible_collections/community/general/plugins/modules/keycloak_clientscope.py @@ -79,7 +79,8 @@ options: protocol: description: - Type of client. - choices: ['openid-connect', 'saml', 'wsfed'] + - The V(docker-v2) value was added in community.general 8.6.0. + choices: ['openid-connect', 'saml', 'wsfed', 'docker-v2'] type: str protocol_mappers: @@ -95,7 +96,7 @@ options: description: - This specifies for which protocol this protocol mapper. - is active. - choices: ['openid-connect', 'saml', 'wsfed'] + choices: ['openid-connect', 'saml', 'wsfed', 'docker-v2'] type: str protocolMapper: @@ -330,7 +331,7 @@ def main(): protmapper_spec = dict( id=dict(type='str'), name=dict(type='str'), - protocol=dict(type='str', choices=['openid-connect', 'saml', 'wsfed']), + protocol=dict(type='str', choices=['openid-connect', 'saml', 'wsfed', 'docker-v2']), protocolMapper=dict(type='str'), config=dict(type='dict'), ) @@ -341,7 +342,7 @@ def main(): id=dict(type='str'), name=dict(type='str'), description=dict(type='str'), - protocol=dict(type='str', choices=['openid-connect', 'saml', 'wsfed']), + protocol=dict(type='str', choices=['openid-connect', 'saml', 'wsfed', 'docker-v2']), attributes=dict(type='dict'), protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec, aliases=['protocolMappers']), ) diff --git a/ansible_collections/community/general/plugins/modules/keycloak_clienttemplate.py b/ansible_collections/community/general/plugins/modules/keycloak_clienttemplate.py index cd7f6c09b..7bffb5cbb 100644 --- a/ansible_collections/community/general/plugins/modules/keycloak_clienttemplate.py +++ b/ansible_collections/community/general/plugins/modules/keycloak_clienttemplate.py @@ -68,7 +68,8 @@ options: protocol: description: - Type of client template. - choices: ['openid-connect', 'saml'] + - The V(docker-v2) value was added in community.general 8.6.0. + choices: ['openid-connect', 'saml', 'docker-v2'] type: str full_scope_allowed: @@ -107,7 +108,7 @@ options: protocol: description: - This specifies for which protocol this protocol mapper is active. - choices: ['openid-connect', 'saml'] + choices: ['openid-connect', 'saml', 'docker-v2'] type: str protocolMapper: @@ -292,7 +293,7 @@ def main(): consentText=dict(type='str'), id=dict(type='str'), name=dict(type='str'), - protocol=dict(type='str', choices=['openid-connect', 'saml']), + protocol=dict(type='str', choices=['openid-connect', 'saml', 'docker-v2']), protocolMapper=dict(type='str'), config=dict(type='dict'), ) @@ -304,7 +305,7 @@ def main(): id=dict(type='str'), name=dict(type='str'), description=dict(type='str'), - protocol=dict(type='str', choices=['openid-connect', 'saml']), + protocol=dict(type='str', choices=['openid-connect', 'saml', 'docker-v2']), attributes=dict(type='dict'), full_scope_allowed=dict(type='bool'), protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec), diff --git a/ansible_collections/community/general/plugins/modules/keycloak_realm.py b/ansible_collections/community/general/plugins/modules/keycloak_realm.py index 9f2e72b52..6128c9e4c 100644 --- a/ansible_collections/community/general/plugins/modules/keycloak_realm.py +++ b/ansible_collections/community/general/plugins/modules/keycloak_realm.py @@ -582,6 +582,27 @@ from ansible_collections.community.general.plugins.module_utils.identity.keycloa from ansible.module_utils.basic import AnsibleModule +def normalise_cr(realmrep): + """ Re-sorts any properties where the order is important so that diff's is minimised and the change detection is more effective. + + :param realmrep: the realmrep dict to be sanitized + :return: normalised realmrep dict + """ + # Avoid the dict passed in to be modified + realmrep = realmrep.copy() + + if 'enabledEventTypes' in realmrep: + realmrep['enabledEventTypes'] = list(sorted(realmrep['enabledEventTypes'])) + + if 'otpSupportedApplications' in realmrep: + realmrep['otpSupportedApplications'] = list(sorted(realmrep['otpSupportedApplications'])) + + if 'supportedLocales' in realmrep: + realmrep['supportedLocales'] = list(sorted(realmrep['supportedLocales'])) + + return realmrep + + def sanitize_cr(realmrep): """ Removes probably sensitive details from a realm representation. @@ -595,7 +616,7 @@ def sanitize_cr(realmrep): if 'saml.signing.private.key' in result['attributes']: result['attributes'] = result['attributes'].copy() result['attributes']['saml.signing.private.key'] = '********' - return result + return normalise_cr(result) def main(): @@ -777,9 +798,11 @@ def main(): result['changed'] = True if module.check_mode: # We can only compare the current realm with the proposed updates we have + before_norm = normalise_cr(before_realm) + desired_norm = normalise_cr(desired_realm) if module._diff: - result['diff'] = dict(before=before_realm_sanitized, - after=sanitize_cr(desired_realm)) + result['diff'] = dict(before=sanitize_cr(before_norm), + after=sanitize_cr(desired_norm)) result['changed'] = (before_realm != desired_realm) module.exit_json(**result) diff --git a/ansible_collections/community/general/plugins/modules/lxd_container.py b/ansible_collections/community/general/plugins/modules/lxd_container.py index 9fd1b183b..b82e2be9b 100644 --- a/ansible_collections/community/general/plugins/modules/lxd_container.py +++ b/ansible_collections/community/general/plugins/modules/lxd_container.py @@ -86,8 +86,8 @@ options: source: description: - 'The source for the instance - (for example V({ "type": "image", "mode": "pull", "server": "https://images.linuxcontainers.org", - "protocol": "lxd", "alias": "ubuntu/xenial/amd64" })).' + (for example V({ "type": "image", "mode": "pull", "server": "https://cloud-images.ubuntu.com/releases/", + "protocol": "simplestreams", "alias": "22.04" })).' - 'See U(https://documentation.ubuntu.com/lxd/en/latest/api/) for complete API documentation.' - 'Note that C(protocol) accepts two choices: V(lxd) or V(simplestreams).' required: false @@ -205,6 +205,9 @@ notes: - You can copy a file in the created instance to the localhost with C(command=lxc file pull instance_name/dir/filename filename). See the first example below. + - linuxcontainers.org has phased out LXC/LXD support with March 2024 + (U(https://discuss.linuxcontainers.org/t/important-notice-for-lxd-users-image-server/18479)). + Currently only Ubuntu is still providing images. ''' EXAMPLES = ''' @@ -220,9 +223,9 @@ EXAMPLES = ''' source: type: image mode: pull - server: https://images.linuxcontainers.org - protocol: lxd # if you get a 404, try setting protocol: simplestreams - alias: ubuntu/xenial/amd64 + server: https://cloud-images.ubuntu.com/releases/ + protocol: simplestreams + alias: "22.04" profiles: ["default"] wait_for_ipv4_addresses: true timeout: 600 @@ -264,6 +267,26 @@ EXAMPLES = ''' wait_for_ipv4_addresses: true timeout: 600 +# An example of creating a ubuntu-minial container +- hosts: localhost + connection: local + tasks: + - name: Create a started container + community.general.lxd_container: + name: mycontainer + ignore_volatile_options: true + state: started + source: + type: image + mode: pull + # Provides Ubuntu minimal images + server: https://cloud-images.ubuntu.com/minimal/releases/ + protocol: simplestreams + alias: "22.04" + profiles: ["default"] + wait_for_ipv4_addresses: true + timeout: 600 + # An example for creating container in project other than default - hosts: localhost connection: local @@ -278,8 +301,8 @@ EXAMPLES = ''' protocol: simplestreams type: image mode: pull - server: https://images.linuxcontainers.org - alias: ubuntu/20.04/cloud + server: https://cloud-images.ubuntu.com/releases/ + alias: "22.04" profiles: ["default"] wait_for_ipv4_addresses: true timeout: 600 @@ -347,7 +370,7 @@ EXAMPLES = ''' source: type: image mode: pull - alias: ubuntu/xenial/amd64 + alias: "22.04" target: node01 - name: Create container on another node @@ -358,7 +381,7 @@ EXAMPLES = ''' source: type: image mode: pull - alias: ubuntu/xenial/amd64 + alias: "22.04" target: node02 # An example for creating a virtual machine diff --git a/ansible_collections/community/general/plugins/modules/nmcli.py b/ansible_collections/community/general/plugins/modules/nmcli.py index 9360ce37d..6f0884da9 100644 --- a/ansible_collections/community/general/plugins/modules/nmcli.py +++ b/ansible_collections/community/general/plugins/modules/nmcli.py @@ -64,13 +64,16 @@ options: - Type V(infiniband) is added in community.general 2.0.0. - Type V(loopback) is added in community.general 8.1.0. - Type V(macvlan) is added in community.general 6.6.0. + - Type V(ovs-bridge) is added in community.general 8.6.0. + - Type V(ovs-interface) is added in community.general 8.6.0. + - Type V(ovs-port) is added in community.general 8.6.0. - Type V(wireguard) is added in community.general 4.3.0. - Type V(vpn) is added in community.general 5.1.0. - Using V(bond-slave), V(bridge-slave), or V(team-slave) implies V(ethernet) connection type with corresponding O(slave_type) option. - If you want to control non-ethernet connection attached to V(bond), V(bridge), or V(team) consider using O(slave_type) option. type: str choices: [ bond, bond-slave, bridge, bridge-slave, dummy, ethernet, generic, gre, infiniband, ipip, macvlan, sit, team, team-slave, vlan, vxlan, - wifi, gsm, wireguard, vpn, loopback ] + wifi, gsm, wireguard, ovs-bridge, ovs-port, ovs-interface, vpn, loopback ] mode: description: - This is the type of device or network connection that you wish to create for a bond or bridge. @@ -86,12 +89,13 @@ options: slave_type: description: - Type of the device of this slave's master connection (for example V(bond)). + - Type V(ovs-port) is added in community.general 8.6.0. type: str - choices: [ 'bond', 'bridge', 'team' ] + choices: [ 'bond', 'bridge', 'team', 'ovs-port' ] version_added: 7.0.0 master: description: - - Master <master (ifname, or connection UUID or conn_name) of bridge, team, bond master connection profile. + - Master <master (ifname, or connection UUID or conn_name) of bridge, team, bond, ovs-port master connection profile. - Mandatory if O(slave_type) is defined. type: str ip4: @@ -1505,6 +1509,32 @@ EXAMPLES = r''' table: "production" routing_rules4: - "priority 0 from 192.168.1.50 table 200" + +## Creating an OVS bridge and attaching a port +- name: Create OVS Bridge + community.general.nmcli: + conn_name: ovs-br-conn + ifname: ovs-br + type: ovs-bridge + state: present + +- name: Create OVS Port for OVS Bridge Interface + community.general.nmcli: + conn_name: ovs-br-interface-port-conn + ifname: ovs-br-interface-port + master: ovs-br + type: ovs-port + state: present + +## Adding an ethernet interface to an OVS bridge port +- name: Add Ethernet Interface to OVS Port + community.general.nmcli: + conn_name: eno1 + ifname: eno1 + master: ovs-br-interface-port + slave_type: ovs-port + type: ethernet + state: present ''' RETURN = r"""# @@ -1678,7 +1708,8 @@ class Nmcli(object): } # IP address options. - if self.ip_conn_type and not self.master: + # The ovs-interface type can be both ip_conn_type and have a master + if (self.ip_conn_type and not self.master) or self.type == "ovs-interface": options.update({ 'ipv4.addresses': self.enforce_ipv4_cidr_notation(self.ip4), 'ipv4.dhcp-client-id': self.dhcp_client_id, @@ -1939,6 +1970,7 @@ class Nmcli(object): 'wireguard', 'vpn', 'loopback', + 'ovs-interface', ) @property @@ -2005,6 +2037,8 @@ class Nmcli(object): 'team-slave', 'wifi', 'infiniband', + 'ovs-port', + 'ovs-interface', ) @property @@ -2400,7 +2434,7 @@ def main(): state=dict(type='str', required=True, choices=['absent', 'present']), conn_name=dict(type='str', required=True), master=dict(type='str'), - slave_type=dict(type='str', choices=['bond', 'bridge', 'team']), + slave_type=dict(type='str', choices=['bond', 'bridge', 'team', 'ovs-port']), ifname=dict(type='str'), type=dict(type='str', choices=[ @@ -2425,6 +2459,9 @@ def main(): 'wireguard', 'vpn', 'loopback', + 'ovs-interface', + 'ovs-bridge', + 'ovs-port', ]), ip4=dict(type='list', elements='str'), gw4=dict(type='str'), diff --git a/ansible_collections/community/general/plugins/modules/osx_defaults.py b/ansible_collections/community/general/plugins/modules/osx_defaults.py index 336e95332..db5d889a3 100644 --- a/ansible_collections/community/general/plugins/modules/osx_defaults.py +++ b/ansible_collections/community/general/plugins/modules/osx_defaults.py @@ -50,6 +50,13 @@ options: type: str choices: [ array, bool, boolean, date, float, int, integer, string ] default: string + check_type: + description: + - Checks if the type of the provided O(value) matches the type of an existing default. + - If the types do not match, raises an error. + type: bool + default: true + version_added: 8.6.0 array_add: description: - Add new elements to the array for a key which has an array as its value. @@ -158,6 +165,7 @@ class OSXDefaults(object): self.domain = module.params['domain'] self.host = module.params['host'] self.key = module.params['key'] + self.check_type = module.params['check_type'] self.type = module.params['type'] self.array_add = module.params['array_add'] self.value = module.params['value'] @@ -349,10 +357,11 @@ class OSXDefaults(object): self.delete() return True - # There is a type mismatch! Given type does not match the type in defaults - value_type = type(self.value) - if self.current_value is not None and not isinstance(self.current_value, value_type): - raise OSXDefaultsException("Type mismatch. Type in defaults: %s" % type(self.current_value).__name__) + # Check if there is a type mismatch, e.g. given type does not match the type in defaults + if self.check_type: + value_type = type(self.value) + if self.current_value is not None and not isinstance(self.current_value, value_type): + raise OSXDefaultsException("Type mismatch. Type in defaults: %s" % type(self.current_value).__name__) # Current value matches the given value. Nothing need to be done. Arrays need extra care if self.type == "array" and self.current_value is not None and not self.array_add and \ @@ -383,6 +392,7 @@ def main(): domain=dict(type='str', default='NSGlobalDomain'), host=dict(type='str'), key=dict(type='str', no_log=False), + check_type=dict(type='bool', default=True), type=dict(type='str', default='string', choices=['array', 'bool', 'boolean', 'date', 'float', 'int', 'integer', 'string']), array_add=dict(type='bool', default=False), value=dict(type='raw'), diff --git a/ansible_collections/community/general/plugins/modules/pagerduty.py b/ansible_collections/community/general/plugins/modules/pagerduty.py index 596c4f4da..853bd6d79 100644 --- a/ansible_collections/community/general/plugins/modules/pagerduty.py +++ b/ansible_collections/community/general/plugins/modules/pagerduty.py @@ -151,6 +151,10 @@ import json from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import fetch_url +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + class PagerDutyRequest(object): def __init__(self, module, name, user, token): @@ -206,9 +210,9 @@ class PagerDutyRequest(object): return [{'id': service, 'type': 'service_reference'}] def _compute_start_end_time(self, hours, minutes): - now = datetime.datetime.utcnow() - later = now + datetime.timedelta(hours=int(hours), minutes=int(minutes)) - start = now.strftime("%Y-%m-%dT%H:%M:%SZ") + now_t = now() + later = now_t + datetime.timedelta(hours=int(hours), minutes=int(minutes)) + start = now_t.strftime("%Y-%m-%dT%H:%M:%SZ") end = later.strftime("%Y-%m-%dT%H:%M:%SZ") return start, end diff --git a/ansible_collections/community/general/plugins/modules/pagerduty_change.py b/ansible_collections/community/general/plugins/modules/pagerduty_change.py index 1a1e50dcf..acd31fb44 100644 --- a/ansible_collections/community/general/plugins/modules/pagerduty_change.py +++ b/ansible_collections/community/general/plugins/modules/pagerduty_change.py @@ -110,7 +110,10 @@ EXAMPLES = ''' from ansible.module_utils.urls import fetch_url from ansible.module_utils.basic import AnsibleModule -from datetime import datetime + +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) def main(): @@ -161,8 +164,7 @@ def main(): if module.params['environment']: custom_details['environment'] = module.params['environment'] - now = datetime.utcnow() - timestamp = now.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + timestamp = now().strftime("%Y-%m-%dT%H:%M:%S.%fZ") payload = { 'summary': module.params['summary'], diff --git a/ansible_collections/community/general/plugins/modules/portage.py b/ansible_collections/community/general/plugins/modules/portage.py index 112f6d2d7..8ae8efb08 100644 --- a/ansible_collections/community/general/plugins/modules/portage.py +++ b/ansible_collections/community/general/plugins/modules/portage.py @@ -121,6 +121,14 @@ options: type: bool default: false + select: + description: + - If set to V(true), explicitely add the package to the world file. + - Please note that this option is not used for idempotency, it is only used + when actually installing a package. + type: bool + version_added: 8.6.0 + sync: description: - Sync package repositories first @@ -374,6 +382,7 @@ def emerge_packages(module, packages): 'loadavg': '--load-average', 'backtrack': '--backtrack', 'withbdeps': '--with-bdeps', + 'select': '--select', } for flag, arg in emerge_flags.items(): @@ -523,6 +532,7 @@ def main(): nodeps=dict(default=False, type='bool'), onlydeps=dict(default=False, type='bool'), depclean=dict(default=False, type='bool'), + select=dict(default=None, type='bool'), quiet=dict(default=False, type='bool'), verbose=dict(default=False, type='bool'), sync=dict(default=None, choices=['yes', 'web', 'no']), @@ -543,6 +553,7 @@ def main(): ['quiet', 'verbose'], ['quietbuild', 'verbose'], ['quietfail', 'verbose'], + ['oneshot', 'select'], ], supports_check_mode=True, ) diff --git a/ansible_collections/community/general/plugins/modules/puppet.py b/ansible_collections/community/general/plugins/modules/puppet.py index 86eac062a..b28583fe0 100644 --- a/ansible_collections/community/general/plugins/modules/puppet.py +++ b/ansible_collections/community/general/plugins/modules/puppet.py @@ -116,6 +116,15 @@ options: - Whether to print file changes details type: bool default: false + environment_lang: + description: + - The lang environment to use when running the puppet agent. + - The default value, V(C), is supported on every system, but can lead to encoding errors if UTF-8 is used in the output + - Use V(C.UTF-8) or V(en_US.UTF-8) or similar UTF-8 supporting locales in case of problems. You need to make sure + the selected locale is supported on the system the puppet agent runs on. + type: str + default: C + version_added: 8.6.0 requirements: - puppet author: @@ -208,6 +217,7 @@ def main(): debug=dict(type='bool', default=False), verbose=dict(type='bool', default=False), use_srv_records=dict(type='bool'), + environment_lang=dict(type='str', default='C'), ), supports_check_mode=True, mutually_exclusive=[ diff --git a/ansible_collections/community/general/plugins/modules/redfish_command.py b/ansible_collections/community/general/plugins/modules/redfish_command.py index e66380493..06224235a 100644 --- a/ansible_collections/community/general/plugins/modules/redfish_command.py +++ b/ansible_collections/community/general/plugins/modules/redfish_command.py @@ -281,6 +281,12 @@ options: - BIOS attributes that needs to be verified in the given server. type: dict version_added: 6.4.0 + reset_to_defaults_mode: + description: + - Mode to apply when reseting to default. + type: str + choices: [ ResetAll, PreserveNetworkAndUsers, PreserveNetwork ] + version_added: 8.6.0 author: - "Jose Delarosa (@jose-delarosa)" @@ -714,6 +720,13 @@ EXAMPLES = ''' command: PowerReboot resource_id: BMC + - name: Factory reset manager to defaults + community.general.redfish_command: + category: Manager + command: ResetToDefaults + resource_id: BMC + reset_to_defaults_mode: ResetAll + - name: Verify BIOS attributes community.general.redfish_command: category: Systems @@ -764,6 +777,7 @@ CATEGORY_COMMANDS_ALL = { "UpdateAccountServiceProperties"], "Sessions": ["ClearSessions", "CreateSession", "DeleteSession"], "Manager": ["GracefulRestart", "ClearLogs", "VirtualMediaInsert", + "ResetToDefaults", "VirtualMediaEject", "PowerOn", "PowerForceOff", "PowerForceRestart", "PowerGracefulRestart", "PowerGracefulShutdown", "PowerReboot"], "Update": ["SimpleUpdate", "MultipartHTTPPushUpdate", "PerformRequestedOperations"], @@ -825,6 +839,7 @@ def main(): ) ), strip_etag_quotes=dict(type='bool', default=False), + reset_to_defaults_mode=dict(choices=['ResetAll', 'PreserveNetworkAndUsers', 'PreserveNetwork']), bios_attributes=dict(type="dict") ), required_together=[ @@ -1017,6 +1032,8 @@ def main(): result = rf_utils.virtual_media_insert(virtual_media, category) elif command == 'VirtualMediaEject': result = rf_utils.virtual_media_eject(virtual_media, category) + elif command == 'ResetToDefaults': + result = rf_utils.manager_reset_to_defaults(module.params['reset_to_defaults_mode']) elif category == "Update": # execute only if we find UpdateService resources diff --git a/ansible_collections/community/general/plugins/modules/riak.py b/ansible_collections/community/general/plugins/modules/riak.py index fe295d2d6..438263da2 100644 --- a/ansible_collections/community/general/plugins/modules/riak.py +++ b/ansible_collections/community/general/plugins/modules/riak.py @@ -93,7 +93,7 @@ from ansible.module_utils.urls import fetch_url def ring_check(module, riak_admin_bin): - cmd = '%s ringready' % riak_admin_bin + cmd = riak_admin_bin + ['ringready'] rc, out, err = module.run_command(cmd) if rc == 0 and 'TRUE All nodes agree on the ring' in out: return True @@ -127,6 +127,7 @@ def main(): # make sure riak commands are on the path riak_bin = module.get_bin_path('riak') riak_admin_bin = module.get_bin_path('riak-admin') + riak_admin_bin = [riak_admin_bin] if riak_admin_bin is not None else [riak_bin, 'admin'] timeout = time.time() + 120 while True: @@ -164,7 +165,7 @@ def main(): module.fail_json(msg=out) elif command == 'kv_test': - cmd = '%s test' % riak_admin_bin + cmd = riak_admin_bin + ['test'] rc, out, err = module.run_command(cmd) if rc == 0: result['kv_test'] = out @@ -175,7 +176,7 @@ def main(): if nodes.count(node_name) == 1 and len(nodes) > 1: result['join'] = 'Node is already in cluster or staged to be in cluster.' else: - cmd = '%s cluster join %s' % (riak_admin_bin, target_node) + cmd = riak_admin_bin + ['cluster', 'join', target_node] rc, out, err = module.run_command(cmd) if rc == 0: result['join'] = out @@ -184,7 +185,7 @@ def main(): module.fail_json(msg=out) elif command == 'plan': - cmd = '%s cluster plan' % riak_admin_bin + cmd = riak_admin_bin + ['cluster', 'plan'] rc, out, err = module.run_command(cmd) if rc == 0: result['plan'] = out @@ -194,7 +195,7 @@ def main(): module.fail_json(msg=out) elif command == 'commit': - cmd = '%s cluster commit' % riak_admin_bin + cmd = riak_admin_bin + ['cluster', 'commit'] rc, out, err = module.run_command(cmd) if rc == 0: result['commit'] = out @@ -206,7 +207,7 @@ def main(): if wait_for_handoffs: timeout = time.time() + wait_for_handoffs while True: - cmd = '%s transfers' % riak_admin_bin + cmd = riak_admin_bin + ['transfers'] rc, out, err = module.run_command(cmd) if 'No transfers active' in out: result['handoffs'] = 'No transfers active.' @@ -216,7 +217,7 @@ def main(): module.fail_json(msg='Timeout waiting for handoffs.') if wait_for_service: - cmd = [riak_admin_bin, 'wait_for_service', 'riak_%s' % wait_for_service, node_name] + cmd = riak_admin_bin + ['wait_for_service', 'riak_%s' % wait_for_service, node_name] rc, out, err = module.run_command(cmd) result['service'] = out diff --git a/ansible_collections/community/general/plugins/modules/scaleway_compute.py b/ansible_collections/community/general/plugins/modules/scaleway_compute.py index 7f85bc668..58a321505 100644 --- a/ansible_collections/community/general/plugins/modules/scaleway_compute.py +++ b/ansible_collections/community/general/plugins/modules/scaleway_compute.py @@ -183,6 +183,7 @@ import datetime import time from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.datetime import now from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, scaleway_argument_spec, Scaleway SCALEWAY_SERVER_STATES = ( @@ -235,9 +236,9 @@ def wait_to_complete_state_transition(compute_api, server, wait=None): wait_timeout = compute_api.module.params["wait_timeout"] wait_sleep_time = compute_api.module.params["wait_sleep_time"] - start = datetime.datetime.utcnow() + start = now() end = start + datetime.timedelta(seconds=wait_timeout) - while datetime.datetime.utcnow() < end: + while now() < end: compute_api.module.debug("We are going to wait for the server to finish its transition") if fetch_state(compute_api, server) not in SCALEWAY_TRANSITIONS_STATES: compute_api.module.debug("It seems that the server is not in transition anymore.") diff --git a/ansible_collections/community/general/plugins/modules/scaleway_database_backup.py b/ansible_collections/community/general/plugins/modules/scaleway_database_backup.py index 592ec0b7f..1d0c17fb6 100644 --- a/ansible_collections/community/general/plugins/modules/scaleway_database_backup.py +++ b/ansible_collections/community/general/plugins/modules/scaleway_database_backup.py @@ -170,6 +170,9 @@ import datetime import time from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) from ansible_collections.community.general.plugins.module_utils.scaleway import ( Scaleway, scaleway_argument_spec, @@ -189,9 +192,9 @@ def wait_to_complete_state_transition(module, account_api, backup=None): if backup is None or backup['status'] in stable_states: return backup - start = datetime.datetime.utcnow() + start = now() end = start + datetime.timedelta(seconds=wait_timeout) - while datetime.datetime.utcnow() < end: + while now() < end: module.debug('We are going to wait for the backup to finish its transition') response = account_api.get('/rdb/v1/regions/%s/backups/%s' % (module.params.get('region'), backup['id'])) diff --git a/ansible_collections/community/general/plugins/modules/scaleway_lb.py b/ansible_collections/community/general/plugins/modules/scaleway_lb.py index 3e43a8ae2..5bd16c3f4 100644 --- a/ansible_collections/community/general/plugins/modules/scaleway_lb.py +++ b/ansible_collections/community/general/plugins/modules/scaleway_lb.py @@ -161,6 +161,7 @@ RETURNS = ''' import datetime import time from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.datetime import now from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_REGIONS, SCALEWAY_ENDPOINT, scaleway_argument_spec, Scaleway STABLE_STATES = ( @@ -208,9 +209,9 @@ def wait_to_complete_state_transition(api, lb, force_wait=False): wait_timeout = api.module.params["wait_timeout"] wait_sleep_time = api.module.params["wait_sleep_time"] - start = datetime.datetime.utcnow() + start = now() end = start + datetime.timedelta(seconds=wait_timeout) - while datetime.datetime.utcnow() < end: + while now() < end: api.module.debug("We are going to wait for the load-balancer to finish its transition") state = fetch_state(api, lb) if state in STABLE_STATES: diff --git a/ansible_collections/community/general/plugins/modules/ssh_config.py b/ansible_collections/community/general/plugins/modules/ssh_config.py index e89e087b3..d974f4537 100644 --- a/ansible_collections/community/general/plugins/modules/ssh_config.py +++ b/ansible_collections/community/general/plugins/modules/ssh_config.py @@ -88,7 +88,8 @@ options: strict_host_key_checking: description: - Whether to strictly check the host key when doing connections to the remote host. - choices: [ 'yes', 'no', 'ask' ] + - The value V(accept-new) is supported since community.general 8.6.0. + choices: [ 'yes', 'no', 'ask', 'accept-new' ] type: str proxycommand: description: @@ -370,7 +371,7 @@ def main(): strict_host_key_checking=dict( type='str', default=None, - choices=['yes', 'no', 'ask'] + choices=['yes', 'no', 'ask', 'accept-new'], ), controlmaster=dict(type='str', default=None, choices=['yes', 'no', 'ask', 'auto', 'autoask']), controlpath=dict(type='str', default=None), diff --git a/ansible_collections/community/general/plugins/modules/statusio_maintenance.py b/ansible_collections/community/general/plugins/modules/statusio_maintenance.py index e6b34b709..0a96d0fb4 100644 --- a/ansible_collections/community/general/plugins/modules/statusio_maintenance.py +++ b/ansible_collections/community/general/plugins/modules/statusio_maintenance.py @@ -188,6 +188,10 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.urls import open_url +from ansible_collections.community.general.plugins.module_utils.datetime import ( + now, +) + def get_api_auth_headers(api_id, api_key, url, statuspage): @@ -270,11 +274,11 @@ def get_date_time(start_date, start_time, minutes): except (NameError, ValueError): return 1, None, "Couldn't work out a valid date" else: - now = datetime.datetime.utcnow() - delta = now + datetime.timedelta(minutes=minutes) + now_t = now() + delta = now_t + datetime.timedelta(minutes=minutes) # start_date - returned_date.append(now.strftime("%m/%d/%Y")) - returned_date.append(now.strftime("%H:%M")) + returned_date.append(now_t.strftime("%m/%d/%Y")) + returned_date.append(now_t.strftime("%H:%M")) # end_date returned_date.append(delta.strftime("%m/%d/%Y")) returned_date.append(delta.strftime("%H:%M")) diff --git a/ansible_collections/community/general/plugins/modules/xml.py b/ansible_collections/community/general/plugins/modules/xml.py index a3c12b8ee..f5cdbeac3 100644 --- a/ansible_collections/community/general/plugins/modules/xml.py +++ b/ansible_collections/community/general/plugins/modules/xml.py @@ -436,11 +436,16 @@ def is_attribute(tree, xpath, namespaces): """ Test if a given xpath matches and that match is an attribute An xpath attribute search will only match one item""" + + # lxml 5.1.1 removed etree._ElementStringResult, so we can no longer simply assume it's there + # (https://github.com/lxml/lxml/commit/eba79343d0e7ad1ce40169f60460cdd4caa29eb3) + ElementStringResult = getattr(etree, '_ElementStringResult', None) + if xpath_matches(tree, xpath, namespaces): match = tree.xpath(xpath, namespaces=namespaces) - if isinstance(match[0], etree._ElementStringResult): + if isinstance(match[0], etree._ElementUnicodeResult): return True - elif isinstance(match[0], etree._ElementUnicodeResult): + elif ElementStringResult is not None and isinstance(match[0], ElementStringResult): return True return False diff --git a/ansible_collections/community/general/plugins/plugin_utils/unsafe.py b/ansible_collections/community/general/plugins/plugin_utils/unsafe.py new file mode 100644 index 000000000..1eb61bea0 --- /dev/null +++ b/ansible_collections/community/general/plugins/plugin_utils/unsafe.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, 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 re + +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.common._collections_compat import Mapping, Set +from ansible.module_utils.common.collections import is_sequence +from ansible.utils.unsafe_proxy import ( + AnsibleUnsafe, + wrap_var as _make_unsafe, +) + +_RE_TEMPLATE_CHARS = re.compile(u'[{}]') +_RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]') + + +def make_unsafe(value): + if value is None or isinstance(value, AnsibleUnsafe): + return value + + if isinstance(value, Mapping): + return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) + elif isinstance(value, Set): + return set(make_unsafe(elt) for elt in value) + elif is_sequence(value): + return type(value)(make_unsafe(elt) for elt in value) + elif isinstance(value, binary_type): + if _RE_TEMPLATE_CHARS_BYTES.search(value): + value = _make_unsafe(value) + return value + elif isinstance(value, text_type): + if _RE_TEMPLATE_CHARS.search(value): + value = _make_unsafe(value) + return value + + return value diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml index ec446d241..7ff30bcd5 100644 --- a/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml +++ b/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml @@ -15,6 +15,7 @@ tested_filesystems: # - 1.7.0 requires at least 30Mo # - 1.10.0 requires at least 38Mo # - resizefs asserts when initial fs is smaller than 60Mo and seems to require 1.10.0 + bcachefs: {fssize: 20, grow: true, new_uuid: null} ext4: {fssize: 10, grow: true, new_uuid: 'random'} ext4dev: {fssize: 10, grow: true, new_uuid: 'random'} ext3: {fssize: 10, grow: true, new_uuid: 'random'} diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml index 0c15c2155..51361079c 100644 --- a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml +++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml @@ -36,7 +36,7 @@ # Not available: btrfs, lvm, f2fs, ocfs2 # All BSD systems use swap fs, but only Linux needs mkswap # Supported: ext2/3/4 (e2fsprogs), xfs (xfsprogs), reiserfs (progsreiserfs), vfat - - 'not (ansible_system == "FreeBSD" and item.0.key in ["btrfs", "f2fs", "swap", "lvm", "ocfs2"])' + - 'not (ansible_system == "FreeBSD" and item.0.key in ["bcachefs", "btrfs", "f2fs", "swap", "lvm", "ocfs2"])' # Available on FreeBSD but not on testbed (util-linux conflicts with e2fsprogs): wipefs, mkfs.minix - 'not (ansible_system == "FreeBSD" and item.1 in ["overwrite_another_fs", "remove_fs"])' @@ -46,6 +46,10 @@ # Other limitations and corner cases + # bcachefs only on Alpine > 3.18 and Arch Linux for now + # other distributions have too old versions of bcachefs-tools and/or util-linux (blkid for UUID tests) + - 'ansible_distribution == "Alpine" and ansible_distribution_version is version("3.18", ">") and item.0.key == "bcachefs"' + - 'ansible_distribution == "Archlinux" and item.0.key == "bcachefs"' # f2fs-tools and reiserfs-utils packages not available with RHEL/CentOS on CI - 'not (ansible_distribution in ["CentOS", "RedHat"] and item.0.key in ["f2fs", "reiserfs"])' - 'not (ansible_os_family == "RedHat" and ansible_distribution_major_version is version("8", ">=") and diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml index 97dafaeee..77c028aca 100644 --- a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml +++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml @@ -16,6 +16,16 @@ - e2fsprogs - xfsprogs +- name: "Install bcachefs tools" + ansible.builtin.package: + name: bcachefs-tools + state: present + when: + # bcachefs only on Alpine > 3.18 and Arch Linux for now + # other distributions have too old versions of bcachefs-tools and/or util-linux (blkid for UUID tests) + - ansible_distribution == "Alpine" and ansible_distribution_version is version("3.18", ">") + - ansible_distribution == "Archlinux" + - name: "Install btrfs progs" ansible.builtin.package: name: btrfs-progs diff --git a/ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml index a2eca36a6..abb92dfc5 100644 --- a/ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml +++ b/ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml @@ -12,15 +12,21 @@ another_section: connection: 'ssh' + interpolate_test: + interpolate_test_key: '%' + - name: 'Write INI file that reflects ini_test_dict to {{ ini_test_file }}' ansible.builtin.copy: dest: '{{ ini_test_file }}' content: | [section_name] - key_name=key value + key_name = key value [another_section] - connection=ssh + connection = ssh + + [interpolate_test] + interpolate_test_key = % - name: 'Slurp the test file: {{ ini_test_file }}' ansible.builtin.slurp: diff --git a/ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml index 877d4471d..e16aa98a5 100644 --- a/ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml +++ b/ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml @@ -16,6 +16,9 @@ another_section: connection: 'ssh' + interpolate_test: + interpolate_test_key: '%' + - name: 'Write INI file manually to {{ ini_test_file }}' ansible.builtin.copy: dest: '{{ ini_test_file }}' @@ -26,6 +29,9 @@ [another_section] connection = ssh + [interpolate_test] + interpolate_test_key = % + - name: 'Slurp the manually created test file: {{ ini_test_file }}' ansible.builtin.slurp: src: '{{ ini_test_file }}' diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml index 9f52dc122..b4538200f 100644 --- a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml +++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml @@ -52,6 +52,38 @@ - removal_result is not changed msg: "Removing an absent flatpak shall mark module execution as not changed" +# state=latest on absent flatpak + +- name: Test state=latest of absent flatpak (check mode) + flatpak: + name: com.dummy.App1 + remote: dummy-remote + state: latest + register: latest_result + check_mode: true + +- name: Verify state=latest of absent flatpak test result (check mode) + assert: + that: + - latest_result is changed + msg: "state=latest an absent flatpak shall mark module execution as changed" + +- name: Test non-existent idempotency of state=latest of absent flatpak (check mode) + flatpak: + name: com.dummy.App1 + remote: dummy-remote + state: latest + register: double_latest_result + check_mode: true + +- name: Verify non-existent idempotency of state=latest of absent flatpak test result (check mode) + assert: + that: + - double_latest_result is changed + msg: | + state=latest an absent flatpak a second time shall still mark module execution + as changed in check mode + # state=present with url on absent flatpak - name: Test addition of absent flatpak with url (check mode) @@ -101,6 +133,40 @@ - url_removal_result is not changed msg: "Removing an absent flatpak shall mark module execution as not changed" +# state=latest with url on absent flatpak + +- name: Test state=latest of absent flatpak with url (check mode) + flatpak: + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote + state: latest + register: url_latest_result + check_mode: true + +- name: Verify state=latest of absent flatpak with url test result (check mode) + assert: + that: + - url_latest_result is changed + msg: "state=latest an absent flatpak from URL shall mark module execution as changed" + +- name: Test non-existent idempotency of state=latest of absent flatpak with url (check mode) + flatpak: + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote + state: latest + register: double_url_latest_result + check_mode: true + +- name: > + Verify non-existent idempotency of additionof state=latest flatpak with url test + result (check mode) + assert: + that: + - double_url_latest_result is changed + msg: | + state=latest an absent flatpak from URL a second time shall still mark module execution + as changed in check mode + # - Tests with present flatpak ------------------------------------------------- # state=present on present flatpak @@ -149,6 +215,22 @@ Removing a present flatpak a second time shall still mark module execution as changed in check mode +# state=latest on present flatpak + +- name: Test state=latest of present flatpak (check mode) + flatpak: + name: com.dummy.App2 + remote: dummy-remote + state: latest + register: latest_present_result + check_mode: true + +- name: Verify latest test result of present flatpak (check mode) + assert: + that: + - latest_present_result is changed + msg: "state=latest an present flatpak shall mark module execution as changed" + # state=present with url on present flatpak - name: Test addition with url of present flatpak (check mode) @@ -195,3 +277,19 @@ that: - double_url_removal_present_result is changed msg: Removing an absent flatpak a second time shall still mark module execution as changed + +# state=latest with url on present flatpak + +- name: Test state=latest with url of present flatpak (check mode) + flatpak: + name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + remote: dummy-remote + state: latest + register: url_latest_present_result + check_mode: true + +- name: Verify state=latest with url of present flatpak test result (check mode) + assert: + that: + - url_latest_present_result is changed + msg: "state=latest a present flatpak from URL shall mark module execution as changed" diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml index 29c4efbe9..658f7b116 100644 --- a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml +++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml @@ -65,6 +65,45 @@ - double_removal_result is not changed msg: "state=absent shall not do anything when flatpak is not present" +# state=latest + +- name: Test state=latest - {{ method }} + flatpak: + name: com.dummy.App1 + remote: dummy-remote + state: present + method: "{{ method }}" + no_dependencies: true + register: latest_result + +- name: Verify state=latest test result - {{ method }} + assert: + that: + - latest_result is changed + msg: "state=latest shall add flatpak when absent" + +- name: Test idempotency of state=latest - {{ method }} + flatpak: + name: com.dummy.App1 + remote: dummy-remote + state: present + method: "{{ method }}" + no_dependencies: true + register: double_latest_result + +- name: Verify idempotency of state=latest test result - {{ method }} + assert: + that: + - double_latest_result is not changed + msg: "state=latest shall not do anything when flatpak is already present" + +- name: Cleanup after state=present test - {{ method }} + flatpak: + name: com.dummy.App1 + state: absent + method: "{{ method }}" + no_dependencies: true + # state=present with url as name - name: Test addition with url - {{ method }} @@ -152,6 +191,45 @@ method: "{{ method }}" no_dependencies: true +# state=latest with url as name + +- name: Test state=latest with url - {{ method }} + flatpak: + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote + state: latest + method: "{{ method }}" + no_dependencies: true + register: url_latest_result + +- name: Verify state=latest test result - {{ method }} + assert: + that: + - url_latest_result is changed + msg: "state=present with url as name shall add flatpak when absent" + +- name: Test idempotency of state=latest with url - {{ method }} + flatpak: + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote + state: latest + method: "{{ method }}" + no_dependencies: true + register: double_url_latest_result + +- name: Verify idempotency of state=latest with url test result - {{ method }} + assert: + that: + - double_url_latest_result is not changed + msg: "state=present with url as name shall not do anything when flatpak is already present" + +- name: Cleanup after state=present with url test - {{ method }} + flatpak: + name: com.dummy.App1 + state: absent + method: "{{ method }}" + no_dependencies: true + # state=present with list of packages - name: Test addition with list - {{ method }} @@ -287,3 +365,84 @@ that: - double_removal_result is not changed msg: "state=absent shall not do anything when flatpak is not present" + +# state=latest with list of packages + +- name: Test state=latest with list - {{ method }} + flatpak: + name: + - com.dummy.App1 + - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + remote: dummy-remote + state: latest + method: "{{ method }}" + no_dependencies: true + register: latest_result + +- name: Verify state=latest with list test result - {{ method }} + assert: + that: + - latest_result is changed + msg: "state=present shall add flatpak when absent" + +- name: Test idempotency of state=latest with list - {{ method }} + flatpak: + name: + - com.dummy.App1 + - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + remote: dummy-remote + state: latest + method: "{{ method }}" + no_dependencies: true + register: double_latest_result + +- name: Verify idempotency of state=latest with list test result - {{ method }} + assert: + that: + - double_latest_result is not changed + msg: "state=present shall not do anything when flatpak is already present" + +- name: Test state=latest with list partially installed - {{ method }} + flatpak: + name: + - com.dummy.App1 + - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + - com.dummy.App3 + remote: dummy-remote + state: latest + method: "{{ method }}" + no_dependencies: true + register: latest_result + +- name: Verify state=latest with list partially installed test result - {{ method }} + assert: + that: + - latest_result is changed + msg: "state=present shall add flatpak when absent" + +- name: Test idempotency of state=latest with list partially installed - {{ method }} + flatpak: + name: + - com.dummy.App1 + - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + - com.dummy.App3 + remote: dummy-remote + state: latest + method: "{{ method }}" + no_dependencies: true + register: double_latest_result + +- name: Verify idempotency of state=latest with list partially installed test result - {{ method }} + assert: + that: + - double_latest_result is not changed + msg: "state=present shall not do anything when flatpak is already present" + +- name: Cleanup after state=present with list test - {{ method }} + flatpak: + name: + - com.dummy.App1 + - com.dummy.App2 + - com.dummy.App3 + state: absent + method: "{{ method }}" diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml index 0ed3c2817..8fd88074b 100644 --- a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml +++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml @@ -16,7 +16,6 @@ - name: include tasks block: - - name: include tasks to perform basic tests include_tasks: tests/00-basic.yml @@ -50,3 +49,6 @@ - name: include tasks to test optional spaces in section headings include_tasks: tests/07-section_name_spaces.yml + + - name: include tasks to test section_has_values + include_tasks: tests/08-section.yml diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml new file mode 100644 index 000000000..4f3a135e1 --- /dev/null +++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml @@ -0,0 +1,341 @@ +--- +# 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 + +## testing section selection + +- name: test-section 1 - Create starting ini file + copy: + content: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + fav = lemonade + beverage = pineapple juice + + dest: "{{ output_file }}" + +- name: test-section 1 - Modify starting ini file + ini_file: + dest: "{{ output_file }}" + section: drinks + option: car + value: volvo + state: present + register: result1 + +- name: test-section 1 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 1 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + car = volvo + + [drinks] + fav = lemonade + beverage = pineapple juice + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 1 - Option was added to first section + assert: + that: + - result1 is changed + - result1.msg == 'option added' + - output1 == expected1 + +# ---------------- + +- name: test-section 2 - Create starting ini file + copy: + content: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + fav = lemonade + beverage = pineapple juice + + dest: "{{ output_file }}" + +- name: test-section 2 - Modify starting ini file + ini_file: + dest: "{{ output_file }}" + section: drinks + section_has_values: + - option: beverage + value: pineapple juice + option: car + value: volvo + state: present + register: result1 + +- name: test-section 2 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 2 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + fav = lemonade + beverage = pineapple juice + car = volvo + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 2 - Option added to second section specified with section_has_values + assert: + that: + - result1 is changed + - result1.msg == 'option added' + - output1 == expected1 + +# ---------------- + +- name: test-section 3 - Create starting ini file + copy: + content: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + fav = lemonade + beverage = pineapple juice + + dest: "{{ output_file }}" + +- name: test-section 3 - Modify starting ini file + ini_file: + dest: "{{ output_file }}" + section: drinks + section_has_values: + - option: beverage + value: pineapple juice + option: fav + value: lemonade + state: absent + register: result1 + +- name: test-section 3 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 3 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + beverage = pineapple juice + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 3 - Option was removed from specified section + assert: + that: + - result1 is changed + - result1.msg == 'option changed' + - output1 == expected1 + +# ---------------- + +- name: test-section 4 - Create starting ini file + copy: + content: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + fav = lemonade + beverage = pineapple juice + + dest: "{{ output_file }}" + +- name: test-section 4 - Modify starting ini file + ini_file: + dest: "{{ output_file }}" + section: drinks + section_has_values: + - option: beverage + value: alligator slime + option: fav + value: tea + state: present + register: result1 + +- name: test-section 4 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 4 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + fav = lemonade + beverage = pineapple juice + [drinks] + beverage = alligator slime + fav = tea + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 4 - New section created, including required values + assert: + that: + - result1 is changed + - result1.msg == 'section and option added' + - output1 == expected1 + +# ---------------- + +- name: test-section 5 - Modify test-section 4 result file + ini_file: + dest: "{{ output_file }}" + section: drinks + section_has_values: + - option: fav + value: lemonade + - option: beverage + value: pineapple juice + state: absent + register: result1 + +- name: test-section 5 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 5 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + beverage = alligator slime + fav = tea + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 5 - Section removed as specified + assert: + that: + - result1 is changed + - result1.msg == 'section removed' + - output1 == expected1 + +# ---------------- + +- name: test-section 6 - Modify test-section 5 result file with multiple values + ini_file: + dest: "{{ output_file }}" + section: drinks + section_has_values: + - option: fav + values: + - cherry + - lemon + - vanilla + - option: beverage + value: pineapple juice + state: present + option: fav + values: + - vanilla + - grape + exclusive: false + register: result1 + +- name: test-section 6 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 6 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + beverage = alligator slime + fav = tea + [drinks] + beverage = pineapple juice + fav = vanilla + fav = grape + fav = cherry + fav = lemon + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 6 - New section added + assert: + that: + - result1 is changed + - result1.msg == 'section and option added' + - output1 == expected1 + +# ---------------- + +- name: test-section 7 - Modify test-section 6 result file with exclusive value + ini_file: + dest: "{{ output_file }}" + section: drinks + section_has_values: + - option: fav + value: vanilla + state: present + option: fav + value: cherry + exclusive: true + register: result1 + +- name: test-section 7 - Read modified file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: test-section 7 - Create expected result + set_fact: + expected1: | + [drinks] + fav = lemonade + beverage = orange juice + + [drinks] + beverage = alligator slime + fav = tea + [drinks] + beverage = pineapple juice + fav = cherry + output1: "{{ output_content.content | b64decode }}" + +- name: test-section 7 - Option changed + assert: + that: + - result1 is changed + - result1.msg == 'option changed' + - output1 == expected1 diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md new file mode 100644 index 000000000..cd1152dad --- /dev/null +++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md @@ -0,0 +1,20 @@ +<!-- +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 +--> +# Running keycloak_client_rolescope module integration test + +To run Keycloak component info module's integration test, start a keycloak server using Docker: + + docker run -d --rm --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth + +Run integration tests: + + ansible-test integration -v keycloak_client_rolescope --allow-unsupported --docker fedora35 --docker-network host + +Cleanup: + + docker stop mykeycloak + + diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/aliases new file mode 100644 index 000000000..bd1f02444 --- /dev/null +++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/aliases @@ -0,0 +1,5 @@ +# 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 + +unsupported diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml new file mode 100644 index 000000000..8675c9548 --- /dev/null +++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml @@ -0,0 +1,317 @@ +--- +# 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: Wait for Keycloak + uri: + url: "{{ url }}/admin/" + status_code: 200 + validate_certs: no + register: result + until: result.status == 200 + retries: 10 + delay: 10 + +- name: Delete realm if exists + community.general.keycloak_realm: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + state: absent + +- name: Create realm + community.general.keycloak_realm: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + id: "{{ realm }}" + realm: "{{ realm }}" + state: present + +- name: Create a Keycloak realm role + community.general.keycloak_role: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: "{{ item }}" + realm: "{{ realm }}" + with_items: + - "{{ realm_role_admin }}" + - "{{ realm_role_user }}" + +- name: Client private + community.general.keycloak_client: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_private }}" + state: present + redirect_uris: + - "https://my-backend-api.c.org/" + fullScopeAllowed: True + attributes: '{{client_attributes1}}' + public_client: False + +- name: Create a Keycloak client role + community.general.keycloak_role: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + name: "{{ item }}" + realm: "{{ realm }}" + client_id: "{{ client_name_private }}" + with_items: + - "{{ client_role_admin }}" + - "{{ client_role_user }}" + +- name: Client public + community.general.keycloak_client: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + redirect_uris: + - "https://my-onepage-app-frontend.c.org/" + attributes: '{{client_attributes1}}' + full_scope_allowed: False + public_client: True + + +- name: Map roles to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + client_scope_id: "{{ client_name_private }}" + role_names: + - "{{ client_role_admin }}" + - "{{ client_role_user }}" + register: result + +- name: Assert mapping created + assert: + that: + - result is changed + - result.end_state | length == 2 + +- name: remap role user to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + client_scope_id: "{{ client_name_private }}" + role_names: + - "{{ client_role_user }}" + register: result + +- name: Assert mapping created + assert: + that: + - result is not changed + - result.end_state | length == 2 + +- name: Remove Map role admin to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + client_scope_id: "{{ client_name_private }}" + role_names: + - "{{ client_role_admin }}" + state: absent + register: result + +- name: Assert mapping deleted + assert: + that: + - result is changed + - result.end_state | length == 1 + - result.end_state[0].name == client_role_user + +- name: Map missing roles to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + client_scope_id: "{{ client_name_private }}" + role_names: + - "{{ client_role_admin }}" + - "{{ client_role_not_exists }}" + ignore_errors: true + register: result + +- name: Assert failed mapping missing role + assert: + that: + - result is failed + +- name: Map roles duplicate + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + client_scope_id: "{{ client_name_private }}" + role_names: + - "{{ client_role_admin }}" + - "{{ client_role_admin }}" + register: result + +- name: Assert result + assert: + that: + - result is changed + - result.end_state | length == 2 + +- name: Map roles to private client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_private }}" + role_names: + - "{{ realm_role_admin }}" + ignore_errors: true + register: result + +- name: Assert failed mapping role to full scope client + assert: + that: + - result is failed + +- name: Map realm role to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + role_names: + - "{{ realm_role_admin }}" + register: result + +- name: Assert result + assert: + that: + - result is changed + - result.end_state | length == 1 + +- name: Map two realm roles to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + role_names: + - "{{ realm_role_admin }}" + - "{{ realm_role_user }}" + register: result + +- name: Assert result + assert: + that: + - result is changed + - result.end_state | length == 2 + +- name: Unmap all realm roles to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + role_names: + - "{{ realm_role_admin }}" + - "{{ realm_role_user }}" + state: absent + register: result + +- name: Assert result + assert: + that: + - result is changed + - result.end_state | length == 0 + +- name: Map missing realm role to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + role_names: + - "{{ realm_role_not_exists }}" + ignore_errors: true + register: result + +- name: Assert failed mapping missing realm role + assert: + that: + - result is failed + +- name: Check-mode try to Map realm roles to public client + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + role_names: + - "{{ realm_role_admin }}" + - "{{ realm_role_user }}" + check_mode: true + register: result + +- name: Assert result + assert: + that: + - result is changed + - result.end_state | length == 2 + +- name: Check-mode step two, check if change where applied + community.general.keycloak_client_rolescope: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + client_id: "{{ client_name_public }}" + role_names: [] + register: result + +- name: Assert result + assert: + that: + - result is not changed + - result.end_state | length == 0
\ No newline at end of file diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.yml new file mode 100644 index 000000000..8bd59398b --- /dev/null +++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.yml @@ -0,0 +1,26 @@ +--- +# 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 + +url: http://localhost:8080/auth +admin_realm: master +admin_user: admin +admin_password: password +realm: myrealm + + +client_name_private: backend-client-private +client_role_admin: client-role-admin +client_role_user: client-role-user +client_role_not_exists: client-role-missing + +client_name_public: frontend-client-public + + +realm_role_admin: realm-role-admin +realm_role_user: realm-role-user +realm_role_not_exists: client-role-missing + + +client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false, "client.secret.creation.time": 0} diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml index 217c020ca..8a88bca45 100644 --- a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml +++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml @@ -19,13 +19,13 @@ - item.0 == 'nl' - item.1 == 'Netherlands' vars: - - lmdb_kv_db: jp.mdb + lmdb_kv_db: jp.mdb with_community.general.lmdb_kv: - n* - assert: that: - item == 'Belgium' vars: - - lmdb_kv_db: jp.mdb + lmdb_kv_db: jp.mdb with_community.general.lmdb_kv: - be diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.18.txt b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..d75aaeac2 --- /dev/null +++ b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt @@ -0,0 +1,17 @@ +plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice +plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' +plugins/modules/homectl.py import-3.12 # Uses deprecated stdlib library 'crypt' +plugins/modules/iptables_state.py validate-modules:undocumented-parameter # params _back and _timeout used by action plugin +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/test_gio_mime.yaml no-smart-quotes diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/general/tests/sanity/ignore-2.18.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/general/tests/unit/plugins/callback/test_loganalytics.py b/ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py index 17932ed5f..4d7c2c9db 100644 --- a/ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py +++ b/ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py @@ -9,8 +9,8 @@ from ansible.executor.task_result import TaskResult from ansible_collections.community.general.tests.unit.compat import unittest from ansible_collections.community.general.tests.unit.compat.mock import patch, Mock from ansible_collections.community.general.plugins.callback.loganalytics import AzureLogAnalyticsSource -from datetime import datetime +from datetime import datetime import json import sys @@ -32,10 +32,10 @@ class TestAzureLogAnalytics(unittest.TestCase): if sys.version_info < (3, 2): self.assertRegex = self.assertRegexpMatches - @patch('ansible_collections.community.general.plugins.callback.loganalytics.datetime') + @patch('ansible_collections.community.general.plugins.callback.loganalytics.now') @patch('ansible_collections.community.general.plugins.callback.loganalytics.open_url') - def test_overall(self, open_url_mock, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2020, 12, 1) + def test_overall(self, open_url_mock, mock_now): + mock_now.return_value = datetime(2020, 12, 1) result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields) self.loganalytics.send_event(workspace_id='01234567-0123-0123-0123-01234567890a', @@ -52,10 +52,10 @@ class TestAzureLogAnalytics(unittest.TestCase): self.assertEqual(sent_data['event']['uuid'], 'myuuid') self.assertEqual(args[0], 'https://01234567-0123-0123-0123-01234567890a.ods.opinsights.azure.com/api/logs?api-version=2016-04-01') - @patch('ansible_collections.community.general.plugins.callback.loganalytics.datetime') + @patch('ansible_collections.community.general.plugins.callback.loganalytics.now') @patch('ansible_collections.community.general.plugins.callback.loganalytics.open_url') - def test_auth_headers(self, open_url_mock, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2020, 12, 1) + def test_auth_headers(self, open_url_mock, mock_now): + mock_now.return_value = datetime(2020, 12, 1) result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields) self.loganalytics.send_event(workspace_id='01234567-0123-0123-0123-01234567890a', diff --git a/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py b/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py index ddcdae24c..c09540fc0 100644 --- a/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py +++ b/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py @@ -27,10 +27,10 @@ class TestSplunkClient(unittest.TestCase): self.mock_host = Mock('MockHost') self.mock_host.name = 'myhost' - @patch('ansible_collections.community.general.plugins.callback.splunk.datetime') + @patch('ansible_collections.community.general.plugins.callback.splunk.now') @patch('ansible_collections.community.general.plugins.callback.splunk.open_url') - def test_timestamp_with_milliseconds(self, open_url_mock, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2020, 12, 1) + def test_timestamp_with_milliseconds(self, open_url_mock, mock_now): + mock_now.return_value = datetime(2020, 12, 1) result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields) self.splunk.send_event( @@ -45,10 +45,10 @@ class TestSplunkClient(unittest.TestCase): self.assertEqual(sent_data['event']['host'], 'my-host') self.assertEqual(sent_data['event']['ip_address'], '1.2.3.4') - @patch('ansible_collections.community.general.plugins.callback.splunk.datetime') + @patch('ansible_collections.community.general.plugins.callback.splunk.now') @patch('ansible_collections.community.general.plugins.callback.splunk.open_url') - def test_timestamp_without_milliseconds(self, open_url_mock, mock_datetime): - mock_datetime.utcnow.return_value = datetime(2020, 12, 1) + def test_timestamp_without_milliseconds(self, open_url_mock, mock_now): + mock_now.return_value = datetime(2020, 12, 1) result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields) self.splunk.send_event( diff --git a/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py b/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py index 9270dd44e..04cad8d6c 100644 --- a/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py +++ b/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py @@ -6,6 +6,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +import re from ansible_collections.community.general.tests.unit.compat import unittest from ansible_collections.community.general.tests.unit.compat.mock import patch @@ -13,8 +14,10 @@ from ansible.errors import AnsibleError from ansible.module_utils import six from ansible.plugins.loader import lookup_loader from ansible_collections.community.general.plugins.lookup.bitwarden import Bitwarden +from ansible.parsing.ajson import AnsibleJSONEncoder MOCK_COLLECTION_ID = "3b12a9da-7c49-40b8-ad33-aede017a7ead" +MOCK_ORGANIZATION_ID = "292ba0c6-f289-11ee-9301-ef7b639ccd2a" MOCK_RECORDS = [ { @@ -48,7 +51,7 @@ MOCK_RECORDS = [ "name": "a_test", "notes": None, "object": "item", - "organizationId": None, + "organizationId": MOCK_ORGANIZATION_ID, "passwordHistory": [ { "lastUsedDate": "2022-07-26T23:03:23.405Z", @@ -68,9 +71,7 @@ MOCK_RECORDS = [ "type": 1 }, { - "collectionIds": [ - MOCK_COLLECTION_ID - ], + "collectionIds": [], "deletedDate": None, "favorite": False, "folderId": None, @@ -106,10 +107,30 @@ MOCK_RECORDS = [ "name": "dupe_name", "notes": None, "object": "item", - "organizationId": None, + "organizationId": MOCK_ORGANIZATION_ID, "reprompt": 0, "revisionDate": "2022-07-27T03:42:46.673Z", "type": 1 + }, + { + "collectionIds": [], + "deletedDate": None, + "favorite": False, + "folderId": None, + "id": "2bf517be-fb13-11ee-be89-a345aa369a94", + "login": { + "password": "e", + "passwordRevisionDate": None, + "totp": None, + "username": "f" + }, + "name": "non_collection_org_record", + "notes": None, + "object": "item", + "organizationId": MOCK_ORGANIZATION_ID, + "reprompt": 0, + "revisionDate": "2024-14-15T11:30:00.000Z", + "type": 1 } ] @@ -118,11 +139,41 @@ class MockBitwarden(Bitwarden): unlocked = True - def _get_matches(self, search_value=None, search_field="name", collection_id=None): - if not search_value and collection_id: - return list(filter(lambda record: collection_id in record['collectionIds'], MOCK_RECORDS)) + def _run(self, args, stdin=None, expected_rc=0): + if args[0] == 'get': + if args[1] == 'item': + for item in MOCK_RECORDS: + if item.get('id') == args[2]: + return AnsibleJSONEncoder().encode(item), '' + if args[0] == 'list': + if args[1] == 'items': + try: + search_value = args[args.index('--search') + 1] + except ValueError: + search_value = None + + try: + collection_to_filter = args[args.index('--collectionid') + 1] + except ValueError: + collection_to_filter = None + + try: + organization_to_filter = args[args.index('--organizationid') + 1] + except ValueError: + organization_to_filter = None + + items = [] + for item in MOCK_RECORDS: + if search_value and not re.search(search_value, item.get('name')): + continue + if collection_to_filter and collection_to_filter not in item.get('collectionIds', []): + continue + if organization_to_filter and item.get('organizationId') != organization_to_filter: + continue + items.append(item) + return AnsibleJSONEncoder().encode(items), '' - return list(filter(lambda record: record[search_field] == search_value, MOCK_RECORDS)) + return '[]', '' class LoggedOutMockBitwarden(MockBitwarden): @@ -194,4 +245,19 @@ class TestLookupModule(unittest.TestCase): @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden()) def test_bitwarden_plugin_full_collection(self): # Try to retrieve the full records of the given collection. - self.assertEqual(MOCK_RECORDS, self.lookup.run(None, collection_id=MOCK_COLLECTION_ID)[0]) + self.assertEqual([MOCK_RECORDS[0], MOCK_RECORDS[2]], self.lookup.run(None, collection_id=MOCK_COLLECTION_ID)[0]) + + @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden()) + def test_bitwarden_plugin_full_organization(self): + self.assertEqual([MOCK_RECORDS[0], MOCK_RECORDS[2], MOCK_RECORDS[3]], + self.lookup.run(None, organization_id=MOCK_ORGANIZATION_ID)[0]) + + @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden()) + def test_bitwarden_plugin_filter_organization(self): + self.assertEqual([MOCK_RECORDS[2]], + self.lookup.run(['dupe_name'], organization_id=MOCK_ORGANIZATION_ID)[0]) + + @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden()) + def test_bitwarden_plugin_full_collection_organization(self): + self.assertEqual([MOCK_RECORDS[0], MOCK_RECORDS[2]], self.lookup.run(None, + collection_id=MOCK_COLLECTION_ID, organization_id=MOCK_ORGANIZATION_ID)[0]) diff --git a/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml b/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml index 1e66b7d29..6aadd1b4f 100644 --- a/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/hrobot/.github/workflows/ansible-test.yml @@ -34,6 +34,7 @@ jobs: - 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 @@ -75,6 +76,7 @@ jobs: - stable-2.14 - stable-2.15 - stable-2.16 + - stable-2.17 - devel steps: diff --git a/ansible_collections/community/hrobot/.github/workflows/docs-pr.yml b/ansible_collections/community/hrobot/.github/workflows/docs-pr.yml index c5d5c24b5..3d1b87a86 100644 --- a/ansible_collections/community/hrobot/.github/workflows/docs-pr.yml +++ b/ansible_collections/community/hrobot/.github/workflows/docs-pr.yml @@ -32,6 +32,7 @@ jobs: documentation_home_url=https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/branch/main/ squash-hierarchy: true render-file-line: '> * `$<status>` [$<path_tail>](https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr/${{ github.event.number }}/$<path_tail>)' + extra-collections: community.library_inventory_filtering_v1 publish-docs-gh-pages: # for now we won't run this on forks diff --git a/ansible_collections/community/hrobot/.github/workflows/docs-push.yml b/ansible_collections/community/hrobot/.github/workflows/docs-push.yml index e1db3c2eb..783ff30e1 100644 --- a/ansible_collections/community/hrobot/.github/workflows/docs-push.yml +++ b/ansible_collections/community/hrobot/.github/workflows/docs-push.yml @@ -37,6 +37,7 @@ jobs: init-extra-html-theme-options: | documentation_home_url=https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/branch/main/ squash-hierarchy: true + extra-collections: community.library_inventory_filtering_v1 publish-docs-gh-pages: # for now we won't run this on forks diff --git a/ansible_collections/community/hrobot/CHANGELOG.md b/ansible_collections/community/hrobot/CHANGELOG.md index d09d85be0..fec73109e 100644 --- a/ansible_collections/community/hrobot/CHANGELOG.md +++ b/ansible_collections/community/hrobot/CHANGELOG.md @@ -2,74 +2,90 @@ **Topics** -- <a href="#v1-9-1">v1\.9\.1</a> +- <a href="#v1-9-2">v1\.9\.2</a> - <a href="#release-summary">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="#security-fixes">Security Fixes</a> - <a href="#v1-9-0">v1\.9\.0</a> - - <a href="#release-summary-1">Release Summary</a> + - <a href="#release-summary-2">Release Summary</a> - <a href="#minor-changes">Minor Changes</a> - <a href="#deprecated-features">Deprecated Features</a> - <a href="#v1-8-2">v1\.8\.2</a> - - <a href="#release-summary-2">Release Summary</a> - - <a href="#bugfixes">Bugfixes</a> -- <a href="#v1-8-1">v1\.8\.1</a> - <a href="#release-summary-3">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="#known-issues">Known Issues</a> - <a href="#v1-8-0">v1\.8\.0</a> - - <a href="#release-summary-4">Release Summary</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-5">Release Summary</a> + - <a href="#release-summary-6">Release Summary</a> - <a href="#new-modules">New Modules</a> - <a href="#v1-6-0">v1\.6\.0</a> - - <a href="#release-summary-6">Release Summary</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-7">Release Summary</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="#release-summary-8">Release Summary</a> -- <a href="#v1-5-0">v1\.5\.0</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="#release-summary-10">Release Summary</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="#release-summary-11">Release Summary</a> - - <a href="#bugfixes-1">Bugfixes</a> -- <a href="#v1-3-0">v1\.3\.0</a> - <a href="#release-summary-12">Release Summary</a> - - <a href="#minor-changes-6">Minor Changes</a> - <a href="#bugfixes-2">Bugfixes</a> -- <a href="#v1-2-3">v1\.2\.3</a> +- <a href="#v1-3-0">v1\.3\.0</a> - <a href="#release-summary-13">Release Summary</a> -- <a href="#v1-2-2">v1\.2\.2</a> - - <a href="#release-summary-14">Release Summary</a> + - <a href="#minor-changes-6">Minor Changes</a> - <a href="#bugfixes-3">Bugfixes</a> -- <a href="#v1-2-1">v1\.2\.1</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="#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-16">Release Summary</a> + - <a href="#release-summary-17">Release Summary</a> - <a href="#minor-changes-8">Minor Changes</a> - <a href="#new-modules-1">New Modules</a> - <a href="#v1-1-1">v1\.1\.1</a> - - <a href="#release-summary-17">Release Summary</a> - - <a href="#bugfixes-4">Bugfixes</a> -- <a href="#v1-1-0">v1\.1\.0</a> - <a href="#release-summary-18">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="#new-plugins">New Plugins</a> - <a href="#inventory">Inventory</a> - <a href="#v1-0-0">v1\.0\.0</a> - - <a href="#release-summary-19">Release Summary</a> + - <a href="#release-summary-20">Release Summary</a> - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a> +<a id="v1-9-2"></a> +## v1\.9\.2 + +<a id="release-summary"></a> +### Release Summary + +Bugfix release\. + +<a id="bugfixes"></a> +### Bugfixes + +* 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\.hrobot/pull/102](https\://github\.com/ansible\-collections/community\.hrobot/pull/102)\)\. + <a id="v1-9-1"></a> ## v1\.9\.1 -<a id="release-summary"></a> +<a id="release-summary-1"></a> ### Release Summary Bugfix release\. @@ -82,7 +98,7 @@ Bugfix release\. <a id="v1-9-0"></a> ## v1\.9\.0 -<a id="release-summary-1"></a> +<a id="release-summary-2"></a> ### Release Summary Feature and maintenance release\. @@ -100,12 +116,12 @@ Feature and maintenance release\. <a id="v1-8-2"></a> ## v1\.8\.2 -<a id="release-summary-2"></a> +<a id="release-summary-3"></a> ### Release Summary Maintenance release with updated documentation\. -<a id="bugfixes"></a> +<a id="bugfixes-1"></a> ### Bugfixes * Show more information \(if available\) from error messages \([https\://github\.com/ansible\-collections/community\.hrobot/pull/89](https\://github\.com/ansible\-collections/community\.hrobot/pull/89)\)\. @@ -113,7 +129,7 @@ Maintenance release with updated documentation\. <a id="v1-8-1"></a> ## v1\.8\.1 -<a id="release-summary-3"></a> +<a id="release-summary-4"></a> ### Release Summary Maintenance release with updated documentation\. @@ -134,7 +150,7 @@ 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-4"></a> +<a id="release-summary-5"></a> ### Release Summary Feature release for the Hetzner firewall changes\. @@ -153,7 +169,7 @@ Feature release for the Hetzner firewall changes\. <a id="v1-7-0"></a> ## v1\.7\.0 -<a id="release-summary-5"></a> +<a id="release-summary-6"></a> ### Release Summary Feature release\. @@ -166,7 +182,7 @@ Feature release\. <a id="v1-6-0"></a> ## v1\.6\.0 -<a id="release-summary-6"></a> +<a id="release-summary-7"></a> ### Release Summary Feature release with improved documentation\. @@ -179,7 +195,7 @@ Feature release with improved documentation\. <a id="v1-5-2"></a> ## v1\.5\.2 -<a id="release-summary-7"></a> +<a id="release-summary-8"></a> ### Release Summary Maintenance release with a documentation improvement\. @@ -192,7 +208,7 @@ Maintenance release with a documentation improvement\. <a id="v1-5-1"></a> ## v1\.5\.1 -<a id="release-summary-8"></a> +<a id="release-summary-9"></a> ### Release Summary Maintenance release with small documentation fixes\. @@ -200,7 +216,7 @@ Maintenance release with small documentation fixes\. <a id="v1-5-0"></a> ## v1\.5\.0 -<a id="release-summary-9"></a> +<a id="release-summary-10"></a> ### Release Summary Maintenance release changing the way licenses are declared\. No functional changes\. @@ -213,7 +229,7 @@ Maintenance release changing the way licenses are declared\. No functional chang <a id="v1-4-0"></a> ## v1\.4\.0 -<a id="release-summary-10"></a> +<a id="release-summary-11"></a> ### Release Summary Feature release\. @@ -226,12 +242,12 @@ Feature release\. <a id="v1-3-1"></a> ## v1\.3\.1 -<a id="release-summary-11"></a> +<a id="release-summary-12"></a> ### Release Summary Maintenance release\. -<a id="bugfixes-1"></a> +<a id="bugfixes-2"></a> ### Bugfixes * Include <code>simplified\_bsd\.txt</code> license file for the <code>robot</code> and <code>failover</code> module utils\. @@ -239,7 +255,7 @@ Maintenance release\. <a id="v1-3-0"></a> ## v1\.3\.0 -<a id="release-summary-12"></a> +<a id="release-summary-13"></a> ### Release Summary Feature and bugfix release\. @@ -249,7 +265,7 @@ Feature and bugfix release\. * 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)\)\. -<a id="bugfixes-2"></a> +<a id="bugfixes-3"></a> ### Bugfixes * robot inventory plugin \- do not crash if a server neither has name or primary IP set\. Instead\, fall back to using the server\'s number as the name\. This can happen if unnamed rack reservations show up in your server list \([https\://github\.com/ansible\-collections/community\.hrobot/issues/40](https\://github\.com/ansible\-collections/community\.hrobot/issues/40)\, [https\://github\.com/ansible\-collections/community\.hrobot/pull/47](https\://github\.com/ansible\-collections/community\.hrobot/pull/47)\)\. @@ -257,7 +273,7 @@ Feature and bugfix release\. <a id="v1-2-3"></a> ## v1\.2\.3 -<a id="release-summary-13"></a> +<a id="release-summary-14"></a> ### Release Summary Docs update release\. @@ -265,12 +281,12 @@ Docs update release\. <a id="v1-2-2"></a> ## v1\.2\.2 -<a id="release-summary-14"></a> +<a id="release-summary-15"></a> ### Release Summary Bugfix release\. -<a id="bugfixes-3"></a> +<a id="bugfixes-4"></a> ### Bugfixes * boot \- fix incorrect handling of SSH authorized keys \([https\://github\.com/ansible\-collections/community\.hrobot/issues/32](https\://github\.com/ansible\-collections/community\.hrobot/issues/32)\, [https\://github\.com/ansible\-collections/community\.hrobot/pull/33](https\://github\.com/ansible\-collections/community\.hrobot/pull/33)\)\. @@ -278,7 +294,7 @@ Bugfix release\. <a id="v1-2-1"></a> ## v1\.2\.1 -<a id="release-summary-15"></a> +<a id="release-summary-16"></a> ### Release Summary Maintenance release\. @@ -291,7 +307,7 @@ Maintenance release\. <a id="v1-2-0"></a> ## v1\.2\.0 -<a id="release-summary-16"></a> +<a id="release-summary-17"></a> ### Release Summary Feature release with multiple new modules\. @@ -318,12 +334,12 @@ Feature release with multiple new modules\. <a id="v1-1-1"></a> ## v1\.1\.1 -<a id="release-summary-17"></a> +<a id="release-summary-18"></a> ### Release Summary Bugfix release which reduces the number of HTTPS queries for the modules and plugins\. -<a id="bugfixes-4"></a> +<a id="bugfixes-5"></a> ### Bugfixes * robot \- force HTTP basic authentication to reduce number of HTTPS requests \([https\://github\.com/ansible\-collections/community\.hrobot/pull/9](https\://github\.com/ansible\-collections/community\.hrobot/pull/9)\)\. @@ -331,7 +347,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-18"></a> +<a id="release-summary-19"></a> ### Release Summary Release with a new inventory plugin\. @@ -347,7 +363,7 @@ Release with a new inventory plugin\. <a id="v1-0-0"></a> ## v1\.0\.0 -<a id="release-summary-19"></a> +<a id="release-summary-20"></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>\. diff --git a/ansible_collections/community/hrobot/CHANGELOG.rst b/ansible_collections/community/hrobot/CHANGELOG.rst index 847d3dbda..fdb9c4a23 100644 --- a/ansible_collections/community/hrobot/CHANGELOG.rst +++ b/ansible_collections/community/hrobot/CHANGELOG.rst @@ -4,6 +4,19 @@ Community Hetzner Robot Collection Release Notes .. contents:: Topics +v1.9.2 +====== + +Release Summary +--------------- + +Bugfix release. + +Bugfixes +-------- + +- 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.hrobot/pull/102). + v1.9.1 ====== diff --git a/ansible_collections/community/hrobot/FILES.json b/ansible_collections/community/hrobot/FILES.json index 54c28f1e6..e5964a9b0 100644 --- a/ansible_collections/community/hrobot/FILES.json +++ b/ansible_collections/community/hrobot/FILES.json @@ -25,21 +25,21 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b221558d1b9e91f2f1b3087eca7455efea6016a313388315d94c748a736f6d0c", + "chksum_sha256": "6745e283a9f1578108ad5f14efed6558cdfb1a25c5e04426836b343baa7f1ccc", "format": 1 }, { "name": ".github/workflows/docs-pr.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "369ffbe6357397daf6ef60448f249fc74a2ccd0c023bb37e956f29f1107087a0", + "chksum_sha256": "7d4d4e79b974e499d22506e1dae74806636da815166fcd615d0a0d728290370a", "format": 1 }, { "name": ".github/workflows/docs-push.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a37437b4ac5178def5765173891f1cc0b5562f833d0fabfe8f2dca166cdae6b4", + "chksum_sha256": "1404c05e77bda38b2061314876ed1d9f7e426b281d69f7b588d52b83b740f46e", "format": 1 }, { @@ -137,7 +137,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7bb1dd839047930188a470f49ab846872b8b5fed15a0ad79f2a4f6badc7ca08f", + "chksum_sha256": "e941d53c423339dae173424865a5f4e2c892aa52818bebd6999d2444ff2188a3", "format": 1 }, { @@ -169,6 +169,13 @@ "format": 1 }, { + "name": "docs/docsite/config.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0c5ec9ff76cf4db33b5d3f771419ef50d448e5d510cb7a98fc07dd9ecee69c4e", + "format": 1 + }, + { "name": "docs/docsite/links.yml", "ftype": "file", "chksum_type": "sha256", @@ -235,7 +242,7 @@ "name": "plugins/inventory/robot.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "08386e031100da8e3ae8d8a76fdf511b71ebce6d5b9648dc24f32784ee497fda", + "chksum_sha256": "9ebb90b3fa1ce6a294b1d56b7d943e86ada342b9e288bdd416bde2e39e9989db", "format": 1 }, { @@ -351,6 +358,20 @@ "format": 1 }, { + "name": "plugins/plugin_utils", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/plugin_utils/unsafe.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "93ccc2e18634405c7ff21a91a1df4f17261ac24b0f41bf3c46dbec2f254538c3", + "format": 1 + }, + { "name": "tests", "ftype": "dir", "chksum_type": null, @@ -610,6 +631,20 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5264853edb2c6ff138f5496111c1e758a3a54b61e82d96c0072cb9429fb31c6e", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.18.txt.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "tests/sanity/ignore-2.9.txt", "ftype": "file", "chksum_type": "sha256", @@ -648,7 +683,7 @@ "name": "tests/unit/plugins/inventory/test_robot.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "673ffae43e3a3584719643a42bbdd33321b2b8331629a9d069793c3925d21c35", + "chksum_sha256": "e77768bf19cc0b1743641419d4b0360b6725b8dbb4e79d2ecacfac69d0886db9", "format": 1 }, { @@ -788,7 +823,7 @@ "name": "CHANGELOG.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2c4facb0c77d486fd61f1ea78cd2bee7c6cf833fc4dd328b57a9a440efe43db3", + "chksum_sha256": "ec9612359cac38411b264cb53d67607a383a08d1a2bffc3ff84cdb1d9ad1de4c", "format": 1 }, { @@ -802,7 +837,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ca10d6a2a30e1165b9325897d7c6335ff8b3a50859742e2e4333070df0e6c38f", + "chksum_sha256": "84b7a7e9f7b8280abe9151db53d4fc3235b37db19686030e8d8fd000513e41ad", "format": 1 }, { @@ -823,7 +858,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b26ea8090f24cde8afb282f7779abf6ce363edbf65068631c38984c5ed51ba70", + "chksum_sha256": "df4f5e5e0c88eb6caf14a6b2d3916a5849ac18a2ee6c748d0276d1788d145911", "format": 1 }, { diff --git a/ansible_collections/community/hrobot/MANIFEST.json b/ansible_collections/community/hrobot/MANIFEST.json index 5fd6295d8..1ac2e2da3 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.1", + "version": "1.9.2", "authors": [ "Felix Fontein (github.com/felixfontein)" ], @@ -30,7 +30,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cada2fa56571e4857ace197d0dd1c09e665fdd718cea048c0327ba8ef3447245", + "chksum_sha256": "a5c77f86ec2889eb57623d0ccd7ffbae9635537c46dc4539324e8da92b7ddf27", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/hrobot/README.md b/ansible_collections/community/hrobot/README.md index 44ee9ddcd..bdc481de9 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, and ansible-core 2.16 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. +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. ## External requirements diff --git a/ansible_collections/community/hrobot/changelogs/changelog.yaml b/ansible_collections/community/hrobot/changelogs/changelog.yaml index ff49e627a..eca36fc8f 100644 --- a/ansible_collections/community/hrobot/changelogs/changelog.yaml +++ b/ansible_collections/community/hrobot/changelogs/changelog.yaml @@ -280,3 +280,13 @@ releases: - 1.9.1.yml - inventory-rce.yml release_date: '2024-03-16' + 1.9.2: + changes: + bugfixes: + - 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.hrobot/pull/102). + release_summary: Bugfix release. + fragments: + - 1.9.2.yml + - 102-unsafe.yml + release_date: '2024-04-16' diff --git a/ansible_collections/community/hrobot/docs/docsite/config.yml b/ansible_collections/community/hrobot/docs/docsite/config.yml new file mode 100644 index 000000000..1d6cf8554 --- /dev/null +++ b/ansible_collections/community/hrobot/docs/docsite/config.yml @@ -0,0 +1,7 @@ +--- +# 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 + +changelog: + write_changelog: true diff --git a/ansible_collections/community/hrobot/plugins/inventory/robot.py b/ansible_collections/community/hrobot/plugins/inventory/robot.py index 19a2f1aa4..409c90992 100644 --- a/ansible_collections/community/hrobot/plugins/inventory/robot.py +++ b/ansible_collections/community/hrobot/plugins/inventory/robot.py @@ -85,13 +85,13 @@ from ansible.errors import AnsibleError from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.template import Templar from ansible.utils.display import Display -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe from ansible_collections.community.hrobot.plugins.module_utils.robot import ( BASE_URL, PluginException, plugin_open_url_json, ) +from ansible_collections.community.hrobot.plugins.plugin_utils.unsafe import make_unsafe display = Display() diff --git a/ansible_collections/community/hrobot/plugins/plugin_utils/unsafe.py b/ansible_collections/community/hrobot/plugins/plugin_utils/unsafe.py new file mode 100644 index 000000000..1eb61bea0 --- /dev/null +++ b/ansible_collections/community/hrobot/plugins/plugin_utils/unsafe.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, 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 re + +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.common._collections_compat import Mapping, Set +from ansible.module_utils.common.collections import is_sequence +from ansible.utils.unsafe_proxy import ( + AnsibleUnsafe, + wrap_var as _make_unsafe, +) + +_RE_TEMPLATE_CHARS = re.compile(u'[{}]') +_RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]') + + +def make_unsafe(value): + if value is None or isinstance(value, AnsibleUnsafe): + return value + + if isinstance(value, Mapping): + return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) + elif isinstance(value, Set): + return set(make_unsafe(elt) for elt in value) + elif is_sequence(value): + return type(value)(make_unsafe(elt) for elt in value) + elif isinstance(value, binary_type): + if _RE_TEMPLATE_CHARS_BYTES.search(value): + value = _make_unsafe(value) + return value + elif isinstance(value, text_type): + if _RE_TEMPLATE_CHARS.search(value): + value = _make_unsafe(value) + return value + + return value diff --git a/ansible_collections/community/hrobot/tests/sanity/ignore-2.18.txt b/ansible_collections/community/hrobot/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..0d9329fad --- /dev/null +++ b/ansible_collections/community/hrobot/tests/sanity/ignore-2.18.txt @@ -0,0 +1 @@ +tests/ee/roles/smoke/library/smoke_ipaddress.py shebang diff --git a/ansible_collections/community/hrobot/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/hrobot/tests/sanity/ignore-2.18.txt.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/hrobot/tests/sanity/ignore-2.18.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/hrobot/tests/unit/plugins/inventory/test_robot.py b/ansible_collections/community/hrobot/tests/unit/plugins/inventory/test_robot.py index d5514aee5..c10524f7e 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 @@ -368,14 +368,14 @@ def test_unsafe(inventory, mocker): .result_json([ { 'server': { - 'server_ip': '1.2.3.4', + 'server_ip': '1.2.{3.4', 'dc': 'abc', }, }, { 'server': { 'server_ip': '1.2.3.5', - 'server_name': 'foo', + 'server_name': 'fo{o', 'dc': 'EVALU{{ "" }}ATED', }, }, @@ -389,27 +389,27 @@ def test_unsafe(inventory, mocker): open_url.assert_is_done() - host_1 = inventory.inventory.get_host('1.2.3.4') - host_2 = inventory.inventory.get_host('foo') + host_1 = inventory.inventory.get_host('1.2.{3.4') + host_2 = inventory.inventory.get_host('fo{o') host_1_vars = host_1.get_vars() host_2_vars = host_2.get_vars() - assert host_1_vars['ansible_host'] == '1.2.3.4' - assert host_1_vars['hrobot_server_ip'] == '1.2.3.4' + assert host_1_vars['ansible_host'] == '1.2.{3.4' + assert host_1_vars['hrobot_server_ip'] == '1.2.{3.4' assert host_1_vars['hrobot_dc'] == 'abc' assert host_2_vars['ansible_host'] == '1.2.3.5' assert host_2_vars['hrobot_server_ip'] == '1.2.3.5' - assert host_2_vars['hrobot_server_name'] == 'foo' + assert host_2_vars['hrobot_server_name'] == 'fo{o' assert host_2_vars['hrobot_dc'] == 'EVALU{{ "" }}ATED' # Make sure everything is unsafe assert isinstance(host_1_vars['ansible_host'], AnsibleUnsafe) assert isinstance(host_1_vars['hrobot_server_ip'], AnsibleUnsafe) - assert isinstance(host_1_vars['hrobot_dc'], AnsibleUnsafe) + assert not isinstance(host_1_vars['hrobot_dc'], AnsibleUnsafe) - assert isinstance(host_2_vars['ansible_host'], AnsibleUnsafe) - assert isinstance(host_2_vars['hrobot_server_ip'], AnsibleUnsafe) + assert not isinstance(host_2_vars['ansible_host'], AnsibleUnsafe) + assert not isinstance(host_2_vars['hrobot_server_ip'], AnsibleUnsafe) assert isinstance(host_2_vars['hrobot_server_name'], AnsibleUnsafe) assert isinstance(host_2_vars['hrobot_dc'], AnsibleUnsafe) diff --git a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/ansible-test.yml b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/ansible-test.yml index ff4cd6afd..a9d3a2966 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/ansible-test.yml @@ -33,6 +33,7 @@ jobs: - 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 @@ -74,6 +75,7 @@ jobs: - stable-2.14 - stable-2.15 - stable-2.16 + - stable-2.17 - devel steps: diff --git a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/docs-pr.yml b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/docs-pr.yml new file mode 100644 index 000000000..b5a8e0d06 --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/docs-pr.yml @@ -0,0 +1,92 @@ +--- +# 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: Collection Docs +concurrency: + group: docs-pr-${{ github.head_ref }} + cancel-in-progress: true +on: + pull_request_target: + types: [opened, synchronize, reopened, closed] + +env: + GHP_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }} + +jobs: + build-docs: + permissions: + contents: read + name: Build Ansible Docs + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@main + with: + collection-name: community.library_inventory_filtering_v1 + init-lenient: false + init-fail-on-error: true + squash-hierarchy: true + init-project: Community.Library_Inventory_Filtering Collection + init-copyright: Community.Library_Inventory_Filtering Contributors + init-title: Community.Library_Inventory_Filtering Collection Documentation + init-html-short-title: Community.Library_Inventory_Filtering Collection Docs + init-extra-html-theme-options: | + documentation_home_url=https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/branch/stable-1/ + render-file-line: '> * `$<status>` [$<path_tail>](https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/pr/${{ github.event.number }}/$<path_tail>)' + + publish-docs-gh-pages: + # for now we won't run this on forks + if: github.repository == 'ansible-collections/community.library_inventory_filtering' + permissions: + contents: write + needs: [build-docs] + name: Publish Ansible Docs + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-publish-gh-pages.yml@main + with: + artifact-name: ${{ needs.build-docs.outputs.artifact-name }} + action: ${{ (github.event.action == 'closed' || needs.build-docs.outputs.changed != 'true') && 'teardown' || 'publish' }} + secrets: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + comment: + permissions: + pull-requests: write + runs-on: ubuntu-latest + needs: [build-docs, publish-docs-gh-pages] + name: PR comments + steps: + - name: PR comment + uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@main + with: + body-includes: '## Docs Build' + reactions: heart + action: ${{ needs.build-docs.outputs.changed != 'true' && 'remove' || '' }} + on-closed-body: | + ## Docs Build 📝 + + This PR is closed and any previously published docsite has been unpublished. + on-merged-body: | + ## Docs Build 📝 + + Thank you for contribution!✨ + + This PR has been merged and the docs are now incorporated into `stable-1`: + ${{ env.GHP_BASE_URL }}/branch/stable-1 + body: | + ## Docs Build 📝 + + Thank you for contribution!✨ + + The docs for **this PR** have been published here: + ${{ env.GHP_BASE_URL }}/pr/${{ github.event.number }} + + You can compare to the docs for the `stable-1` branch here: + ${{ env.GHP_BASE_URL }}/branch/stable-1 + + The docsite for **this PR** is also available for download as an artifact from this run: + ${{ needs.build-docs.outputs.artifact-url }} + + File changes: + + ${{ needs.build-docs.outputs.diff-files-rendered }} + + ${{ needs.build-docs.outputs.diff-rendered }} diff --git a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/docs-push.yml b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/docs-push.yml new file mode 100644 index 000000000..53a4a56de --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/docs-push.yml @@ -0,0 +1,51 @@ +--- +# 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: Collection Docs +concurrency: + group: docs-push-${{ github.sha }} + cancel-in-progress: true +on: + push: + branches: + - stable-* + tags: + - '*' + # Run CI once per day (at 04:45 UTC) + schedule: + - cron: '45 4 * * *' + # Allow manual trigger (for newer antsibull-docs, sphinx-ansible-theme, ... versions) + workflow_dispatch: + +jobs: + build-docs: + permissions: + contents: read + name: Build Ansible Docs + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@main + with: + collection-name: community.library_inventory_filtering_v1 + init-lenient: false + init-fail-on-error: true + squash-hierarchy: true + init-project: Community.Library_Inventory_Filtering Collection + init-copyright: Community.Library_Inventory_Filtering Contributors + init-title: Community.Library_Inventory_Filtering Collection Documentation + init-html-short-title: Community.Library_Inventory_Filtering Collection Docs + init-extra-html-theme-options: | + documentation_home_url=https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/branch/stable-1/ + + publish-docs-gh-pages: + # for now we won't run this on forks + if: github.repository == 'ansible-collections/community.library_inventory_filtering' + permissions: + contents: write + needs: [build-docs] + name: Publish Ansible Docs + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-publish-gh-pages.yml@main + with: + artifact-name: ${{ needs.build-docs.outputs.artifact-name }} + secrets: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/extra-tests.yml b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/extra-tests.yml index 8352f7f32..679176264 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/extra-tests.yml +++ b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/extra-tests.yml @@ -30,9 +30,9 @@ jobs: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} - name: Set up Python - uses: actions/setup-python@v4 + 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 diff --git a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/import-galaxy.yml b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/import-galaxy.yml index 45dcfafe0..0c0ee402a 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/import-galaxy.yml +++ b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/import-galaxy.yml @@ -4,84 +4,17 @@ # SPDX-License-Identifier: GPL-3.0-or-later name: import-galaxy -on: +'on': # Run CI against all pushes (direct commits, also merged PRs) to main, and all Pull Requests push: branches: + - main - stable-* pull_request: -env: - # Adjust this to your collection - NAMESPACE: community - COLLECTION_NAME: library_inventory_filtering_v1 - jobs: - build-collection: - name: Build collection artifact - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v4 - with: - path: ./checkout - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - - name: Install ansible-core - run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check - - - name: Make sure galaxy.yml has version entry - run: >- - python -c - 'import yaml ; - f = open("galaxy.yml", "rb") ; - data = yaml.safe_load(f) ; - f.close() ; - data["version"] = data.get("version") or "0.0.1" ; - f = open("galaxy.yml", "wb") ; - f.write(yaml.dump(data).encode("utf-8")) ; - f.close() ; - ' - working-directory: ./checkout - - - name: Build collection - run: ansible-galaxy collection build - working-directory: ./checkout - - - name: Copy artifact into subdirectory - run: mkdir ./artifact && mv ./checkout/${{ env.NAMESPACE }}-${{ env.COLLECTION_NAME }}-*.tar.gz ./artifact - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ env.NAMESPACE }}-${{ env.COLLECTION_NAME }}-${{ github.sha }} - path: ./artifact/ - import-galaxy: - name: Import artifact with Galaxy importer - runs-on: ubuntu-latest - needs: - - build-collection - steps: - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - - name: Install ansible-core - run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check - - - name: Install galaxy-importer - run: pip install galaxy-importer --disable-pip-version-check - - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: ${{ env.NAMESPACE }}-${{ env.COLLECTION_NAME }}-${{ github.sha }} - - - name: Run Galaxy importer - run: python -m galaxy_importer.main ${{ env.NAMESPACE }}-${{ env.COLLECTION_NAME }}-*.tar.gz + permissions: + contents: read + name: Test to import built collection artifact with Galaxy importer + uses: ansible-community/github-action-test-galaxy-import/.github/workflows/test-galaxy-import.yml@main diff --git a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/reuse.yml b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/reuse.yml index 8785d624c..276b2ea24 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/reuse.yml +++ b/ansible_collections/community/library_inventory_filtering_v1/.github/workflows/reuse.yml @@ -23,10 +23,5 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install dependencies - run: | - pip install reuse - - - name: Check REUSE compliance - run: | - reuse lint + - name: REUSE Compliance Check + uses: fsfe/reuse-action@v3 diff --git a/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.md b/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.md new file mode 100644 index 000000000..b3ff507da --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.md @@ -0,0 +1,34 @@ +# Community Inventory Filtering Library Collection Release Notes + +**Topics** + +- <a href="#v1-0-1">v1\.0\.1</a> + - <a href="#release-summary">Release Summary</a> +- <a href="#v1-0-0">v1\.0\.0</a> + - <a href="#release-summary-1">Release Summary</a> +- <a href="#v0-1-0">v0\.1\.0</a> + - <a href="#release-summary-2">Release Summary</a> + +<a id="v1-0-1"></a> +## v1\.0\.1 + +<a id="release-summary"></a> +### Release Summary + +Maintenance release with documentation\. + +<a id="v1-0-0"></a> +## v1\.0\.0 + +<a id="release-summary-1"></a> +### Release Summary + +First production ready release\. + +<a id="v0-1-0"></a> +## v0\.1\.0 + +<a id="release-summary-2"></a> +### Release Summary + +Initial test release\. diff --git a/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.md.license b/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.md.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.md.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/library_inventory_filtering_v1/CHANGELOG.rst b/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.rst index 9f655c4cf..4f13fcf95 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.rst +++ b/ansible_collections/community/library_inventory_filtering_v1/CHANGELOG.rst @@ -4,6 +4,13 @@ Community Inventory Filtering Library Collection Release Notes .. contents:: Topics +v1.0.1 +====== + +Release Summary +--------------- + +Maintenance release with documentation. v1.0.0 ====== diff --git a/ansible_collections/community/library_inventory_filtering_v1/FILES.json b/ansible_collections/community/library_inventory_filtering_v1/FILES.json index f89f629d5..332860b52 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/FILES.json +++ b/ansible_collections/community/library_inventory_filtering_v1/FILES.json @@ -25,28 +25,42 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "29df556b00de431af2c7824813c09ceff4dc440903465c18b382e423cfdb04b8", + "chksum_sha256": "e4c0dfca6b656fd2a85ffa83996421299ef5b10f9f46b39231ae2505238fc355", + "format": 1 + }, + { + "name": ".github/workflows/docs-pr.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "baa2a051226089dd82bf1ca7ca9c305d2d81b0c3cf18a0bb688aecf56e269828", + "format": 1 + }, + { + "name": ".github/workflows/docs-push.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "504c9bf048c3bfc77a6428d7854c5e747d2fe8c56c033063753174469920df52", "format": 1 }, { "name": ".github/workflows/extra-tests.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "34a58525f32c964e97de3b09619f3c2e540f1521db85f29679d3af6e1e689e89", + "chksum_sha256": "113b8c148b730d8abf8040ed7491696ddc7ab03326325945e5e721eccc3b6b16", "format": 1 }, { "name": ".github/workflows/import-galaxy.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bf7394f8711a28c66c2a0b199e18c11d25d181cc827a2f7d0a0372a9f16ec0a9", + "chksum_sha256": "739c36223d6e0e6ccc98907c43cba53296e7b1ccd64a2d995c2ff21df4ab25a5", "format": 1 }, { "name": ".github/workflows/reuse.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5430af9a962c589c971154eb0dbd19a3f3a8b9eb870cb6c2d5e3896a5e962dac", + "chksum_sha256": "4c8fff4ef98f0dc1af3658b126140721ab1085979e76ed099308aa39828b297e", "format": 1 }, { @@ -109,7 +123,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "77a81c4d67042178df11c3235affa25a4c80e9140a6cab05eb8382750f9b5abd", + "chksum_sha256": "ae6dc5859ee98156f3fdbdfd1f3187782cb6586248a52358f2f565774654e78c", "format": 1 }, { @@ -123,7 +137,56 @@ "name": "changelogs/config.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e9f261ba6cc36a9d2639e0a51701fd8dd7e8c2ce7ae226380fb53da97a81a9cd", + "chksum_sha256": "b39f1dff98defdbedc9794ae82d77f5817d5c14144f0b6269c942bf5577a4feb", + "format": 1 + }, + { + "name": "docs", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "docs/docsite", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "docs/docsite/rst", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "docs/docsite/rst/usage_guide.rst", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9cb7a0386071576cb076b0ac3bd680df3c3a1c22d316587c445666dadba986f3", + "format": 1 + }, + { + "name": "docs/docsite/config.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0c5ec9ff76cf4db33b5d3f771419ef50d448e5d510cb7a98fc07dd9ecee69c4e", + "format": 1 + }, + { + "name": "docs/docsite/extra-docs.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bbc2aa66c91ee37c4aea3e5aaff25983305e48b7281dc0356506ccb1e7c05103", + "format": 1 + }, + { + "name": "docs/docsite/links.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2844a8906b69c6d9d7ab60546c1feb624bda986c8e49c5d6f0275e8dc2f687f1", "format": 1 }, { @@ -316,10 +379,24 @@ "format": 1 }, { + "name": "CHANGELOG.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e5dc2d05e3fe257bcfd97b59ff5b7a0fcbcef18a7b3204b866d930b304e89c91", + "format": 1 + }, + { + "name": "CHANGELOG.md.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "48a7116aab933a579b4972ff4646af4a5a37a5059d168f10e50df8054e7951f1", + "chksum_sha256": "8e3955ac95e2b3189609b191684a7a3164551c2583fa1389536635a2b3291e75", "format": 1 }, { @@ -340,7 +417,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b81d36f2d772b7384f5ecc75329982c5cb5812c8532acc9c3f07effff53eb430", + "chksum_sha256": "bef45f0f502d9a001eaf1300ae1480acc6930ddd543741d4dc26e1bd85b7001f", "format": 1 }, { diff --git a/ansible_collections/community/library_inventory_filtering_v1/MANIFEST.json b/ansible_collections/community/library_inventory_filtering_v1/MANIFEST.json index eb2881bcc..19de3ad44 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/MANIFEST.json +++ b/ansible_collections/community/library_inventory_filtering_v1/MANIFEST.json @@ -2,7 +2,7 @@ "collection_info": { "namespace": "community", "name": "library_inventory_filtering_v1", - "version": "1.0.0", + "version": "1.0.1", "authors": [ "Felix Fontein (github.com/felixfontein)" ], @@ -26,7 +26,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9e2fea3417b34954669efe0b692abee7364e520719a215937bd30b3484b546e3", + "chksum_sha256": "3a7e23348c6de582464cfc3937c64cc325727e3e6514fef783ecaa3328fe3ee1", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/library_inventory_filtering_v1/README.md b/ansible_collections/community/library_inventory_filtering_v1/README.md index 88299bbbb..c29686f77 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/README.md +++ b/ansible_collections/community/library_inventory_filtering_v1/README.md @@ -11,7 +11,7 @@ This repository contains the `community.library_inventory_filtering_v1` Ansible ## 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, and ansible-core 2.16 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. +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. ## Included content @@ -23,6 +23,16 @@ Usually this collection is installed as a dependency of another collection. You See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for general instructions on how to use collections. +## Collection Documentation + +Browsing the [**latest** collection documentation](https://docs.ansible.com/ansible/latest/collections/community/library_inventory_filtering_v1) will show docs for the _latest version released in the Ansible package_, not the latest version of the collection released on Galaxy. + +Browsing the [**devel** collection documentation](https://docs.ansible.com/ansible/devel/collections/community/library_inventory_filtering_v1) shows docs for the _latest version released on Galaxy_. + +We also separately publish [**latest commit** collection documentation](https://ansible-collections.github.io/community.library_inventory_filtering/branch/stable-1/) which shows docs for the _latest commit in the `stable-1` branch_. + +If you use the Ansible package and do not update collections independently, use **latest**. If you install or update this collection directly from Galaxy, use **devel**. If you are looking to contribute, use **latest commit**. + ## Contributing to this collection If you want to develop new content for this collection or improve what is already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATH`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there. @@ -31,7 +41,19 @@ You can find more information in the [developer guide for collections](https://d ## Release notes -See the [changelog](https://github.com/ansible-collections/community.library_inventory_filtering/tree/stable-1/CHANGELOG.rst). +See the [changelog](https://github.com/ansible-collections/community.library_inventory_filtering/tree/stable-1/CHANGELOG.md). + +## Releasing, Versioning and Deprecation + +This collection follows [Semantic Versioning](https://semver.org/). More details on versioning can be found [in the Ansible docs](https://docs.ansible.com/ansible/latest/dev_guide/developing_collections.html#collection-versions). + +We plan to regularly release new minor or bugfix versions once new features or bugfixes have been implemented. + +Releasing the major version X happens from the `stable-X` branch. The collection name depends on the major branch; the collections released from `stable-1` have a `_v1` suffix; the collections released from `stable-2` have a `_v2` suffix; and so on. The different suffix allows to install multiple major releases of the collection in parallel. This makes it possible to migrate some collections to major version 2 without forcing to upgrade all of them simultaneously. + +Features might be backported to earlier stable branches. Bugfixes are backported as long as these stable branches are still maintained. Generally stable branches should still be maintained as long as they are still used by maintained branches of collections. Backporting bugfixes or creating more specialized bugfixes for stable branches might need to be done by the maintainers of the collections still using these branches. + +Since multiple versions are maintained in parallel, there is no need to wait between deprecation and removal. Removal requires a new major release (and thus a new collection name due to a different version suffix). ## More information diff --git a/ansible_collections/community/library_inventory_filtering_v1/changelogs/changelog.yaml b/ansible_collections/community/library_inventory_filtering_v1/changelogs/changelog.yaml index dc48b112a..b4bf6bbcb 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/changelogs/changelog.yaml +++ b/ansible_collections/community/library_inventory_filtering_v1/changelogs/changelog.yaml @@ -12,3 +12,9 @@ releases: fragments: - 1.0.0.yml release_date: '2023-12-28' + 1.0.1: + changes: + release_summary: Maintenance release with documentation. + fragments: + - 1.0.1.yml + release_date: '2024-04-21' diff --git a/ansible_collections/community/library_inventory_filtering_v1/changelogs/config.yaml b/ansible_collections/community/library_inventory_filtering_v1/changelogs/config.yaml index a64e83dc6..cdfc8f323 100644 --- a/ansible_collections/community/library_inventory_filtering_v1/changelogs/config.yaml +++ b/ansible_collections/community/library_inventory_filtering_v1/changelogs/config.yaml @@ -11,6 +11,9 @@ keep_fragments: false mention_ancestor: true new_plugins_after_name: removed_features notesdir: fragments +output_formats: +- rst +- md prelude_section_name: release_summary prelude_section_title: Release Summary sections: diff --git a/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/config.yml b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/config.yml new file mode 100644 index 000000000..1d6cf8554 --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/config.yml @@ -0,0 +1,7 @@ +--- +# 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 + +changelog: + write_changelog: true diff --git a/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/extra-docs.yml b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/extra-docs.yml new file mode 100644 index 000000000..55abd2207 --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/extra-docs.yml @@ -0,0 +1,9 @@ +--- +# 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 + +sections: + - title: Usage guide + toctree: + - usage_guide diff --git a/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/links.yml b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/links.yml new file mode 100644 index 000000000..0346f180e --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/links.yml @@ -0,0 +1,20 @@ +--- +# 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 + +edit_on_github: + repository: ansible-collections/community.library_inventory_filtering + branch: stable-1 + path_prefix: '' + +extra_links: + - description: Submit a bug report + url: https://github.com/ansible-collections/community.library_inventory_filtering/issues/new?assignees=&labels=&template=bug_report.md + - description: Request a feature + url: https://github.com/ansible-collections/community.library_inventory_filtering/issues/new?assignees=&labels=&template=feature_request.md + +communication: + matrix_rooms: + - topic: General usage and support questions + room: '#community:ansible.im' diff --git a/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/rst/usage_guide.rst b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/rst/usage_guide.rst new file mode 100644 index 000000000..d1b1e8374 --- /dev/null +++ b/ansible_collections/community/library_inventory_filtering_v1/docs/docsite/rst/usage_guide.rst @@ -0,0 +1,75 @@ +.. + 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 + +.. _ansible_collections.community.library_inventory_filtering_v1.docsite.usage_guide: + +Usage Guide +=========== + +The `community.library_inventory_filtering_v1 collection <https://galaxy.ansible.com/ui/repo/published/community/library_inventory_filtering_v1/>`_ enables other collections to add common filter functionality to inventory plugins. + +.. contents:: + :local: + :depth: 1 + + +Requirements +------------ + +The ``stable-1`` branch of this collection, released as , works with all ansible-base and ansible-core versions, and with Ansible >= 2.9.10. + +Adding filter functionality to an inventory plugin +-------------------------------------------------- + +The preferred way to use this collection is to use the ``inventory_filter`` docs fragment and the ``inventory_filter`` plugin utils. + +To use the documentation fragment, add it to the ``extends_documentation_fragment`` list in ``DOCUMENTATION``: + +.. code-block:: yaml + + extends_documentation_fragment: + - community.library_inventory_filtering_v1.inventory_filter + +For the filtering, you need to import two functions from the plugin util, ``parse_filters()`` and ``filter_host()``: + +.. code-block:: python + + from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import ( + parse_filters, + filter_host, + ) + +You can use ``parse_filters()`` to parse the ``filters`` option's value (``self.get_option('filters')``), and ``filter_host()`` to determine whether to include a host: + +.. code-block:: python + + class InventoryModule(BaseInventoryPlugin, ...): + + def parse(self, inventory, loader, path, cache=True): + super(InventoryModule, self).parse(inventory, loader, path, cache) + self._read_config_data(path) + + ... + + # Parse the filters option + filters = parse_filters(self.get_option('filters')) + + ... + + for host in hosts: + # Compile the host vars + host_vars = ... + + # Now we can evaluate potential filter conditions + # based on the host name and host vars: + if not filter_host(self, host, host_vars, filters): + continue + + # Add the host with its vars + self.inventory.add_host(name) + for key, value in host_vars.items(): + self.inventory.set_variable(name, key, value) + + ... diff --git a/ansible_collections/community/mongodb/CHANGELOG.rst b/ansible_collections/community/mongodb/CHANGELOG.rst index 88b4b7fe4..efe8e7a47 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.3: +========= + +Release Summary +---------------- + +This release is a maintenance release. + +Bug Fixes +---------- + +- 641 - mongodb_mongod - Add test condition for storage option in mongod.conf template file. + v1.7.2: ========= diff --git a/ansible_collections/community/mongodb/FILES.json b/ansible_collections/community/mongodb/FILES.json index ff9223131..f94843a96 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": "62026cfdee0d726808baf3b46212cb3b1d0668bf8f156898c11b3017f45c67e4", + "chksum_sha256": "d7e3cf154cb0134ac530a4ec411e69e5d21ed2d500e5bc219ddc983625779f64", "format": 1 }, { @@ -1698,7 +1698,7 @@ "name": "roles/mongodb_mongod/templates/mongod.conf.j2", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7640c7f81cf31e93dc02bb1e1b5099ddc1f9b555e5109190f2c252fed81f4b43", + "chksum_sha256": "b13fcb483b070ce7bf9cd99f742bffce8ce7170e59a4eaa183f40ea6ee7cc0f7", "format": 1 }, { @@ -2370,7 +2370,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c81479be70033bb9abe13501e9c3eef37936cb74ea74bbfea1d83d9e685c2917", + "chksum_sha256": "dd8f971dbb162351148320dbed19aa7fb8e49aa683205224ea51defff77fe3f3", "format": 1 }, { @@ -2384,7 +2384,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "30119dbbd021221c84f7447cee3fd266408933a599e51affa2fab12db835bd87", + "chksum_sha256": "65a9319fb932c67923de4f992f3119feae296f85411b5cffb00aa04b93a44f29", "format": 1 }, { diff --git a/ansible_collections/community/mongodb/MANIFEST.json b/ansible_collections/community/mongodb/MANIFEST.json index 8ae826436..aa6035a5e 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.2", + "version": "1.7.3", "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": "4d1c58600e395dade74dad0a4e8ad949bda341bf224312202dcff67516a0a16e", + "chksum_sha256": "72e4c95bc97cb1a5e68ca35b8c8dffa1bda536bae32ca66bdaa676747ba0244f", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/mongodb/README.md b/ansible_collections/community/mongodb/README.md index caadf1e93..66e50daef 100644 --- a/ansible_collections/community/mongodb/README.md +++ b/ansible_collections/community/mongodb/README.md @@ -1,6 +1,6 @@ # MongoDB Version and PyMongoDB Version Compatibility -- This collection is tested against the most recent two minor MongoDB releases, currently 6.0.X and 7.0.X. +- This collection is tested against the most recent two MongoDB releases, currently 6.0.X and 7.0.X. - PyMongo 3.12.X dropped on 11.04.2023. Now PyMongo latest only. - Compatibility may be maintained for older software versions but is not guaranteed. Please upgrade your PyMongo driver version if you encounter difficulties with older versions. diff --git a/ansible_collections/community/mongodb/changelogs/changelog.yaml b/ansible_collections/community/mongodb/changelogs/changelog.yaml index 7f608d606..641f7c62f 100644 --- a/ansible_collections/community/mongodb/changelogs/changelog.yaml +++ b/ansible_collections/community/mongodb/changelogs/changelog.yaml @@ -330,3 +330,8 @@ releases: This release is a maintenance release. bugfixes: - 638 - mongodb_replicaset - Allow module to update replicaset horizons. + 1.7.3: + release_summary: | + This release is a maintenance release. + bugfixes: + - 641 - mongodb_mongod - Add test condition for storage option in mongod.conf template file. diff --git a/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 b/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 index cd2d1f0fc..33ad19650 100644 --- a/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 +++ b/ansible_collections/community/mongodb/roles/mongodb_mongod/templates/mongod.conf.j2 @@ -15,8 +15,10 @@ systemLog: # Where and how to store data. storage: dbPath: {{ db_path }} +{% if mongodb_version < '6.1' %} journal: enabled: true +{% endif %} engine: "wiredTiger" # how the process runs diff --git a/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml index 7002adffa..69638bf11 100644 --- a/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml +++ b/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml @@ -36,7 +36,7 @@ variables: resources: containers: - container: default - image: quay.io/ansible/azure-pipelines-test-container:3.0.0 + image: quay.io/ansible/azure-pipelines-test-container:4.0.1 pool: Standard @@ -54,77 +54,41 @@ stages: - name: Units test: 'devel/units/1' - - stage: Ansible_2_14 - displayName: Sanity & Units 2.14 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: Sanity - test: '2.14/sanity/1' - - name: Units - test: '2.14/units/1' - - - stage: Ansible_2_13 - displayName: Sanity & Units 2.13 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: Sanity - test: '2.13/sanity/1' - - name: Units - test: '2.13/units/1' - - - stage: Ansible_2_12 - displayName: Sanity & Units 2.12 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: Sanity - test: '2.12/sanity/1' - - name: Units - test: '2.12/units/1' - - - stage: Ansible_2_11 - displayName: Sanity & Units 2.11 + - stage: Ansible_2_16 + displayName: Sanity & Units 2.16 dependsOn: [] jobs: - template: templates/matrix.yml parameters: targets: - name: Sanity - test: '2.11/sanity/1' + test: '2.16/sanity/1' - name: Units - test: '2.11/units/1' + test: '2.16/units/1' - - stage: Ansible_2_10 - displayName: Sanity & Units 2.10 + - stage: Ansible_2_15 + displayName: Sanity & Units 2.15 dependsOn: [] jobs: - template: templates/matrix.yml parameters: targets: - name: Sanity - test: '2.10/sanity/1' + test: '2.15/sanity/1' - name: Units - test: '2.10/units/1' + test: '2.15/units/1' - - stage: Ansible_2_9 - displayName: Sanity & Units 2.9 + - stage: Ansible_2_14 + displayName: Sanity & Units 2.14 dependsOn: [] jobs: - template: templates/matrix.yml parameters: targets: - name: Sanity - test: '2.9/sanity/1' + test: '2.14/sanity/1' - name: Units - test: '2.9/units/1' + test: '2.14/units/1' ### Docker - stage: Docker_devel @@ -163,113 +127,50 @@ stages: #- name: Ubuntu 20.04 # test: ubuntu2004 - - stage: Docker_2_14 - displayName: Docker 2.14 + - stage: Docker_2_16 + displayName: Docker 2.16 dependsOn: [] jobs: - template: templates/matrix.yml parameters: - testFormat: 2.14/linux/{0}/1 + testFormat: 2.16/linux/{0}/1 targets: - name: Ubuntu 22.04 test: ubuntu2204 - # Currently 20.04 is causing devel to fail. This maybe due to Ubuntu 20.04 running python - # 3.8, however, ansible-test requires 3.9+. This means ansible test spins up a controller - # and target container which is probably why rabbitmq_publish is not able to connect to - # rabbitmq on localhost. - #- name: Ubuntu 20.04 - # test: ubuntu2004 - - - stage: Docker_2_13 - displayName: Docker 2.13 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.13/linux/{0}/1 - targets: - #- name: Ubuntu 18.04 - # test: ubuntu1804 - - name: Ubuntu 20.04 - test: ubuntu2004 - - - stage: Docker_2_12 - displayName: Docker 2.12 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.12/linux/{0}/1 - targets: - #- name: Ubuntu 18.04 - # test: ubuntu1804 - - name: Ubuntu 20.04 - test: ubuntu2004 - - - stage: Docker_2_11 - displayName: Docker 2.11 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - testFormat: 2.11/linux/{0}/1 - targets: - # NOTE: update integration roles to support platform before enabling here. - #- name: CentOS 6 - # test: centos6 - #- name: CentOS 7 - # test: centos7 - #- name: Fedora 32 - # test: fedora32 - #- name: Fedora 33 - # test: fedora33 - #- name: openSUSE 15 py2 - # test: opensuse15py2 - #- name: openSUSE 15 py3 - # test: opensuse15 - - name: Ubuntu 18.04 - test: ubuntu1804 - - name: Ubuntu 20.04 - test: ubuntu2004 - - stage: Docker_2_10 - displayName: Docker 2.10 + - stage: Docker_2_15 + displayName: Docker 2.15 dependsOn: [] jobs: - template: templates/matrix.yml parameters: - testFormat: 2.10/linux/{0}/1 + testFormat: 2.15/linux/{0}/1 targets: - # NOTE: update integration roles to support platform before enabling here. - #- name: CentOS 6 - # test: centos6 - #- name: CentOS 7 - # test: centos7 - #- name: Fedora 31 - # test: fedora31 - #- name: Fedora 32 - # test: fedora32 - #- name: openSUSE 15 py2 - # test: opensuse15py2 - #- name: openSUSE 15 py3 - # test: opensuse15 - - name: Ubuntu 18.04 - test: ubuntu1804 - - name: Ubuntu 20.04 - test: ubuntu2004 + - name: Ubuntu 22.04 + test: ubuntu2204 + # Currently 20.04 is causing devel to fail. This maybe due to Ubuntu 20.04 running python + # 3.8, however, ansible-test requires 3.9+. This means ansible test spins up a controller + # and target container which is probably why rabbitmq_publish is not able to connect to + # rabbitmq on localhost. + #- name: Ubuntu 20.04 + # test: ubuntu2004 - - stage: Docker_2_9 - displayName: Docker 2.9 + - stage: Docker_2_14 + displayName: Docker 2.14 dependsOn: [] jobs: - template: templates/matrix.yml parameters: - testFormat: 2.9/linux/{0}/1 + testFormat: 2.14/linux/{0}/1 targets: - # NOTE: update integration roles to support platform before adding here. - - name: Ubuntu 18.04 - test: ubuntu1804 # freezes in rabbitmq_setup - # ansible-test 2.9 does not support 20.04 (image not included in its test-containers list) + - name: Ubuntu 22.04 + test: ubuntu2204 + # Currently 20.04 is causing devel to fail. This maybe due to Ubuntu 20.04 running python + # 3.8, however, ansible-test requires 3.9+. This means ansible test spins up a controller + # and target container which is probably why rabbitmq_publish is not able to connect to + # rabbitmq on localhost. + #- name: Ubuntu 20.04 + # test: ubuntu2004 ### Remote # - stage: Remote_devel @@ -288,74 +189,16 @@ stages: # test: freebsd/11.4 # - name: FreeBSD 12.2 # test: freebsd/12.2 -# - stage: Remote_2_11 -# displayName: Remote 2.11 -# dependsOn: [] -# jobs: -# - template: templates/matrix.yml -# parameters: -# testFormat: 2.11/{0}/1 -# targets: -# - name: RHEL 7.9 -# test: rhel/7.9 -# - name: RHEL 8.3 -# test: rhel/8.3 -# - name: FreeBSD 11.4 -# test: freebsd/11.4 -# - name: FreeBSD 12.2 -# test: freebsd/12.2 -# - stage: Remote_2_10 -# displayName: Remote 2.10 -# dependsOn: [] -# jobs: -# - template: templates/matrix.yml -# parameters: -# testFormat: 2.10/{0}/1 -# targets: -# - name: RHEL 7.8 -# test: rhel/7.8 -# - name: RHEL 8.2 -# test: rhel/8.2 -# - name: FreeBSD 11.1 -# test: freebsd/11.1 -# - name: FreeBSD 12.1 -# test: freebsd/12.1 -# - stage: Remote_2_9 -# displayName: Remote 2.9 -# dependsOn: [] -# jobs: -# - template: templates/matrix.yml -# parameters: -# testFormat: 2.9/{0}/1 -# targets: -# - name: RHEL 7.8 -# test: rhel/7.8 -# - name: RHEL 8.2 -# test: rhel/8.2 -# - name: FreeBSD 11.1 -# test: freebsd/11.1 -# - name: FreeBSD 12.1 -# test: freebsd/12.1 + - stage: Summary condition: succeededOrFailed() dependsOn: - Ansible_devel + - Ansible_2_15 - Ansible_2_14 - - Ansible_2_13 - - Ansible_2_12 - - Ansible_2_11 - - Ansible_2_10 - - Ansible_2_9 - Docker_devel + - Docker_2_15 - Docker_2_14 - - Docker_2_13 - - Docker_2_12 - - Docker_2_11 - - Docker_2_10 - - Docker_2_9 #- Remote_devel - #- Remote_2_11 - #- Remote_2_10 - #- Remote_2_9 jobs: - template: templates/coverage.yml diff --git a/ansible_collections/community/rabbitmq/CHANGELOG.rst b/ansible_collections/community/rabbitmq/CHANGELOG.rst index 2972a9aa7..4f376603c 100644 --- a/ansible_collections/community/rabbitmq/CHANGELOG.rst +++ b/ansible_collections/community/rabbitmq/CHANGELOG.rst @@ -4,6 +4,20 @@ Community.Rabbitmq Release Notes .. contents:: Topics +v1.3.0 +====== + +Release Summary +--------------- + +This is the minor release of the ``community.rabbitmq`` collection. +This changelog contains all changes to the modules and plugins in this collection +that have been made after the 1.2.3 release. + +Minor Changes +------------- + +- rabbitmq_user - add support to user manipulation through RabbitMQ API (https://github.com/ansible-collections/community.rabbitmq/issues/76) v1.2.3 ====== @@ -15,7 +29,6 @@ This is the minor release of the ``community.rabbitmq`` collection. This changelog contains all changes to the modules and plugins in this collection that have been made after the 1.2.2 release. - Minor Changes ------------- @@ -25,8 +38,8 @@ Minor Changes Bugfixes -------- -- rabbitmq_queue - fixing an issue where a special character in the queue name would result in an API error (https://github.com/ansible-collections/community.rabbitmq/issues/114). - Various CI fixes (https://github.com/ansible-collections/community.rabbitmq/pull/139 & https://github.com/ansible-collections/community.rabbitmq/pull/141). +- rabbitmq_queue - fixing an issue where a special character in the queue name would result in an API error (https://github.com/ansible-collections/community.rabbitmq/issues/114). v1.2.2 ====== diff --git a/ansible_collections/community/rabbitmq/FILES.json b/ansible_collections/community/rabbitmq/FILES.json index 386bcdee6..c3722e646 100644 --- a/ansible_collections/community/rabbitmq/FILES.json +++ b/ansible_collections/community/rabbitmq/FILES.json @@ -109,7 +109,7 @@ "name": ".azure-pipelines/azure-pipelines.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "fcad40ddb0bcc93a39f7d1a5085a0cda0b6c16cfcc52d8874a23ddc090f0c57f", + "chksum_sha256": "16db5589035b7434f5d3a7025654cd37a6b1b283f406688fc07ca2fa0805a33d", "format": 1 }, { @@ -123,7 +123,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2c1ac1a9869d7c8d4e39046dab344e152b41c4568e830c835c5a160c5c7f4d9f", + "chksum_sha256": "9bc8251d2d005b494b776c350eae47d6af7d7863cd82cbe1bb696a7b84b87815", "format": 1 }, { @@ -186,7 +186,7 @@ "name": "plugins/lookup/rabbitmq.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b9c692de8e40a03374e0ca861a7878a0fd62e030b6b318dfc92f4b8ae20a688e", + "chksum_sha256": "cfe3e5e5754f50515b05ab3d4e4079aa4bc6c64c449f75e5c8e791d83b68377c", "format": 1 }, { @@ -207,7 +207,7 @@ "name": "plugins/module_utils/rabbitmq.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e0f334c9bff8d4198ee16bec49f13f08da5b9c43191109cab7c17d26bbddf218", + "chksum_sha256": "612bbc76033437090e05aa16b797e6003d7d90e8a0ced59d28b27ad82f970368", "format": 1 }, { @@ -256,7 +256,7 @@ "name": "plugins/modules/rabbitmq_parameter.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2cd6c3187093db8314603108d9d91c318c784af4bd07cc4f196a6bc01dcddc33", + "chksum_sha256": "d2d85dec30694641f91cccbddb5c827462cebd51655273462ba0280a35e4e4a9", "format": 1 }, { @@ -277,7 +277,7 @@ "name": "plugins/modules/rabbitmq_publish.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d5585f87fd00075bad137a8b185cd5d9fabc8ae7576629e8b01c200610e8177a", + "chksum_sha256": "1c0c9680fe5d3d6fe7d77df6bc63fe44d3269af82e3238d44e8d28efb958fff9", "format": 1 }, { @@ -298,7 +298,7 @@ "name": "plugins/modules/rabbitmq_user.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5fe7cd8150b3b76e87f8f86fe164f89070d9f62a61411d6b84e004c18949451f", + "chksum_sha256": "df9c298b4a460cee35c274032a83cc402a843ffc63f53f40376d22cead3c70e3", "format": 1 }, { @@ -375,7 +375,7 @@ "name": "tests/integration/targets/lookup_rabbitmq/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0", + "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c", "format": 1 }, { @@ -718,7 +718,7 @@ "name": "tests/integration/targets/rabbitmq_publish/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0", + "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c", "format": 1 }, { @@ -767,7 +767,7 @@ "name": "tests/integration/targets/rabbitmq_queue/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0", + "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c", "format": 1 }, { @@ -865,7 +865,7 @@ "name": "tests/integration/targets/rabbitmq_user/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "27b82af4f4e91ff9565ee5a834d7b93b0322b25dec30ab06a23d07b178f515c9", + "chksum_sha256": "7b47e3c3e8b4970ef2b1d8a97410a8224c72b0c949e423e385d238ded830f3b9", "format": 1 }, { @@ -876,6 +876,13 @@ "format": 1 }, { + "name": "tests/integration/targets/rabbitmq_user/tasks/tests_api.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "87e87bd203d2432fe211e49940b58e9b409d97f735e898f12c15408b041e530c", + "format": 1 + }, + { "name": "tests/integration/targets/rabbitmq_user/aliases", "ftype": "file", "chksum_type": "sha256", @@ -914,7 +921,7 @@ "name": "tests/integration/targets/rabbitmq_user_limits/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0", + "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c", "format": 1 }, { @@ -1012,7 +1019,7 @@ "name": "tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0", + "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c", "format": 1 }, { @@ -1212,20 +1219,6 @@ "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", @@ -1250,21 +1243,21 @@ "name": "tests/sanity/ignore-2.15.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8", + "chksum_sha256": "f9e62f04368d06e3fee2abe014f49bc1696a1478a4d0a8e32fb5c1dae693c43e", "format": 1 }, { - "name": "tests/sanity/ignore-2.9.txt", + "name": "tests/sanity/ignore-2.16.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8", + "chksum_sha256": "7919c2c8970b1cac1d23835cdb9a3a250190bd789e4f24b3331dfca7ddbfd1ad", "format": 1 }, { - "name": "tests/sanity/ignore.txt", + "name": "tests/sanity/ignore-2.17.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8", + "chksum_sha256": "7919c2c8970b1cac1d23835cdb9a3a250190bd789e4f24b3331dfca7ddbfd1ad", "format": 1 }, { @@ -1299,7 +1292,7 @@ "name": "tests/unit/compat/mock.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0af958450cf6de3fbafe94b1111eae8ba5a8dbe1d785ffbb9df81f26e4946d99", + "chksum_sha256": "77edbe32e554aef3000b7d3c0bf7ae96c307cb0f0943fe91a4dfa4d840ba7fc9", "format": 1 }, { @@ -1327,7 +1320,7 @@ "name": "tests/unit/mock/loader.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cfe3480f0eae6d3723ee62d01d00a0e9f58fcdc082ea1d8e4836157c56d4fa95", + "chksum_sha256": "7307b7f5d85fc5a4de7fe47f0b5f008e57fb24a0fe2702f09d9d7e80afbc44d8", "format": 1 }, { @@ -1481,7 +1474,7 @@ "name": "tests/utils/shippable/shippable.sh", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "fbd386cce60ec181967826a2accc28b054021c67b124b056120dc37fca1c9a10", + "chksum_sha256": "60fa0850685439febcef31fe85586a7f346e9155fa563be2549365a988c3fabe", "format": 1 }, { @@ -1516,7 +1509,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0ebfd06c05555985fd1766d51b262d7d16bdcbb7e62a556533a583c7804cf664", + "chksum_sha256": "65a2321cc2f0390f03fe9d00e12d2fa8fc98b65d1e54a44325427abda483b724", "format": 1 }, { diff --git a/ansible_collections/community/rabbitmq/MANIFEST.json b/ansible_collections/community/rabbitmq/MANIFEST.json index aef8fe4bf..9653a4d58 100644 --- a/ansible_collections/community/rabbitmq/MANIFEST.json +++ b/ansible_collections/community/rabbitmq/MANIFEST.json @@ -2,7 +2,7 @@ "collection_info": { "namespace": "community", "name": "rabbitmq", - "version": "1.2.3", + "version": "1.3.0", "authors": [ "Ansible (https://github.com/ansible)", "community.rabbitmq" @@ -24,7 +24,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5ccdbf6355d35529c8944cfa5f572e21e987b5050135b9262c754cdcbc1c25d7", + "chksum_sha256": "e4a87617bfd273702d37e86b00a3e37f03b8242320e8ffa8f90d2f7b9b9cc975", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/rabbitmq/changelogs/changelog.yaml b/ansible_collections/community/rabbitmq/changelogs/changelog.yaml index ee3c424ba..db72d33e0 100644 --- a/ansible_collections/community/rabbitmq/changelogs/changelog.yaml +++ b/ansible_collections/community/rabbitmq/changelogs/changelog.yaml @@ -95,22 +95,21 @@ releases: 1.2.3: changes: bugfixes: + - Various CI fixes (https://github.com/ansible-collections/community.rabbitmq/pull/139 + & https://github.com/ansible-collections/community.rabbitmq/pull/141). - rabbitmq_queue - fixing an issue where a special character in the queue name would result in an API error (https://github.com/ansible-collections/community.rabbitmq/issues/114). minor_changes: - rabbitmq_exchange - adding ability to specify exchange types that are enabled - via plugins. I(x-random), I(x-consistent-hash) and I(x-recent-history) - (https://github.com/ansible-collections/community.rabbitmq/pull/142). + via plugins. I(x-random), I(x-consistent-hash) and I(x-recent-history) (https://github.com/ansible-collections/community.rabbitmq/pull/142). - rabbitmq_publish - fixing issue with publishing to exchanges and adding exchange documentation examples. Publishing to an exchange or queue is now mutually - exclusive (https://github.com/ansible-collections/community.rabbitmq/pull/140). - - Various CI fixes (https://github.com/ansible-collections/community.rabbitmq/pull/139 & - https://github.com/ansible-collections/community.rabbitmq/pull/141). + exclusive (https://github.com/ansible-collections/community.rabbitmq/pull/140). release_summary: 'This is the minor release of the ``community.rabbitmq`` collection. This changelog contains all changes to the modules and plugins in this collection - that have been made after the 1.2.1 release.' + that have been made after the 1.2.2 release.' fragments: - 1.2.3.yml - 114-queue-name-escape.yml @@ -118,3 +117,16 @@ releases: - 140-fixing-publishing-to-exchanges.yaml - 142-new-plugin-exchanges.yml release_date: '2022-11-04' + 1.3.0: + changes: + minor_changes: + - rabbitmq_user - add support to user manipulation through RabbitMQ API (https://github.com/ansible-collections/community.rabbitmq/issues/76) + release_summary: 'This is the minor release of the ``community.rabbitmq`` collection. + + This changelog contains all changes to the modules and plugins in this collection + + that have been made after the 1.2.3 release.' + fragments: + - 1.3.0.yml + - 120-api-managed-users.yaml + release_date: '2024-03-31' diff --git a/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py b/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py index 9ecd97e5f..16a93868c 100644 --- a/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py +++ b/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py @@ -98,14 +98,13 @@ RETURN = """ import json -from ansible.errors import AnsibleError, AnsibleParserError +from ansible.errors import AnsibleError from ansible.plugins.lookup import LookupBase from ansible.module_utils._text import to_native, to_text from ansible.utils.display import Display try: import pika - from pika import spec HAS_PIKA = True except ImportError: HAS_PIKA = False diff --git a/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py b/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py index f981c8539..5f00acc91 100644 --- a/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py +++ b/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py @@ -21,7 +21,6 @@ PIKA_IMP_ERR = None try: import pika import pika.exceptions - from pika import spec HAS_PIKA = True except ImportError: PIKA_IMP_ERR = traceback.format_exc() diff --git a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py index 5ecbd4ec4..8728bf757 100644 --- a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py +++ b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py @@ -55,6 +55,21 @@ EXAMPLES = r""" name: local-username value: '"guest"' state: present + +- name: Create or update a shovel + vars: + payload: + src-protocol: "amqp091" + src-uri: "amqp://" + src-queue: "src-queue" + dest-protocol: "amqp091" + dest-uri: "amqp://guest:guest@example.com" + dest-queue: "dest-queue" + community.rabbitmq.rabbitmq_parameter: + component: shovel + name: "shovel-name" + value: "{{ payload | to_json }}" + state: present """ import json from ansible.module_utils.basic import AnsibleModule diff --git a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py index 38b5a64bb..e4054deaa 100644 --- a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py +++ b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py @@ -187,15 +187,7 @@ result: 'result': { 'content_type': 'text/plain', 'msg': 'Successfully published to queue test', 'queue': 'test' } ''' -try: - import pika - HAS_PIKA = True -except ImportError: - HAS_PIKA = False - - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native, to_text from ansible_collections.community.rabbitmq.plugins.module_utils.rabbitmq import RabbitClient diff --git a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py index 87d6864fc..b941b759f 100644 --- a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py +++ b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py @@ -5,8 +5,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 -__metaclass__ = type +__metaclass__ = type DOCUMENTATION = r''' --- @@ -30,7 +30,8 @@ options: type: str tags: description: - - User tags specified as comma delimited + - User tags specified as comma delimited. + - The suggested tags to use are management, policymaker, monitoring and administrator. type: str permissions: description: @@ -103,9 +104,36 @@ options: description: - C(on_create) will only set the password for newly created users. C(always) will update passwords if they differ. type: str - required: false default: on_create choices: ['on_create', 'always'] + login_protocol: + description: + - Specify which TCP/IP protocol will be used. + type: str + default: http + choices: ['http', 'https'] + version_added: '1.3.0' + login_host: + description: + - Hostname of API. + type: str + version_added: '1.3.0' + login_port: + description: + - login_port of access from API. + type: str + default: '15672' + version_added: '1.3.0' + login_user: + description: + - Administrator's username the management API. + type: str + version_added: '1.3.0' + login_password: + description: + - Login password of the management API. + type: str + version_added: '1.3.0' ''' EXAMPLES = r''' @@ -146,13 +174,64 @@ EXAMPLES = r''' read_priv: .* write_priv: 'prod\\.logging\\..*' state: present + +- name: |- + Add or Update a user using the API + community.rabbitmq.rabbitmq_user: + user: joe + password: changeme + tags: monitoring + login_protocol: https + login_host: localhost + login_port: 15672 + login_user: admin + login_password: changeadmin + permissions: + - vhost: / + configure_priv: .* + read_priv: .* + write_priv: .* + topic_permissions: + - vhost: / + exchange: amq.topic + read_priv: .* + write_priv: 'prod\\.logging\\..*' + state: present + + +- name: |- + Remove a user using the API + community.rabbitmq.rabbitmq_user: + user: joe + password: changeme + tags: monitoring + login_protocol: https + login_host: localhost + login_port: 15672 + login_user: admin + login_password: changeadmin + state: absent + ''' -import ansible_collections.community.rabbitmq.plugins.module_utils.version as Version -import json -import re +import ansible_collections.community.rabbitmq.plugins.module_utils.version as Version # noqa: E402 +import json # noqa: E402 +import re # noqa: E402 + +from ansible.module_utils.six.moves.urllib import parse + +import traceback + +REQUESTS_IMP_ERR = None +try: + import requests + + HAS_REQUESTS = True +except ImportError: + REQUESTS_IMP_ERR = traceback.format_exc() + HAS_REQUESTS = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule # noqa: E402 from ansible.module_utils.common.collections import count @@ -193,9 +272,24 @@ def first(iterable): return next(iter(iterable)) +def treat_permissions_for_api(permissions): + return { + "configure": permissions.get('configure') if permissions.get('configure') else '^$', + "write": permissions.get('write') if permissions.get('write') else '^$', + "read": permissions.get('read') if permissions.get('read') else '^$' + } + + +def treat_topic_permissions_for_api(permissions): + return {"exchange": permissions.get('exchange'), "write": permissions.get('write'), + "read": permissions.get('read')} + + class RabbitMqUser(object): def __init__(self, module, username, password, tags, permissions, - topic_permissions, node, bulk_permissions=False): + topic_permissions, node, bulk_permissions=False, + login_protocol=None, login_host=None, login_port=None, + login_user=None, login_password=None): self.module = module self.username = username self.password = password or '' @@ -204,12 +298,21 @@ class RabbitMqUser(object): self.permissions = as_permission_dict(permissions) self.topic_permissions = as_topic_permission_dict(topic_permissions) self.bulk_permissions = bulk_permissions + self.login_protocol = login_protocol + self.login_host = login_host + self.login_port = login_port + self.login_user = login_user + self.login_password = login_password self.existing_tags = None self.existing_permissions = dict() self.existing_topic_permissions = dict() - self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True) - self._version = self._check_version() + if self.login_host is not None: + self._rabbitmqctl = module.get_bin_path('rabbitmqctl', False) + self._version = None + else: + self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True) + self._version = self._check_version() def _check_version(self): """Get the version of the RabbitMQ server.""" @@ -233,6 +336,7 @@ class RabbitMqUser(object): version of `rabbitmqctl` we are using, so we will try to use the JSON formatter and see what happens. In some versions of """ + def int_list_to_str(ints): return ''.join([chr(i) for i in ints]) @@ -318,22 +422,39 @@ class RabbitMqUser(object): If the version of the node is >= 3.7.6 the JSON formatter will be used, otherwise the plaintext will be parsed. """ - if self._version >= Version.StrictVersion('3.7.6'): - users = dict([(user_entry['user'], user_entry['tags']) - for user_entry in json.loads(self._exec(['list_users', '--formatter', 'json']))]) + users = dict() + if self.login_host is not None: + response = self.request_users_api('GET') + if response.status_code == 200: + if isinstance(response.json(), list): + users = dict([(user_entry['name'], user_entry['tags']) for user_entry in response.json()]) + else: + users = {response.json()['name']: response.json()['tags']} + elif response.status_code == 404: + return None + else: + self.module.fail_json( + msg="Error getting the user", + status=response.status_code, + details=response.text + ) else: - users = self._exec(['list_users']) + if self._version >= Version.StrictVersion('3.7.6'): + users = dict([(user_entry['user'], user_entry['tags']) + for user_entry in json.loads(self._exec(['list_users', '--formatter', 'json']))]) + else: + users = self._exec(['list_users']) - def process_tags(tags): - if not tags: - return list() - return tags.replace('[', '').replace(']', '').replace(' ', '').strip('\t').split(',') + def process_tags(tags): + if not tags: + return list() + return tags.replace('[', '').replace(']', '').replace(' ', '').strip('\t').split(',') - users_and_tags = [user_entry.split('\t') for user_entry in users.strip().split('\n')] + users_and_tags = [user_entry.split('\t') for user_entry in users.strip().split('\n')] - users = dict() - for user_parts in users_and_tags: - users[user_parts[0]] = process_tags(user_parts[1]) if len(user_parts) > 1 else [] + users = dict() + for user_parts in users_and_tags: + users[user_parts[0]] = process_tags(user_parts[1]) if len(user_parts) > 1 else [] self.existing_tags = users.get(self.username, list()) self.existing_permissions = self._get_permissions() if self.username in users else dict() @@ -342,17 +463,48 @@ class RabbitMqUser(object): def _get_permissions(self): """Get permissions of the user from RabbitMQ.""" - if self._version >= Version.StrictVersion('3.7.6'): - permissions = json.loads(self._exec(['list_user_permissions', self.username, '--formatter', 'json'])) + if self.login_host is not None: + try: + response = requests.get(self.get_permissions_api_url_builder(self.username), + auth=(self.login_user, + self.login_password)) + except requests.exceptions.RequestException as exception: + msg = ("Error trying to request topic permissions " + "of the user %s info in rabbitmq.") % (self.username) + self.module.fail_json( + msg=msg, + exception=exception, + ) + + if response.ok or (response.status_code == 204): + permissions = list() + for permission in response.json(): + permissions.append({ + "vhost": permission.get('vhost'), + "configure": permission.get('configure'), + "write": permission.get('write'), + "read": permission.get('read') + }) + elif response.status_code == 404: + return None + else: + self.module.fail_json( + msg="Error getting the user", + status=response.status_code, + details=response.text + ) else: - output = self._exec(['list_user_permissions', self.username]).strip().split('\n') - perms_out = [perm.split('\t') for perm in output if perm.strip()] - # Filter out headers from the output of the command in case they are still present - perms_out = [perm for perm in perms_out if perm != ["vhost", "configure", "write", "read"]] + if self._version >= Version.StrictVersion('3.7.6'): + permissions = json.loads(self._exec(['list_user_permissions', self.username, '--formatter', 'json'])) + else: + output = self._exec(['list_user_permissions', self.username]).strip().split('\n') + perms_out = [perm.split('\t') for perm in output if perm.strip()] + # Filter out headers from the output of the command in case they are still present + perms_out = [perm for perm in perms_out if perm != ["vhost", "configure", "write", "read"]] - permissions = list() - for vhost, configure, write, read in perms_out: - permissions.append(dict(vhost=vhost, configure=configure, write=write, read=read)) + permissions = list() + for vhost, configure, write, read in perms_out: + permissions.append(dict(vhost=vhost, configure=configure, write=write, read=read)) if self.bulk_permissions: return as_permission_dict(permissions) @@ -361,58 +513,166 @@ class RabbitMqUser(object): def _get_topic_permissions(self): """Get topic permissions of the user from RabbitMQ.""" - if self._version < Version.StrictVersion('3.7.0'): - return dict() - if self._version >= Version.StrictVersion('3.7.6'): - permissions = json.loads(self._exec(['list_user_topic_permissions', self.username, '--formatter', 'json'])) + if self.login_host is not None: + try: + response = requests.get(self.get_topic_permissions_api_url_builder(self.username), + auth=(self.login_user, + self.login_password)) + except requests.exceptions.RequestException as exception: + msg = ("Error trying to request permissions " + "of the user %s info in rabbitmq.") % (self.username) + self.module.fail_json( + msg=msg, + exception=exception, + ) + + if response.ok or (response.status_code == 204): + permissions = list() + for permission in response.json(): + permissions.append({ + "vhost": permission.get('vhost'), + "exchange": permission.get('exchange'), + "write": permission.get('write'), + "read": permission.get('read') + }) + return as_topic_permission_dict(permissions) + elif response.status_code == 404: + return None + else: + self.module.fail_json( + msg="Error getting the user", + status=response.status_code, + details=response.text + ) else: - output = self._exec(['list_user_topic_permissions', self.username]).strip().split('\n') - perms_out = [perm.split('\t') for perm in output if perm.strip()] - permissions = list() - for vhost, exchange, write, read in perms_out: - permissions.append(dict(vhost=vhost, exchange=exchange, write=write, read=read)) - return as_topic_permission_dict(permissions) + if self._version < Version.StrictVersion('3.7.0'): + return dict() + if self._version >= Version.StrictVersion('3.7.6'): + permissions = json.loads( + self._exec(['list_user_topic_permissions', self.username, '--formatter', 'json'])) + else: + output = self._exec(['list_user_topic_permissions', self.username]).strip().split('\n') + perms_out = [perm.split('\t') for perm in output if perm.strip()] + permissions = list() + for vhost, exchange, write, read in perms_out: + permissions.append(dict(vhost=vhost, exchange=exchange, write=write, read=read)) + return as_topic_permission_dict(permissions) def check_password(self): """Return `True` if the user can authenticate successfully.""" - rc, out, err = self._exec(['authenticate_user', self.username, self.password], check_rc=False) - return rc == 0 + if self.login_host is not None: + url = "%s://%s:%s/api/whoami" % ( + self.login_protocol, + self.login_host, + self.login_port) + try: + response = requests.get(url, auth=(self.login_user, self.login_password)) + except requests.exceptions.RequestException as exception: + msg = ("Error trying to request permissions " + "of the user %s info in rabbitmq.") % (self.username) + self.module.fail_json( + msg=msg, + exception=exception, + ) + + if response.ok or response.json().get('reason') == "Not management user": + return True + else: + return False + else: + rc, out, err = self._exec(['authenticate_user', self.username, self.password], check_rc=False) + return rc == 0 def add(self): - self._exec(['add_user', self.username, self.password or '']) - if not self.password: - self._exec(['clear_password', self.username]) + if self.login_host is not None: + data = {"password": self.password, "tags": self.treat_tags_for_api() or ""} + response = self.request_users_api('PUT', data) + + if not response.ok or (response.status_code == 204): + msg = ("Error trying to create user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + self._exec(['add_user', self.username, self.password or '']) + if not self.password: + self._exec(['clear_password', self.username]) def delete(self): - self._exec(['delete_user', self.username]) + if self.login_host is not None: + response = self.request_users_api('DELETE') + if response.status_code != 204: + msg = ("Error trying to remove user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + self._exec(['delete_user', self.username]) def change_password(self): - if self.password: - self._exec(['change_password', self.username, self.password]) + if self.login_host is not None: + data = {"password": self.password or "", "tags": self.tags or ""} + response = self.request_users_api('PUT', data) + + if not response.ok or (response.status_code == 204): + msg = ("Error trying to set tags for the user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + self.module.fail_json( + msg="Error setting tags for the user", + status=response.status_code, + details=response.text + ) else: - self._exec(['clear_password', self.username]) + if self.password: + self._exec(['change_password', self.username, self.password]) + else: + self._exec(['clear_password', self.username]) def set_tags(self): - self._exec(['set_user_tags', self.username] + self.tags) + if self.login_host is not None: + data = {"password": self.password, "tags": self.treat_tags_for_api() or ""} + response = self.request_users_api('PUT', data) + + if not response.status_code == 204: + msg = ("Error trying to set tags for the user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + + else: + self._exec(['set_user_tags', self.username] + self.tags) def set_permissions(self): permissions_to_add = list() for vhost, permission_dict in self.permissions.items(): if permission_dict != self.existing_permissions.get(vhost, {}): permissions_to_add.append(permission_dict) - permissions_to_clear = list() for vhost in self.existing_permissions.keys(): if vhost not in self.permissions: permissions_to_clear.append(vhost) for vhost in permissions_to_clear: - cmd = 'clear_permissions -p {vhost} {username}'.format(username=self.username, vhost=vhost) - self._exec(cmd.split(' ')) + if self.login_host is not None: + response = self.request_permissions_api('DELETE', vhost) + if response.status_code != 204: + msg = ("Error trying to remove permission from user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + cmd = 'clear_permissions -p {vhost} {username}'.format(username=self.username, vhost=vhost) + self._exec(cmd.split(' ')) for permissions in permissions_to_add: - cmd = ('set_permissions -p {vhost} {username} {configure} {write} {read}' - .format(username=self.username, **permissions)) - self._exec(cmd.split(' ')) + if self.login_host is not None: + response = self.request_permissions_api('PUT', permissions.get('vhost'), + data=treat_permissions_for_api(permissions)) + if response.status_code not in (201, 204): + msg = ("Error trying to add permission to user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + cmd = ('set_permissions -p {vhost} {username} {configure} {write} {read}' + .format(username=self.username, **permissions)) + self._exec(cmd.split(' ')) self.existing_permissions = self._get_permissions() def set_topic_permissions(self): @@ -428,13 +688,28 @@ class RabbitMqUser(object): for vhost_exchange in permissions_to_clear: vhost, exchange = vhost_exchange - cmd = ('clear_topic_permissions -p {vhost} {username} {exchange}' - .format(username=self.username, vhost=vhost, exchange=exchange)) - self._exec(cmd.split(' ')) + if self.login_host is not None: + response = self.request_topic_permissions_api('DELETE', vhost) + if response.status_code != 204: + msg = ("Error trying to remove topic permission from user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + cmd = ('clear_topic_permissions -p {vhost} {username} {exchange}' + .format(username=self.username, vhost=vhost, exchange=exchange)) + self._exec(cmd.split(' ')) for permissions in permissions_to_add: - cmd = ('set_topic_permissions -p {vhost} {username} {exchange} {write} {read}' - .format(username=self.username, **permissions)) - self._exec(cmd.split(' ')) + if self.login_host is not None: + response = self.request_topic_permissions_api('PUT', permissions.get('vhost'), + data=treat_topic_permissions_for_api(permissions)) + if response.status_code not in (201, 204): + msg = ("Error trying to add topic permission to user %s in rabbitmq. " + "Status code '%s'.") % (self.username, response.status_code) + self.module.fail_json(msg=msg) + else: + cmd = ('set_topic_permissions -p {vhost} {username} {exchange} {write} {read}' + .format(username=self.username, **permissions)) + self._exec(cmd.split(' ')) self.existing_topic_permissions = self._get_topic_permissions() def has_tags_modifications(self): @@ -446,6 +721,91 @@ class RabbitMqUser(object): def has_topic_permissions_modifications(self): return self.existing_topic_permissions != self.topic_permissions + def users_api_url_builder(self, username): + return "%s://%s:%s/api/users/%s" % ( + self.login_protocol, + self.login_host, + self.login_port, + parse.quote(username, ""), + ) + + def get_permissions_api_url_builder(self, username): + return "%s://%s:%s/api/users/%s/permissions" % ( + self.login_protocol, + self.login_host, + self.login_port, + username, + ) + + def get_topic_permissions_api_url_builder(self, username): + return "%s://%s:%s/api/users/%s/topic-permissions" % ( + self.login_protocol, + self.login_host, + self.login_port, + username, + ) + + def permissions_api_url_builder(self, username, vhost): + if vhost is None or vhost == "/": + vhost = "%2F" + return "%s://%s:%s/api/permissions/%s/%s" % ( + self.login_protocol, + self.login_host, + self.login_port, + vhost, + username, + ) + + def topic_permissions_api_url_builder(self, username, vhost): + if vhost is None or vhost == "/": + vhost = "%2F" + return "%s://%s:%s/api/topic-permissions/%s/%s" % ( + self.login_protocol, + self.login_host, + self.login_port, + vhost, + username, + ) + + def treat_tags_for_api(self): + return ','.join(tag for tag in self.tags) + + def request_users_api(self, method, data=None): + try: + response = requests.request(method, self.users_api_url_builder(self.username), + auth=(self.login_user, self.login_password), json=data) + except requests.exceptions.RequestException as exception: + msg = "Error in HTTP request (method %s) for user %s in rabbitmq." % ( + method.lower(), + self.username, + ) + self.module.fail_json(msg=msg, exception=exception) + return response + + def request_permissions_api(self, method, vhost=None, data=None): + try: + response = requests.request(method, self.permissions_api_url_builder(self.username, vhost), + auth=(self.login_user, self.login_password), json=data) + except requests.exceptions.RequestException as exception: + msg = "Error in HTTP request (method %s) for user's permission %s in rabbitmq." % ( + method.lower(), + self.username, + ) + self.module.fail_json(msg=msg, exception=exception) + return response + + def request_topic_permissions_api(self, method, vhost=None, data=None): + try: + response = requests.request(method, self.topic_permissions_api_url_builder(self.username, vhost), + auth=(self.login_user, self.login_password), json=data) + except requests.exceptions.RequestException as exception: + msg = "Error in HTTP request (method %s) for topic permission for user %s in rabbitmq." % ( + method.lower(), + self.username, + ) + self.module.fail_json(msg=msg, exception=exception) + return response + def main(): arg_spec = dict( @@ -461,7 +821,12 @@ def main(): force=dict(default='no', type='bool'), state=dict(default='present', choices=['present', 'absent']), node=dict(default='rabbit'), - update_password=dict(default='on_create', choices=['on_create', 'always'], no_log=False) + update_password=dict(default='on_create', choices=['on_create', 'always'], no_log=False), + login_protocol=dict(type="str", default="http", choices=["http", "https"]), + login_host=dict(type="str"), + login_port=dict(type="str", default="15672"), + login_user=dict(type="str", no_log=True), + login_password=dict(type="str", no_log=True) ) module = AnsibleModule( argument_spec=arg_spec, @@ -481,6 +846,11 @@ def main(): state = module.params['state'] node = module.params['node'] update_password = module.params['update_password'] + login_protocol = module.params['login_protocol'] + login_host = module.params['login_host'] + login_port = module.params['login_port'] + login_user = module.params['login_user'] + login_password = module.params['login_password'] if permissions: vhosts = [permission.get('vhost', '/') for permission in permissions] @@ -510,7 +880,7 @@ def main(): for permission in permissions: if not permission['vhost']: - module.fail_json(msg="Error parsing vhost permissions: You can't" + module.fail_json(msg="Error parsing vhost permissions: You can't " "have an empty vhost when setting permissions") for permission in topic_permissions: @@ -524,7 +894,9 @@ def main(): rabbitmq_user = RabbitMqUser(module, username, password, tags, permissions, topic_permissions, node, - bulk_permissions=bulk_permissions) + bulk_permissions=bulk_permissions, login_protocol=login_protocol, + login_host=login_host, login_port=login_port, login_user=login_user, + login_password=login_password) result = dict(changed=False, user=username, state=state) if rabbitmq_user.get(): diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml index 740f89980..9808b9ec7 100644 --- a/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml @@ -1,5 +1,5 @@ # Rabbitmq lookup -- include: ubuntu.yml - when: +- include_tasks: ubuntu.yml + when: - ansible_distribution == 'Ubuntu' - ansible_distribution_release != 'trusty' diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml index 740f89980..9808b9ec7 100644 --- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml @@ -1,5 +1,5 @@ # Rabbitmq lookup -- include: ubuntu.yml - when: +- include_tasks: ubuntu.yml + when: - ansible_distribution == 'Ubuntu' - ansible_distribution_release != 'trusty' diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml index 740f89980..9808b9ec7 100644 --- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml @@ -1,5 +1,5 @@ # Rabbitmq lookup -- include: ubuntu.yml - when: +- include_tasks: ubuntu.yml + when: - ansible_distribution == 'Ubuntu' - ansible_distribution_release != 'trusty' diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml index e03d4c7aa..9db0b6ee6 100644 --- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml @@ -5,6 +5,8 @@ - import_tasks: tests.yml + - import_tasks: tests_api.yml + - import_tasks: tests.yml environment: RABBITMQ_NODENAME: test diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml new file mode 100644 index 000000000..51ded8778 --- /dev/null +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml @@ -0,0 +1,131 @@ +--- + +- name: Test add user + block: + - name: Add user + rabbitmq_user: user=joe password=changeme login_user=guest login_password=guest login_host=127.0.0.1 + register: add_user + + - name: Check that user adding succeeds with a change + assert: + that: + - add_user.changed == true + +- name: Test add user idempotence + block: + - name: Add user + rabbitmq_user: user=joe password=changeme login_user=guest login_password=guest login_host=127.0.0.1 + register: add_user + + - name: Check that user adding succeeds without a change + assert: + that: + - add_user.changed == false + +- name: Test change user permissions + block: + - name: Add user with permissions + rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* login_user=guest login_password=guest login_host=127.0.0.1 + register: add_user + + - name: Check that changing permissions succeeds with a change + assert: + that: + - add_user.changed == true + +- name: Test change user permissions idempotence + block: + - name: Add user with permissions + rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* login_user=guest login_password=guest login_host=127.0.0.1 + register: add_user + + - name: Check that changing permissions succeeds without a change + assert: + that: + - add_user.changed == false + +- name: Test change user topic permissions + block: + - name: Add user with topic permissions + rabbitmq_user: + user: joe + password: changeme + topic_permissions: + - vhost: / + exchange: amq.topic + read_priv: .* + write_priv: .* + login_user: guest + login_password: guest + login_host: 127.0.0.1 + register: add_user + + - name: Check that changing topic permissions succeeds with a change + assert: + that: + - add_user.changed == true + +- name: Test change user topic permissions idempotence + block: + - name: Add user with topic permissions + rabbitmq_user: + user: joe + password: changeme + topic_permissions: + - vhost: / + exchange: amq.topic + read_priv: .* + write_priv: .* + login_user: guest + login_password: guest + login_host: 127.0.0.1 + register: add_user + + - name: Check that changing topic permissions succeeds without a change + assert: + that: + - add_user.changed == false + +- name: Test add user tags + block: + - name: Add user with tags + rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=management,administrator login_user=guest login_password=guest login_host=127.0.0.1 + register: add_user + + - name: Check that adding tags succeeds with a change + assert: + that: + - add_user.changed == true + +- name: Test add user tags idempotence + block: + - name: Add user with tags + rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=administrator,management login_user=guest login_password=guest login_host=127.0.0.1 + register: add_user + + - name: Check that adding tags succeeds without a change + assert: + that: + - add_user.changed == false + +- name: Test remove user + block: + - name: Remove user + rabbitmq_user: user=joe state=absent login_user=guest login_password=guest login_host=127.0.0.1 + register: remove_user + + - name: Check that user removing succeeds with a change + assert: + that: + - remove_user.changed == true + +- name: Test remove user idempotence + block: + - name: Remove user + rabbitmq_user: user=joe state=absent login_user=guest login_password=guest login_host=127.0.0.1 + register: remove_user + + - name: Check that user removing succeeds without a change + assert: + that: + - remove_user.changed == false diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml index 740f89980..9808b9ec7 100644 --- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml @@ -1,5 +1,5 @@ # Rabbitmq lookup -- include: ubuntu.yml - when: +- include_tasks: ubuntu.yml + when: - ansible_distribution == 'Ubuntu' - ansible_distribution_release != 'trusty' diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml index 740f89980..9808b9ec7 100644 --- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml +++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml @@ -1,5 +1,5 @@ # Rabbitmq lookup -- include: ubuntu.yml - when: +- include_tasks: ubuntu.yml + when: - ansible_distribution == 'Ubuntu' - ansible_distribution_release != 'trusty' diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.10.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.10.txt deleted file mode 100644 index caf221794..000000000 --- a/ansible_collections/community/rabbitmq/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/rabbitmq/tests/sanity/ignore-2.11.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.11.txt deleted file mode 100644 index caf221794..000000000 --- a/ansible_collections/community/rabbitmq/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/rabbitmq/tests/sanity/ignore-2.15.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt index caf221794..8fd3dfc11 100644 --- a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt +++ b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt @@ -1,2 +1,4 @@ tests/utils/shippable/check_matrix.py replace-urlopen tests/utils/shippable/timing.py shebang +plugins/module_utils/version.py pylint:unused-import +tests/unit/compat/builtins.py pylint:unused-import diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt new file mode 100644 index 000000000..fe7e62dfc --- /dev/null +++ b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt @@ -0,0 +1,3 @@ +tests/utils/shippable/timing.py shebang +plugins/module_utils/version.py pylint:unused-import +tests/unit/compat/builtins.py pylint:unused-import diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt new file mode 100644 index 000000000..fe7e62dfc --- /dev/null +++ b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt @@ -0,0 +1,3 @@ +tests/utils/shippable/timing.py shebang +plugins/module_utils/version.py pylint:unused-import +tests/unit/compat/builtins.py pylint:unused-import diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.txt deleted file mode 100644 index caf221794..000000000 --- a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.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/rabbitmq/tests/sanity/ignore.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore.txt deleted file mode 100644 index caf221794..000000000 --- a/ansible_collections/community/rabbitmq/tests/sanity/ignore.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/rabbitmq/tests/unit/compat/mock.py b/ansible_collections/community/rabbitmq/tests/unit/compat/mock.py index 0972cd2e8..c7d018307 100644 --- a/ansible_collections/community/rabbitmq/tests/unit/compat/mock.py +++ b/ansible_collections/community/rabbitmq/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 from 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 from _data global file_spec if file_spec is None: diff --git a/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py b/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py index 00a584127..e25731e03 100644 --- a/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py +++ b/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py @@ -30,7 +30,7 @@ class DictDataLoader(DataLoader): def __init__(self, file_mapping=None): file_mapping = {} if file_mapping is None else file_mapping - assert type(file_mapping) == dict + assert isinstance(file_mapping, dict) super(DictDataLoader, self).__init__() diff --git a/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh b/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh index f9b187212..1f69f87e3 100755 --- a/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh +++ b/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh @@ -67,6 +67,7 @@ if [ "${SHIPPABLE_BUILD_ID:-}" ]; then SHIPPABLE_RESULT_DIR="$(pwd)/shippable" TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/rabbitmq" mkdir -p "${TEST_DIR}" + # shellcheck disable=SC2153 cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}" cd "${TEST_DIR}" else diff --git a/ansible_collections/community/routeros/.github/workflows/ansible-test.yml b/ansible_collections/community/routeros/.github/workflows/ansible-test.yml index 0444f593f..f743ae51a 100644 --- a/ansible_collections/community/routeros/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/routeros/.github/workflows/ansible-test.yml @@ -34,6 +34,7 @@ jobs: - 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 @@ -79,6 +80,7 @@ jobs: - stable-2.14 - stable-2.15 - stable-2.16 + - stable-2.17 - devel steps: @@ -113,6 +115,7 @@ jobs: python: - "3.10" - "3.11" + - "3.12" include: # 2.9 - ansible: stable-2.9 @@ -142,6 +145,9 @@ jobs: # 2.16 - ansible: stable-2.16 python: "3.10" + # 2.17 + - ansible: stable-2.17 + python: "3.12" steps: - name: >- diff --git a/ansible_collections/community/routeros/CHANGELOG.md b/ansible_collections/community/routeros/CHANGELOG.md index 99d0bbe6a..adb4f7420 100644 --- a/ansible_collections/community/routeros/CHANGELOG.md +++ b/ansible_collections/community/routeros/CHANGELOG.md @@ -2,106 +2,109 @@ **Topics** -- <a href="#v2-14-0">v2\.14\.0</a> +- <a href="#v2-15-0">v2\.15\.0</a> - <a href="#release-summary">Release Summary</a> - <a href="#minor-changes">Minor Changes</a> -- <a href="#v2-13-0">v2\.13\.0</a> +- <a href="#v2-14-0">v2\.14\.0</a> - <a href="#release-summary-1">Release Summary</a> - <a href="#minor-changes-1">Minor Changes</a> - - <a href="#bugfixes">Bugfixes</a> -- <a href="#v2-12-0">v2\.12\.0</a> +- <a href="#v2-13-0">v2\.13\.0</a> - <a href="#release-summary-2">Release Summary</a> - <a href="#minor-changes-2">Minor Changes</a> -- <a href="#v2-11-0">v2\.11\.0</a> + - <a href="#bugfixes">Bugfixes</a> +- <a href="#v2-12-0">v2\.12\.0</a> - <a href="#release-summary-3">Release Summary</a> - <a href="#minor-changes-3">Minor Changes</a> -- <a href="#v2-10-0">v2\.10\.0</a> +- <a href="#v2-11-0">v2\.11\.0</a> - <a href="#release-summary-4">Release Summary</a> - <a href="#minor-changes-4">Minor Changes</a> - - <a href="#bugfixes-1">Bugfixes</a> -- <a href="#v2-9-0">v2\.9\.0</a> +- <a href="#v2-10-0">v2\.10\.0</a> - <a href="#release-summary-5">Release Summary</a> - <a href="#minor-changes-5">Minor Changes</a> + - <a href="#bugfixes-1">Bugfixes</a> +- <a href="#v2-9-0">v2\.9\.0</a> + - <a href="#release-summary-6">Release Summary</a> + - <a href="#minor-changes-6">Minor Changes</a> - <a href="#bugfixes-2">Bugfixes</a> - <a href="#v2-8-3">v2\.8\.3</a> - - <a href="#release-summary-6">Release Summary</a> + - <a href="#release-summary-7">Release Summary</a> - <a href="#known-issues">Known Issues</a> - <a href="#v2-8-2">v2\.8\.2</a> - - <a href="#release-summary-7">Release Summary</a> + - <a href="#release-summary-8">Release Summary</a> - <a href="#bugfixes-3">Bugfixes</a> - <a href="#v2-8-1">v2\.8\.1</a> - - <a href="#release-summary-8">Release Summary</a> + - <a href="#release-summary-9">Release Summary</a> - <a href="#bugfixes-4">Bugfixes</a> - <a href="#v2-8-0">v2\.8\.0</a> - - <a href="#release-summary-9">Release Summary</a> - - <a href="#minor-changes-6">Minor Changes</a> - - <a href="#bugfixes-5">Bugfixes</a> -- <a href="#v2-7-0">v2\.7\.0</a> - <a href="#release-summary-10">Release Summary</a> - <a href="#minor-changes-7">Minor Changes</a> - - <a href="#bugfixes-6">Bugfixes</a> -- <a href="#v2-6-0">v2\.6\.0</a> + - <a href="#bugfixes-5">Bugfixes</a> +- <a href="#v2-7-0">v2\.7\.0</a> - <a href="#release-summary-11">Release Summary</a> - <a href="#minor-changes-8">Minor Changes</a> - - <a href="#bugfixes-7">Bugfixes</a> -- <a href="#v2-5-0">v2\.5\.0</a> + - <a href="#bugfixes-6">Bugfixes</a> +- <a href="#v2-6-0">v2\.6\.0</a> - <a href="#release-summary-12">Release Summary</a> - <a href="#minor-changes-9">Minor Changes</a> - - <a href="#bugfixes-8">Bugfixes</a> -- <a href="#v2-4-0">v2\.4\.0</a> + - <a href="#bugfixes-7">Bugfixes</a> +- <a href="#v2-5-0">v2\.5\.0</a> - <a href="#release-summary-13">Release Summary</a> - <a href="#minor-changes-10">Minor Changes</a> + - <a href="#bugfixes-8">Bugfixes</a> +- <a href="#v2-4-0">v2\.4\.0</a> + - <a href="#release-summary-14">Release Summary</a> + - <a href="#minor-changes-11">Minor Changes</a> - <a href="#bugfixes-9">Bugfixes</a> - <a href="#known-issues-1">Known Issues</a> - <a href="#v2-3-1">v2\.3\.1</a> - - <a href="#release-summary-14">Release Summary</a> + - <a href="#release-summary-15">Release Summary</a> - <a href="#known-issues-2">Known Issues</a> - <a href="#v2-3-0">v2\.3\.0</a> - - <a href="#release-summary-15">Release Summary</a> - - <a href="#minor-changes-11">Minor Changes</a> + - <a href="#release-summary-16">Release Summary</a> + - <a href="#minor-changes-12">Minor Changes</a> - <a href="#bugfixes-10">Bugfixes</a> - <a href="#v2-2-1">v2\.2\.1</a> - - <a href="#release-summary-16">Release Summary</a> + - <a href="#release-summary-17">Release Summary</a> - <a href="#bugfixes-11">Bugfixes</a> - <a href="#v2-2-0">v2\.2\.0</a> - - <a href="#release-summary-17">Release Summary</a> - - <a href="#minor-changes-12">Minor Changes</a> + - <a href="#release-summary-18">Release Summary</a> + - <a href="#minor-changes-13">Minor Changes</a> - <a href="#bugfixes-12">Bugfixes</a> - <a href="#new-modules">New Modules</a> - <a href="#v2-1-0">v2\.1\.0</a> - - <a href="#release-summary-18">Release Summary</a> - - <a href="#minor-changes-13">Minor Changes</a> + - <a href="#release-summary-19">Release Summary</a> + - <a href="#minor-changes-14">Minor Changes</a> - <a href="#bugfixes-13">Bugfixes</a> - <a href="#new-modules-1">New Modules</a> - <a href="#v2-0-0">v2\.0\.0</a> - - <a href="#release-summary-19">Release Summary</a> - - <a href="#minor-changes-14">Minor Changes</a> + - <a href="#release-summary-20">Release Summary</a> + - <a href="#minor-changes-15">Minor Changes</a> - <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a> - <a href="#bugfixes-14">Bugfixes</a> - <a href="#new-plugins">New Plugins</a> - <a href="#filter">Filter</a> - <a href="#v1-2-0">v1\.2\.0</a> - - <a href="#release-summary-20">Release Summary</a> - - <a href="#minor-changes-15">Minor Changes</a> - - <a href="#bugfixes-15">Bugfixes</a> -- <a href="#v1-1-0">v1\.1\.0</a> - <a href="#release-summary-21">Release Summary</a> - <a href="#minor-changes-16">Minor Changes</a> -- <a href="#v1-0-1">v1\.0\.1</a> + - <a href="#bugfixes-15">Bugfixes</a> +- <a href="#v1-1-0">v1\.1\.0</a> - <a href="#release-summary-22">Release Summary</a> + - <a href="#minor-changes-17">Minor Changes</a> +- <a href="#v1-0-1">v1\.0\.1</a> + - <a href="#release-summary-23">Release Summary</a> - <a href="#bugfixes-16">Bugfixes</a> - <a href="#v1-0-0">v1\.0\.0</a> - - <a href="#release-summary-23">Release Summary</a> + - <a href="#release-summary-24">Release Summary</a> - <a href="#bugfixes-17">Bugfixes</a> - <a href="#v0-1-1">v0\.1\.1</a> - - <a href="#release-summary-24">Release Summary</a> + - <a href="#release-summary-25">Release Summary</a> - <a href="#bugfixes-18">Bugfixes</a> - <a href="#v0-1-0">v0\.1\.0</a> - - <a href="#release-summary-25">Release Summary</a> - - <a href="#minor-changes-17">Minor Changes</a> + - <a href="#release-summary-26">Release Summary</a> + - <a href="#minor-changes-18">Minor Changes</a> -<a id="v2-14-0"></a> -## v2\.14\.0 +<a id="v2-15-0"></a> +## v2\.15\.0 <a id="release-summary"></a> ### Release Summary @@ -111,6 +114,28 @@ Feature release\. <a id="minor-changes"></a> ### Minor Changes +* api\_info\, api\_modify \- Add RouterOS 7\.x support to <code>/mpls ldp</code> path \([https\://github\.com/ansible\-collections/community\.routeros/pull/271](https\://github\.com/ansible\-collections/community\.routeros/pull/271)\)\. +* api\_info\, api\_modify \- add <code>/ip route rule</code> path for RouterOS 6\.x \([https\://github\.com/ansible\-collections/community\.routeros/pull/278](https\://github\.com/ansible\-collections/community\.routeros/pull/278)\)\. +* api\_info\, api\_modify \- add <code>/routing filter</code> path for RouterOS 6\.x \([https\://github\.com/ansible\-collections/community\.routeros/pull/279](https\://github\.com/ansible\-collections/community\.routeros/pull/279)\)\. +* api\_info\, api\_modify \- add default value for <code>from\-pool</code> field in <code>/ipv6 address</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/270](https\://github\.com/ansible\-collections/community\.routeros/pull/270)\)\. +* api\_info\, api\_modify \- add missing path <code>/interface pppoe\-server server</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/273](https\://github\.com/ansible\-collections/community\.routeros/pull/273)\)\. +* api\_info\, api\_modify \- add missing path <code>/ip dhcp\-relay</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/276](https\://github\.com/ansible\-collections/community\.routeros/pull/276)\)\. +* api\_info\, api\_modify \- add missing path <code>/queue simple</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/269](https\://github\.com/ansible\-collections/community\.routeros/pull/269)\)\. +* api\_info\, api\_modify \- add missing path <code>/queue type</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/274](https\://github\.com/ansible\-collections/community\.routeros/pull/274)\)\. +* api\_info\, api\_modify \- add missing paths <code>/routing bgp aggregate</code>\, <code>/routing bgp network</code> and <code>/routing bgp peer</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/277](https\://github\.com/ansible\-collections/community\.routeros/pull/277)\)\. +* api\_info\, api\_modify \- add support for paths <code>/mpls interface</code>\, <code>/mpls ldp accept\-filter</code>\, <code>/mpls ldp advertise\-filter</code> and <code>mpls ldp interface</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/272](https\://github\.com/ansible\-collections/community\.routeros/pull/272)\)\. + +<a id="v2-14-0"></a> +## v2\.14\.0 + +<a id="release-summary-1"></a> +### Release Summary + +Feature release\. + +<a id="minor-changes-1"></a> +### Minor Changes + * api\_info\, api\_modify \- add read\-only fields <code>installed\-version</code>\, <code>latest\-version</code> and <code>status</code> in <code>system package update</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/263](https\://github\.com/ansible\-collections/community\.routeros/pull/263)\)\. * api\_info\, api\_modify \- added support for <code>interface wifi</code> and its sub\-paths \([https\://github\.com/ansible\-collections/community\.routeros/pull/266](https\://github\.com/ansible\-collections/community\.routeros/pull/266)\)\. * api\_info\, api\_modify \- remove default value for read\-only <code>running</code> field in <code>interface wireless</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/264](https\://github\.com/ansible\-collections/community\.routeros/pull/264)\)\. @@ -118,12 +143,12 @@ Feature release\. <a id="v2-13-0"></a> ## v2\.13\.0 -<a id="release-summary-1"></a> +<a id="release-summary-2"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-1"></a> +<a id="minor-changes-2"></a> ### Minor Changes * api\_info\, api\_modify \- make path <code>user group</code> modifiable and add <code>comment</code> attribute \([https\://github\.com/ansible\-collections/community\.routeros/issues/256](https\://github\.com/ansible\-collections/community\.routeros/issues/256)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/257](https\://github\.com/ansible\-collections/community\.routeros/pull/257)\)\. @@ -137,12 +162,12 @@ Bugfix and feature release\. <a id="v2-12-0"></a> ## v2\.12\.0 -<a id="release-summary-2"></a> +<a id="release-summary-3"></a> ### Release Summary Feature release\. -<a id="minor-changes-2"></a> +<a id="minor-changes-3"></a> ### Minor Changes * api\_info\, api\_modify \- add <code>interface ovpn\-client</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/242](https\://github\.com/ansible\-collections/community\.routeros/issues/242)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/244](https\://github\.com/ansible\-collections/community\.routeros/pull/244)\)\. @@ -156,12 +181,12 @@ Feature release\. <a id="v2-11-0"></a> ## v2\.11\.0 -<a id="release-summary-3"></a> +<a id="release-summary-4"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-3"></a> +<a id="minor-changes-4"></a> ### Minor Changes * api\_info\, api\_modify \- add missing DoH parameters <code>doh\-max\-concurrent\-queries</code>\, <code>doh\-max\-server\-connections</code>\, and <code>doh\-timeout</code> to the <code>ip dns</code> path \([https\://github\.com/ansible\-collections/community\.routeros/issues/230](https\://github\.com/ansible\-collections/community\.routeros/issues/230)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/235](https\://github\.com/ansible\-collections/community\.routeros/pull/235)\) @@ -176,12 +201,12 @@ Feature and bugfix release\. <a id="v2-10-0"></a> ## v2\.10\.0 -<a id="release-summary-4"></a> +<a id="release-summary-5"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-4"></a> +<a id="minor-changes-5"></a> ### Minor Changes * api\_info \- add new <code>include\_read\_only</code> option to select behavior for read\-only values\. By default these are not returned \([https\://github\.com/ansible\-collections/community\.routeros/pull/213](https\://github\.com/ansible\-collections/community\.routeros/pull/213)\)\. @@ -213,12 +238,12 @@ Bugfix and feature release\. <a id="v2-9-0"></a> ## v2\.9\.0 -<a id="release-summary-5"></a> +<a id="release-summary-6"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-5"></a> +<a id="minor-changes-6"></a> ### Minor Changes * api\_info\, api\_modify \- add path <code>caps\-man channel</code> and enable path <code>caps\-man manager interface</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/193](https\://github\.com/ansible\-collections/community\.routeros/issues/193)\, [https\://github\.com/ansible\-collections/community\.routeros/pull/194](https\://github\.com/ansible\-collections/community\.routeros/pull/194)\)\. @@ -232,7 +257,7 @@ Bugfix and feature release\. <a id="v2-8-3"></a> ## v2\.8\.3 -<a id="release-summary-6"></a> +<a id="release-summary-7"></a> ### Release Summary Maintenance release with updated documentation\. @@ -253,7 +278,7 @@ for the rendered HTML version of the documentation of the latest release\. <a id="v2-8-2"></a> ## v2\.8\.2 -<a id="release-summary-7"></a> +<a id="release-summary-8"></a> ### Release Summary Bugfix release\. @@ -266,7 +291,7 @@ Bugfix release\. <a id="v2-8-1"></a> ## v2\.8\.1 -<a id="release-summary-8"></a> +<a id="release-summary-9"></a> ### Release Summary Bugfix release\. @@ -279,12 +304,12 @@ Bugfix release\. <a id="v2-8-0"></a> ## v2\.8\.0 -<a id="release-summary-9"></a> +<a id="release-summary-10"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-6"></a> +<a id="minor-changes-7"></a> ### Minor Changes * api\_modify \- adapt data for API paths <code>ip dhcp\-server network</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/156](https\://github\.com/ansible\-collections/community\.routeros/pull/156)\)\. @@ -304,12 +329,12 @@ Bugfix and feature release\. <a id="v2-7-0"></a> ## v2\.7\.0 -<a id="release-summary-10"></a> +<a id="release-summary-11"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-7"></a> +<a id="minor-changes-8"></a> ### Minor Changes * api\_modify\, api\_info \- support API paths <code>ip arp</code>\, <code>ip firewall raw</code>\, <code>ipv6 firewall raw</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/144](https\://github\.com/ansible\-collections/community\.routeros/pull/144)\)\. @@ -322,12 +347,12 @@ Bugfix and feature release\. <a id="v2-6-0"></a> ## v2\.6\.0 -<a id="release-summary-11"></a> +<a id="release-summary-12"></a> ### Release Summary Regular bugfix and feature release\. -<a id="minor-changes-8"></a> +<a id="minor-changes-9"></a> ### Minor Changes * api\_modify\, api\_info \- add field <code>regexp</code> to <code>ip dns static</code> \([https\://github\.com/ansible\-collections/community\.routeros/issues/141](https\://github\.com/ansible\-collections/community\.routeros/issues/141)\)\. @@ -342,12 +367,12 @@ Regular bugfix and feature release\. <a id="v2-5-0"></a> ## v2\.5\.0 -<a id="release-summary-12"></a> +<a id="release-summary-13"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-9"></a> +<a id="minor-changes-10"></a> ### Minor Changes * api\_info\, api\_modify \- support API paths <code>interface ethernet poe</code>\, <code>interface gre6</code>\, <code>interface vrrp</code> and also support all previously missing fields of entries in <code>ip dhcp\-server</code> \([https\://github\.com/ansible\-collections/community\.routeros/pull/137](https\://github\.com/ansible\-collections/community\.routeros/pull/137)\)\. @@ -360,12 +385,12 @@ Feature and bugfix release\. <a id="v2-4-0"></a> ## v2\.4\.0 -<a id="release-summary-13"></a> +<a id="release-summary-14"></a> ### Release Summary Feature release improving the <code>api\*</code> modules\. -<a id="minor-changes-10"></a> +<a id="minor-changes-11"></a> ### Minor Changes * api\* modules \- Add new option <code>force\_no\_cert</code> to connect with ADH ciphers \([https\://github\.com/ansible\-collections/community\.routeros/pull/124](https\://github\.com/ansible\-collections/community\.routeros/pull/124)\)\. @@ -404,7 +429,7 @@ Feature release improving the <code>api\*</code> modules\. <a id="v2-3-1"></a> ## v2\.3\.1 -<a id="release-summary-14"></a> +<a id="release-summary-15"></a> ### Release Summary Maintenance release with improved documentation\. @@ -417,12 +442,12 @@ Maintenance release with improved documentation\. <a id="v2-3-0"></a> ## v2\.3\.0 -<a id="release-summary-15"></a> +<a id="release-summary-16"></a> ### Release Summary Feature and bugfix release\. -<a id="minor-changes-11"></a> +<a id="minor-changes-12"></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\.routeros/pull/108](https\://github\.com/ansible\-collections/community\.routeros/pull/108)\)\. @@ -437,7 +462,7 @@ Feature and bugfix release\. <a id="v2-2-1"></a> ## v2\.2\.1 -<a id="release-summary-16"></a> +<a id="release-summary-17"></a> ### Release Summary Bugfix release\. @@ -451,12 +476,12 @@ Bugfix release\. <a id="v2-2-0"></a> ## v2\.2\.0 -<a id="release-summary-17"></a> +<a id="release-summary-18"></a> ### Release Summary New feature release\. -<a id="minor-changes-12"></a> +<a id="minor-changes-13"></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\.routeros/pull/101](https\://github\.com/ansible\-collections/community\.routeros/pull/101)\)\. @@ -475,12 +500,12 @@ New feature release\. <a id="v2-1-0"></a> ## v2\.1\.0 -<a id="release-summary-18"></a> +<a id="release-summary-19"></a> ### Release Summary Feature and bugfix release with new modules\. -<a id="minor-changes-13"></a> +<a id="minor-changes-14"></a> ### Minor Changes * Added a <code>community\.routeros\.api</code> module defaults group\. Use with <code>group/community\.routeros\.api</code> to provide options for all API\-based modules \([https\://github\.com/ansible\-collections/community\.routeros/pull/89](https\://github\.com/ansible\-collections/community\.routeros/pull/89)\)\. @@ -504,12 +529,12 @@ Feature and bugfix release with new modules\. <a id="v2-0-0"></a> ## v2\.0\.0 -<a id="release-summary-19"></a> +<a id="release-summary-20"></a> ### Release Summary A new major release with breaking changes in the behavior of <code>community\.routeros\.api</code> and <code>community\.routeros\.command</code>\. -<a id="minor-changes-14"></a> +<a id="minor-changes-15"></a> ### Minor Changes * api \- make validation of <code>WHERE</code> for <code>query</code> more strict \([https\://github\.com/ansible\-collections/community\.routeros/pull/53](https\://github\.com/ansible\-collections/community\.routeros/pull/53)\)\. @@ -545,12 +570,12 @@ A new major release with breaking changes in the behavior of <code>community\.ro <a id="v1-2-0"></a> ## v1\.2\.0 -<a id="release-summary-20"></a> +<a id="release-summary-21"></a> ### Release Summary Bugfix and feature release\. -<a id="minor-changes-15"></a> +<a id="minor-changes-16"></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\.routeros/pull/38](https\://github\.com/ansible\-collections/community\.routeros/pull/38)\)\. @@ -566,12 +591,12 @@ Bugfix and feature release\. <a id="v1-1-0"></a> ## v1\.1\.0 -<a id="release-summary-21"></a> +<a id="release-summary-22"></a> ### Release Summary This release allow dashes in usernames for SSH\-based modules\. -<a id="minor-changes-16"></a> +<a id="minor-changes-17"></a> ### Minor Changes * command \- added support for a dash \(<code>\-</code>\) in username \([https\://github\.com/ansible\-collections/community\.routeros/pull/18](https\://github\.com/ansible\-collections/community\.routeros/pull/18)\)\. @@ -580,7 +605,7 @@ This release allow dashes in usernames for SSH\-based modules\. <a id="v1-0-1"></a> ## v1\.0\.1 -<a id="release-summary-22"></a> +<a id="release-summary-23"></a> ### Release Summary Maintenance release with a bugfix for <code>api</code>\. @@ -593,7 +618,7 @@ Maintenance release with a bugfix for <code>api</code>\. <a id="v1-0-0"></a> ## v1\.0\.0 -<a id="release-summary-23"></a> +<a id="release-summary-24"></a> ### Release Summary This is the first production \(non\-prerelease\) release of <code>community\.routeros</code>\. @@ -606,7 +631,7 @@ This is the first production \(non\-prerelease\) release of <code>community\.rou <a id="v0-1-1"></a> ## v0\.1\.1 -<a id="release-summary-24"></a> +<a id="release-summary-25"></a> ### Release Summary Small improvements and bugfixes over the initial release\. @@ -619,12 +644,12 @@ Small improvements and bugfixes over the initial release\. <a id="v0-1-0"></a> ## v0\.1\.0 -<a id="release-summary-25"></a> +<a id="release-summary-26"></a> ### Release Summary The <code>community\.routeros</code> continues the work on the Ansible RouterOS modules from their state in <code>community\.network</code> 1\.2\.0\. The changes listed here are thus relative to the modules <code>community\.network\.routeros\_\*</code>\. -<a id="minor-changes-17"></a> +<a id="minor-changes-18"></a> ### Minor Changes * facts \- now also collecting data about BGP and OSPF \([https\://github\.com/ansible\-collections/community\.network/pull/101](https\://github\.com/ansible\-collections/community\.network/pull/101)\)\. diff --git a/ansible_collections/community/routeros/CHANGELOG.rst b/ansible_collections/community/routeros/CHANGELOG.rst index c7cc6ef67..1b3a76077 100644 --- a/ansible_collections/community/routeros/CHANGELOG.rst +++ b/ansible_collections/community/routeros/CHANGELOG.rst @@ -4,6 +4,28 @@ Community RouterOS Release Notes .. contents:: Topics +v2.15.0 +======= + +Release Summary +--------------- + +Feature release. + +Minor Changes +------------- + +- api_info, api_modify - Add RouterOS 7.x support to ``/mpls ldp`` path (https://github.com/ansible-collections/community.routeros/pull/271). +- api_info, api_modify - add ``/ip route rule`` path for RouterOS 6.x (https://github.com/ansible-collections/community.routeros/pull/278). +- api_info, api_modify - add ``/routing filter`` path for RouterOS 6.x (https://github.com/ansible-collections/community.routeros/pull/279). +- api_info, api_modify - add default value for ``from-pool`` field in ``/ipv6 address`` (https://github.com/ansible-collections/community.routeros/pull/270). +- api_info, api_modify - add missing path ``/interface pppoe-server server`` (https://github.com/ansible-collections/community.routeros/pull/273). +- api_info, api_modify - add missing path ``/ip dhcp-relay`` (https://github.com/ansible-collections/community.routeros/pull/276). +- api_info, api_modify - add missing path ``/queue simple`` (https://github.com/ansible-collections/community.routeros/pull/269). +- api_info, api_modify - add missing path ``/queue type`` (https://github.com/ansible-collections/community.routeros/pull/274). +- api_info, api_modify - add missing paths ``/routing bgp aggregate``, ``/routing bgp network`` and ``/routing bgp peer`` (https://github.com/ansible-collections/community.routeros/pull/277). +- api_info, api_modify - add support for paths ``/mpls interface``, ``/mpls ldp accept-filter``, ``/mpls ldp advertise-filter`` and ``mpls ldp interface`` (https://github.com/ansible-collections/community.routeros/pull/272). + v2.14.0 ======= diff --git a/ansible_collections/community/routeros/FILES.json b/ansible_collections/community/routeros/FILES.json index 65dc9b337..483d87e4f 100644 --- a/ansible_collections/community/routeros/FILES.json +++ b/ansible_collections/community/routeros/FILES.json @@ -25,7 +25,7 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7733552e950b67d67c9b00ef9bb1d15c38ee2d765d47ab2d7404cc5efa6fa0b7", + "chksum_sha256": "bf90bb7d4687afa28b6d64eed2a4ef8761badbd5759319daff0621394fe8a1fe", "format": 1 }, { @@ -151,7 +151,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b9c3d4e8049fa8e3b5e55c2997f4df70ac1942517cfbddb28d7caafef030ba12", + "chksum_sha256": "5780b9cd9fd37dcad0b122ae762afbe426e800c7fda9496e50163c628d77a823", "format": 1 }, { @@ -211,6 +211,13 @@ "format": 1 }, { + "name": "docs/docsite/config.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0c5ec9ff76cf4db33b5d3f771419ef50d448e5d510cb7a98fc07dd9ecee69c4e", + "format": 1 + }, + { "name": "docs/docsite/extra-docs.yml", "ftype": "file", "chksum_type": "sha256", @@ -354,7 +361,7 @@ "name": "plugins/module_utils/_api_data.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b5880a7e63053e5f40b3824e0e8311dc2f61d93bcadc0d639d65dcc3ba88a723", + "chksum_sha256": "2b2dd685aa6a3fd4d481f12ced0ed0284a65d4773844c4c9a30ea3b4cbd38297", "format": 1 }, { @@ -424,14 +431,14 @@ "name": "plugins/modules/api_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ed9d94602cc1c6c87fa65e829342c83724376cc8b0d47072e74a6119e10e0505", + "chksum_sha256": "f86b949f2a5f6da6df2061711adf35ff727c034c7c9b7dc4e3bbb50fe80f0dd8", "format": 1 }, { "name": "plugins/modules/api_modify.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "81752a1a70ce47134663c2d721673481a8aea6995469092ae24b13303772820c", + "chksum_sha256": "2ec95cb3af816b5ee9b3e54ead9258c177f559038d57de7f253f4d9b6f179784", "format": 1 }, { @@ -806,6 +813,20 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1af4ae071777877caae7e48c7a1a1c905d990e0d4d832b285970307cc5ad03df", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.18.txt.license", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6eb915239f9f35407fa68fdc41ed6522f1fdcce11badbdcd6057548023179ac1", + "format": 1 + }, + { "name": "tests/sanity/ignore-2.9.txt", "ftype": "file", "chksum_type": "sha256", @@ -1257,7 +1278,7 @@ "name": "CHANGELOG.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b99dd5a4c3af9a341ee8435a0bd595a093508da336b35963c9f4c21e40442a90", + "chksum_sha256": "3add5cc457f4a9b36baea353affd9965843342f141333acdce5af15d84d7ae2b", "format": 1 }, { @@ -1271,7 +1292,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6f13293d73ce0d0f4ac5a07b1b7e69d3efbfd36dca003148072b792bb5678ffe", + "chksum_sha256": "ed20bebf70ccd5e1e94da8f399771dddf40744a2c2da0283fe210fc6c47d77ca", "format": 1 }, { @@ -1292,7 +1313,7 @@ "name": "README.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be40d1889fd07a702d1422a4da11a614fc9cce965f548eae37f50dfa8cf0ba46", + "chksum_sha256": "f5ae35bdf559206e7f48123c0928ef6b5d9bc29f8a6b6eef90aa731e81aaa516", "format": 1 }, { diff --git a/ansible_collections/community/routeros/MANIFEST.json b/ansible_collections/community/routeros/MANIFEST.json index 02c5b44f9..ddec534d7 100644 --- a/ansible_collections/community/routeros/MANIFEST.json +++ b/ansible_collections/community/routeros/MANIFEST.json @@ -2,7 +2,7 @@ "collection_info": { "namespace": "community", "name": "routeros", - "version": "2.14.0", + "version": "2.15.0", "authors": [ "Egor Zaitsev (github.com/heuels)", "Nikolay Dachev (github.com/NikolayDachev)", @@ -31,7 +31,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b61bc5f91d12dd9344c686a1ce2650fea27acfe4e6dceb5ac36d8fc236ecadc0", + "chksum_sha256": "a36cd24eef5f055d20b8836410e23e222aa2aa857c025faadc9e10767b95fec6", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/routeros/README.md b/ansible_collections/community/routeros/README.md index df692d6d5..e617a8f89 100644 --- a/ansible_collections/community/routeros/README.md +++ b/ansible_collections/community/routeros/README.md @@ -13,7 +13,7 @@ You can find [documentation for the modules and plugins in this collection here] ## 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, and ansible-core 2.16 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. +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. ## External requirements diff --git a/ansible_collections/community/routeros/changelogs/changelog.yaml b/ansible_collections/community/routeros/changelogs/changelog.yaml index e23348b3a..62320dd0e 100644 --- a/ansible_collections/community/routeros/changelogs/changelog.yaml +++ b/ansible_collections/community/routeros/changelogs/changelog.yaml @@ -339,6 +339,38 @@ releases: - 264-wireless-running-default.yml - 266-interface-wifi.yml release_date: '2024-03-25' + 2.15.0: + changes: + minor_changes: + - api_info, api_modify - Add RouterOS 7.x support to ``/mpls ldp`` path (https://github.com/ansible-collections/community.routeros/pull/271). + - api_info, api_modify - add ``/ip route rule`` path for RouterOS 6.x (https://github.com/ansible-collections/community.routeros/pull/278). + - api_info, api_modify - add ``/routing filter`` path for RouterOS 6.x (https://github.com/ansible-collections/community.routeros/pull/279). + - api_info, api_modify - add default value for ``from-pool`` field in ``/ipv6 + address`` (https://github.com/ansible-collections/community.routeros/pull/270). + - api_info, api_modify - add missing path ``/interface pppoe-server server`` + (https://github.com/ansible-collections/community.routeros/pull/273). + - api_info, api_modify - add missing path ``/ip dhcp-relay`` (https://github.com/ansible-collections/community.routeros/pull/276). + - api_info, api_modify - add missing path ``/queue simple`` (https://github.com/ansible-collections/community.routeros/pull/269). + - api_info, api_modify - add missing path ``/queue type`` (https://github.com/ansible-collections/community.routeros/pull/274). + - api_info, api_modify - add missing paths ``/routing bgp aggregate``, ``/routing + bgp network`` and ``/routing bgp peer`` (https://github.com/ansible-collections/community.routeros/pull/277). + - api_info, api_modify - add support for paths ``/mpls interface``, ``/mpls + ldp accept-filter``, ``/mpls ldp advertise-filter`` and ``mpls ldp interface`` + (https://github.com/ansible-collections/community.routeros/pull/272). + release_summary: Feature release. + fragments: + - 2.15.0.yml + - 269-add-queue_simple-path.yml + - 270_fix_ipv6_from_pool_default_value.yml + - 271-mpls_ldp_routeros_7_support.yml + - 272-additional_mpls_path_support.yml + - 273-add_interface_pppoe-server_support.yml + - 274-add_queue_type_path.yml + - 276-add_ip_dhcp-relay_path.yml + - 277-add_routing_bgp_paths.yml + - 278-add_ip_route_rule_path.yml + - 279-add_routing_filter_path.yml + release_date: '2024-04-20' 2.2.0: changes: bugfixes: diff --git a/ansible_collections/community/routeros/docs/docsite/config.yml b/ansible_collections/community/routeros/docs/docsite/config.yml new file mode 100644 index 000000000..1d6cf8554 --- /dev/null +++ b/ansible_collections/community/routeros/docs/docsite/config.yml @@ -0,0 +1,7 @@ +--- +# 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 + +changelog: + write_changelog: true diff --git a/ansible_collections/community/routeros/plugins/module_utils/_api_data.py b/ansible_collections/community/routeros/plugins/module_utils/_api_data.py index a421cffee..fdf5cba58 100644 --- a/ansible_collections/community/routeros/plugins/module_utils/_api_data.py +++ b/ansible_collections/community/routeros/plugins/module_utils/_api_data.py @@ -729,6 +729,23 @@ PATHS = { }, ), ), + ('ip', 'route', 'rule'): APIData( + versioned=[ + ('7', '<', VersionedAPIData( + fully_understood=True, + fields={ + 'action': KeyInfo(default='lookup'), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'disabled': KeyInfo(default=False), + 'dst-address': KeyInfo(can_disable=True), + 'interface': KeyInfo(can_disable=True), + 'routing-mark': KeyInfo(can_disable=True), + 'src-address': KeyInfo(can_disable=True), + 'table': KeyInfo(default='main'), + }, + )), + ], + ), ('ip', 'vrf'): APIData( versioned=[ ('7', '>=', VersionedAPIData( @@ -787,6 +804,73 @@ PATHS = { }, ), ), + ('routing', 'filter'): APIData( + versioned=[ + ('7', '<', VersionedAPIData( + fully_understood=True, + fields={ + 'action': KeyInfo(default='passthrough'), + 'address-family': KeyInfo(can_disable=True), + 'append-bgp-communities': KeyInfo(can_disable=True), + 'append-route-targets': KeyInfo(can_disable=True), + 'bgp-as-path': KeyInfo(can_disable=True), + 'bgp-as-path-length': KeyInfo(can_disable=True), + 'bgp-atomic-aggregate': KeyInfo(can_disable=True), + 'bgp-communities': KeyInfo(can_disable=True), + 'bgp-local-pref': KeyInfo(can_disable=True), + 'bgp-med': KeyInfo(can_disable=True), + 'bgp-origin': KeyInfo(can_disable=True), + 'bgp-weight': KeyInfo(can_disable=True), + 'chain': KeyInfo(required=True), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'disabled': KeyInfo(default=False), + 'distance': KeyInfo(can_disable=True), + 'invert-match': KeyInfo(default=False), + 'jump-target': KeyInfo(), + 'locally-originated-bgp': KeyInfo(can_disable=True), + 'match-chain': KeyInfo(can_disable=True), + 'ospf-type': KeyInfo(can_disable=True), + 'pref-src': KeyInfo(can_disable=True), + 'prefix': KeyInfo(default='0.0.0.0/0'), + 'prefix-length': KeyInfo(can_disable=True), + 'protocol': KeyInfo(can_disable=True), + 'route-comment': KeyInfo(can_disable=True), + 'route-tag': KeyInfo(can_disable=True), + 'route-targets': KeyInfo(can_disable=True), + 'routing-mark': KeyInfo(can_disable=True), + 'scope': KeyInfo(can_disable=True), + 'set-bgp-communities': KeyInfo(can_disable=True), + 'set-bgp-local-pref': KeyInfo(can_disable=True), + 'set-bgp-med': KeyInfo(can_disable=True), + 'set-bgp-prepend': KeyInfo(can_disable=True), + 'set-bgp-prepend-path': KeyInfo(), + 'set-bgp-weight': KeyInfo(can_disable=True), + 'set-check-gateway': KeyInfo(can_disable=True), + 'set-disabled': KeyInfo(can_disable=True), + 'set-distance': KeyInfo(can_disable=True), + 'set-in-nexthop': KeyInfo(can_disable=True), + 'set-in-nexthop-direct': KeyInfo(can_disable=True), + 'set-in-nexthop-ipv6': KeyInfo(can_disable=True), + 'set-in-nexthop-linklocal': KeyInfo(can_disable=True), + 'set-out-nexthop': KeyInfo(can_disable=True), + 'set-out-nexthop-ipv6': KeyInfo(can_disable=True), + 'set-out-nexthop-linklocal': KeyInfo(can_disable=True), + 'set-pref-src': KeyInfo(can_disable=True), + 'set-route-comment': KeyInfo(can_disable=True), + 'set-route-tag': KeyInfo(can_disable=True), + 'set-route-targets': KeyInfo(can_disable=True), + 'set-routing-mark': KeyInfo(can_disable=True), + 'set-scope': KeyInfo(can_disable=True), + 'set-site-of-origin': KeyInfo(can_disable=True), + 'set-target-scope': KeyInfo(can_disable=True), + 'set-type': KeyInfo(can_disable=True), + 'set-use-te-nexthop': KeyInfo(can_disable=True), + 'site-of-origin': KeyInfo(can_disable=True), + 'target-scope': KeyInfo(can_disable=True), + }, + )), + ], + ), ('routing', 'filter', 'rule'): APIData( versioned=[ ('7', '>=', VersionedAPIData( @@ -1397,7 +1481,7 @@ PATHS = { 'comment': KeyInfo(can_disable=True, remove_value=''), 'disabled': KeyInfo(default=False), 'eui-64': KeyInfo(default=False), - 'from-pool': KeyInfo(), + 'from-pool': KeyInfo(default=''), 'interface': KeyInfo(required=True), 'no-dad': KeyInfo(default=False), }, @@ -1497,6 +1581,28 @@ PATHS = { }, ), ), + ('interface', 'pppoe-server', 'server'): APIData( + unversioned=VersionedAPIData( + fully_understood=True, + primary_keys=('interface', ), + fields={ + 'accept-empty-service': KeyInfo(default=True), + 'authentication': KeyInfo(default='pap,chap,mschap1,mschap2'), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'default-profile': KeyInfo(default='default'), + 'disabled': KeyInfo(default=True), + 'interface': KeyInfo(required=True), + 'keepalive-timeout': KeyInfo(default=10), + 'max-mru': KeyInfo(default='auto'), + 'max-mtu': KeyInfo(default='auto'), + 'max-sessions': KeyInfo(default='unlimited'), + 'mrru': KeyInfo(default='disabled'), + 'one-session-per-host': KeyInfo(default=False), + 'pado-delay': KeyInfo(default=0), + 'service-name': KeyInfo(default=''), + }, + ), + ), ('interface', 'pptp-server', 'server'): APIData( unversioned=VersionedAPIData( single_value=True, @@ -2557,6 +2663,22 @@ PATHS = { }, ), ), + ('ip', 'dhcp-relay'): APIData( + unversioned=VersionedAPIData( + fully_understood=True, + primary_keys=('name',), + fields={ + 'add-relay-info': KeyInfo(default=False), + 'delay-threshold': KeyInfo(can_disable=True, remove_value='none'), + 'dhcp-server': KeyInfo(required=True), + 'disabled': KeyInfo(default=False), + 'interface': KeyInfo(required=True), + 'local-address': KeyInfo(can_disable=True, remove_value='0.0.0.0'), + 'name': KeyInfo(), + 'relay-info-remote-id': KeyInfo(), + }, + ), + ), ('ip', 'dhcp-server', 'config'): APIData( unversioned=VersionedAPIData( single_value=True, @@ -3591,29 +3713,90 @@ PATHS = { ), ('mpls', 'interface'): APIData( unversioned=VersionedAPIData( - unknown_mechanism=True, - # primary_keys=('default', ), + fully_understood=True, fields={ - 'default': KeyInfo(), - 'disabled': KeyInfo(), - 'interface': KeyInfo(), + 'disabled': KeyInfo(default=False), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'interface': KeyInfo(required=True), 'mpls-mtu': KeyInfo(), + 'info': KeyInfo(can_disable=True), }, ), ), ('mpls', 'ldp'): APIData( + versioned=[ + ('7.1', '>=', VersionedAPIData( + fully_understood=True, + primary_keys=('vrf', ), + fields={ + 'afi': KeyInfo(can_disable=True), + 'distribute-for-default': KeyInfo(can_disable=True), + 'path-vector-limit': KeyInfo(can_disable=True), + 'vrf': KeyInfo(), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'hop-limit': KeyInfo(can_disable=True), + 'preferred-afi': KeyInfo(can_disable=True), + 'loop-detect': KeyInfo(can_disable=True), + 'transport-addresses': KeyInfo(can_disable=True), + 'disabled': KeyInfo(default=False), + 'lsr-id': KeyInfo(can_disable=True), + 'use-explicit-null': KeyInfo(can_disable=True), + }, + )), + ('7.1', '<', VersionedAPIData( + single_value=True, + fully_understood=True, + fields={ + 'distribute-for-default-route': KeyInfo(default=False), + 'enabled': KeyInfo(default=False), + 'hop-limit': KeyInfo(default=255), + 'loop-detect': KeyInfo(default=False), + 'lsr-id': KeyInfo(default='0.0.0.0'), + 'path-vector-limit': KeyInfo(default=255), + 'transport-address': KeyInfo(default='0.0.0.0'), + 'use-explicit-null': KeyInfo(default=False), + }, + )), + ], + ), + ('mpls', 'ldp', 'accept-filter'): APIData( unversioned=VersionedAPIData( - single_value=True, fully_understood=True, fields={ - 'distribute-for-default-route': KeyInfo(default=False), - 'enabled': KeyInfo(default=False), - 'hop-limit': KeyInfo(default=255), - 'loop-detect': KeyInfo(default=False), - 'lsr-id': KeyInfo(default='0.0.0.0'), - 'path-vector-limit': KeyInfo(default=255), - 'transport-address': KeyInfo(default='0.0.0.0'), - 'use-explicit-null': KeyInfo(default=False), + 'accept': KeyInfo(can_disable=True), + 'disabled': KeyInfo(default=False), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'neighbor': KeyInfo(can_disable=True), + 'prefix': KeyInfo(can_disable=True), + 'vrf': KeyInfo(can_disable=True), + }, + ), + ), + ('mpls', 'ldp', 'advertise-filter'): APIData( + unversioned=VersionedAPIData( + fully_understood=True, + fields={ + 'advertise': KeyInfo(default=''), + 'disabled': KeyInfo(default=False), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'neighbor': KeyInfo(), + 'prefix': KeyInfo(), + 'vrf': KeyInfo(), + }, + ), + ), + ('mpls', 'ldp', 'interface'): APIData( + unversioned=VersionedAPIData( + fully_understood=True, + fields={ + 'disabled': KeyInfo(default=False), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'accept-dynamic-neighbors': KeyInfo(can_disable=True), + 'afi': KeyInfo(can_disable=True), + 'hello-interval': KeyInfo(can_disable=True), + 'hold-time': KeyInfo(can_disable=True), + 'interface': KeyInfo(required=True), + 'transport-addresses': KeyInfo(can_disable=True), }, ), ), @@ -4239,6 +4422,30 @@ PATHS = { }, ), ), + ('queue', 'simple'): APIData( + unversioned=VersionedAPIData( + primary_keys=('name', ), + fully_understood=True, + fields={ + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'dst': KeyInfo(can_disable=True, remove_value=''), + 'time': KeyInfo(can_disable=True, remove_value=''), + 'bucket-size': KeyInfo(default='0.1/0.1'), + 'burst-limit': KeyInfo(default='0/0'), + 'burst-threshold': KeyInfo(default='0/0'), + 'burst-time': KeyInfo(default='0s/0s'), + 'disabled': KeyInfo(default=False), + 'limit-at': KeyInfo(default='0/0'), + 'max-limit': KeyInfo(default='0/0'), + 'name': KeyInfo(), + 'packet-marks': KeyInfo(default=''), + 'parent': KeyInfo(default='none'), + 'priority': KeyInfo(default='8/8'), + 'queue': KeyInfo(default='default-small/default-small'), + 'target': KeyInfo(required=True), + }, + ), + ), ('queue', 'tree'): APIData( unversioned=VersionedAPIData( primary_keys=('name', ), @@ -4260,6 +4467,64 @@ PATHS = { }, ), ), + ('queue', 'type'): APIData( + unversioned=VersionedAPIData( + primary_keys=('name', ), + fully_understood=True, + fields={ + 'name': KeyInfo(), + 'kind': KeyInfo(required=True), + 'bfifo-limit': KeyInfo(default=15000), + 'cake-ack-filter': KeyInfo(default='none'), + 'cake-atm': KeyInfo(default='none'), + 'cake-autorate-ingress': KeyInfo(can_disable=True), + 'cake-bandwidth': KeyInfo(can_disable=True, remove_value=0), + 'cake-diffserv': KeyInfo(default='diffserv3'), + 'cake-flowmode': KeyInfo(default='triple-isolate'), + 'cake-memlimit': KeyInfo(default=0), + 'cake-mpu': KeyInfo(can_disable=True, remove_value=''), + 'cake-nat': KeyInfo(can_disable=True, remove_value=False), + 'cake-overhead': KeyInfo(default=0), + 'cake-overhead-scheme': KeyInfo(can_disable=True, remove_value=''), + 'cake-rtt': KeyInfo(default='100ms'), + 'cake-rtt-scheme': KeyInfo(default='none'), + 'cake-wash': KeyInfo(can_disable=True, remove_value=False), + 'codel-ce-threshold': KeyInfo(can_disable=True, remove_value=''), + 'codel-ecn': KeyInfo(can_disable=True, remove_value=False), + 'codel-interval': KeyInfo(default='100ms'), + 'codel-limit': KeyInfo(default=1000), + 'codel-target': KeyInfo(default='5ms'), + 'fq-codel-ce-threshold': KeyInfo(can_disable=True, remove_value=''), + 'fq-codel-ecn': KeyInfo(default=True), + 'fq-codel-flows': KeyInfo(default=1024), + 'fq-codel-interval': KeyInfo(default='100ms'), + 'fq-codel-limit': KeyInfo(default=10240), + 'fq-codel-memlimit': KeyInfo(default=33554432), + 'fq-codel-quantum': KeyInfo(default=1514), + 'fq-codel-target': KeyInfo(default='5ms'), + 'mq-pfifo-limit': KeyInfo(default=50), + 'pcq-burst-rate': KeyInfo(default=0), + 'pcq-burst-threshold': KeyInfo(default=0), + 'pcq-burst-time': KeyInfo(default='10s'), + 'pcq-classifier': KeyInfo(can_disable=True, remove_value=''), + 'pcq-dst-address-mask': KeyInfo(default=32), + 'pcq-dst-address6-mask': KeyInfo(default=128), + 'pcq-limit': KeyInfo(default=50), + 'pcq-rate': KeyInfo(default=0), + 'pcq-src-address-mask': KeyInfo(default=32), + 'pcq-src-address6-mask': KeyInfo(default=128), + 'pcq-total-limit': KeyInfo(default=2000), + 'pfifo-limit': KeyInfo(default=50), + 'red-avg-packet': KeyInfo(default=1000), + 'red-burst': KeyInfo(default=20), + 'red-limit': KeyInfo(default=60), + 'red-max-threshold': KeyInfo(default=50), + 'red-min-threshold': KeyInfo(default=10), + 'sfq-allot': KeyInfo(default=1514), + 'sfq-perturb': KeyInfo(default=5), + }, + ), + ), ('interface', 'ethernet', 'switch'): APIData( unversioned=VersionedAPIData( fixed_entries=True, @@ -4335,32 +4600,20 @@ PATHS = { }, ), ), - ('queue', 'type'): APIData( + ('routing', 'bgp', 'aggregate'): APIData( unversioned=VersionedAPIData( - has_identifier=True, + primary_keys=('prefix',), + fully_understood=True, fields={ - 'kind': KeyInfo(), - 'mq-pfifo-limit': KeyInfo(), - 'name': KeyInfo(), - 'pcq-burst-rate': KeyInfo(), - 'pcq-burst-threshold': KeyInfo(), - 'pcq-burst-time': KeyInfo(), - 'pcq-classifier': KeyInfo(), - 'pcq-dst-address-mask': KeyInfo(), - 'pcq-dst-address6-mask': KeyInfo(), - 'pcq-limit': KeyInfo(), - 'pcq-rate': KeyInfo(), - 'pcq-src-address-mask': KeyInfo(), - 'pcq-src-address6-mask': KeyInfo(), - 'pcq-total-limit': KeyInfo(), - 'pfifo-limit': KeyInfo(), - 'red-avg-packet': KeyInfo(), - 'red-burst': KeyInfo(), - 'red-limit': KeyInfo(), - 'red-max-threshold': KeyInfo(), - 'red-min-threshold': KeyInfo(), - 'sfq-allot': KeyInfo(), - 'sfq-perturb': KeyInfo(), + 'advertise-filter': KeyInfo(), + 'attribute-filter': KeyInfo(), + 'disabled': KeyInfo(default=False), + 'include-igp': KeyInfo(default=False), + 'inherit-attributes': KeyInfo(default=True), + 'instance': KeyInfo(required=True), + 'prefix': KeyInfo(required=True), + 'summary-only': KeyInfo(default=True), + 'suppress-filter': KeyInfo(), }, ), ), @@ -4448,6 +4701,53 @@ PATHS = { }, ), ), + ('routing', 'bgp', 'network'): APIData( + unversioned=VersionedAPIData( + primary_keys=('network',), + fully_understood=True, + fields={ + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'disabled': KeyInfo(default=False), + 'network': KeyInfo(required=True), + 'synchronize': KeyInfo(default=True), + }, + ), + ), + ('routing', 'bgp', 'peer'): APIData( + unversioned=VersionedAPIData( + primary_keys=('name', ), + fully_understood=True, + fields={ + 'address-families': KeyInfo(default='ip'), + 'allow-as-in': KeyInfo(can_disable=True, remove_value=''), + 'as-override': KeyInfo(default=False), + 'cisco-vpls-nlri-len-fmt': KeyInfo(), + 'comment': KeyInfo(can_disable=True, remove_value=''), + 'default-originate': KeyInfo(default='never'), + 'disabled': KeyInfo(default=False), + 'hold-time': KeyInfo(default='3m'), + 'in-filter': KeyInfo(), + 'instance': KeyInfo(), + 'keepalive-time': KeyInfo(can_disable=True, remove_value=''), + 'max-prefix-limit': KeyInfo(can_disable=True, remove_value=''), + 'max-prefix-restart-time': KeyInfo(can_disable=True, remove_value=''), + 'multihop': KeyInfo(default=False), + 'name': KeyInfo(), + 'nexthop-choice': KeyInfo(default='default'), + 'passive': KeyInfo(default=False), + 'out-filter': KeyInfo(), + 'remote-address': KeyInfo(required=True), + 'remote-as': KeyInfo(required=True), + 'remote-port': KeyInfo(can_disable=True, remove_value=''), + 'remove-private-as': KeyInfo(default=False), + 'route-reflect': KeyInfo(default=False), + 'tcp-md5-key': KeyInfo(), + 'ttl': KeyInfo(default='default'), + 'update-source': KeyInfo(can_disable=True, remove_value='none'), + 'use-bfd': KeyInfo(default=False), + }, + ), + ), ('routing', 'bgp', 'template'): APIData( unversioned=VersionedAPIData( primary_keys=('name', ), diff --git a/ansible_collections/community/routeros/plugins/modules/api_info.py b/ansible_collections/community/routeros/plugins/modules/api_info.py index f9a39464f..a3e800ee3 100644 --- a/ansible_collections/community/routeros/plugins/modules/api_info.py +++ b/ansible_collections/community/routeros/plugins/modules/api_info.py @@ -75,6 +75,7 @@ options: - interface ovpn-server server - interface ppp-client - interface pppoe-client + - interface pppoe-server server - interface pptp-server server - interface sstp-server server - interface vlan @@ -120,6 +121,7 @@ options: - ip cloud advanced - ip dhcp-client - ip dhcp-client option + - ip dhcp-relay - ip dhcp-server - ip dhcp-server config - ip dhcp-server lease @@ -147,6 +149,7 @@ options: - ip pool - ip proxy - ip route + - ip route rule - ip route vrf - ip service - ip settings @@ -174,18 +177,28 @@ options: - ipv6 route - ipv6 settings - mpls + - mpls interface - mpls ldp + - mpls ldp accept-filter + - mpls ldp advertise-filter + - mpls ldp interface - port firmware - port remote-access - ppp aaa - ppp profile - queue interface + - queue simple - queue tree + - queue type - radius - radius incoming + - routing bgp aggregate - routing bgp connection - routing bgp instance + - routing bgp network + - routing bgp peer - routing bgp template + - routing filter - routing filter rule - routing filter select-rule - routing id diff --git a/ansible_collections/community/routeros/plugins/modules/api_modify.py b/ansible_collections/community/routeros/plugins/modules/api_modify.py index d71750073..cd5b3a93d 100644 --- a/ansible_collections/community/routeros/plugins/modules/api_modify.py +++ b/ansible_collections/community/routeros/plugins/modules/api_modify.py @@ -84,6 +84,7 @@ options: - interface ovpn-server server - interface ppp-client - interface pppoe-client + - interface pppoe-server server - interface pptp-server server - interface sstp-server server - interface vlan @@ -129,6 +130,7 @@ options: - ip cloud advanced - ip dhcp-client - ip dhcp-client option + - ip dhcp-relay - ip dhcp-server - ip dhcp-server config - ip dhcp-server lease @@ -156,6 +158,7 @@ options: - ip pool - ip proxy - ip route + - ip route rule - ip route vrf - ip service - ip settings @@ -183,18 +186,28 @@ options: - ipv6 route - ipv6 settings - mpls + - mpls interface - mpls ldp + - mpls ldp accept-filter + - mpls ldp advertise-filter + - mpls ldp interface - port firmware - port remote-access - ppp aaa - ppp profile - queue interface + - queue simple - queue tree + - queue type - radius - radius incoming + - routing bgp aggregate - routing bgp connection - routing bgp instance + - routing bgp network + - routing bgp peer - routing bgp template + - routing filter - routing filter rule - routing filter select-rule - routing id diff --git a/ansible_collections/community/routeros/tests/sanity/ignore-2.18.txt b/ansible_collections/community/routeros/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..0a5234bdb --- /dev/null +++ b/ansible_collections/community/routeros/tests/sanity/ignore-2.18.txt @@ -0,0 +1,2 @@ +update-docs.py shebang +tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2 diff --git a/ansible_collections/community/routeros/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/routeros/tests/sanity/ignore-2.18.txt.license new file mode 100644 index 000000000..edff8c768 --- /dev/null +++ b/ansible_collections/community/routeros/tests/sanity/ignore-2.18.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/vmware/.github/workflows/ansible-test.yml b/ansible_collections/community/vmware/.github/workflows/ansible-test.yml index 1cbb1a26f..6a5866e13 100644 --- a/ansible_collections/community/vmware/.github/workflows/ansible-test.yml +++ b/ansible_collections/community/vmware/.github/workflows/ansible-test.yml @@ -19,8 +19,8 @@ on: push: branches: - main - - stable-2.x - stable-3.x + - stable-4.x pull_request: # Run CI once per day (at 07:12 UTC) # This ensures that even if there haven't been commits that we are still @@ -66,6 +66,7 @@ jobs: # - stable-2.14 - stable-2.15 - stable-2.16 + - stable-2.17 # - devel - milestone # Ansible-test on various stable branches does not yet work well with cgroups v2. @@ -131,6 +132,7 @@ jobs: # - stable-2.14 - stable-2.15 - stable-2.16 + - stable-2.17 # - devel - milestone diff --git a/ansible_collections/community/vmware/.github/workflows/extra-docs-linting.yml b/ansible_collections/community/vmware/.github/workflows/extra-docs-linting.yml index b36247113..91e3524fa 100644 --- a/ansible_collections/community/vmware/.github/workflows/extra-docs-linting.yml +++ b/ansible_collections/community/vmware/.github/workflows/extra-docs-linting.yml @@ -4,8 +4,8 @@ on: push: branches: - main - - stable-2.x - stable-3.x + - stable-4.x pull_request: # Run CI once per day (at 07:12 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 @@ -21,10 +21,10 @@ jobs: steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: python-version: '3.10' diff --git a/ansible_collections/community/vmware/CHANGELOG.rst b/ansible_collections/community/vmware/CHANGELOG.rst index 2c9e8318a..4162c1885 100644 --- a/ansible_collections/community/vmware/CHANGELOG.rst +++ b/ansible_collections/community/vmware/CHANGELOG.rst @@ -6,6 +6,29 @@ community.vmware Release Notes This changelog describes changes after version 3.9.0. +v4.3.0 +====== + +Minor Changes +------------- + +- Document that all parameters and VMware object names are case sensitive (https://github.com/ansible-collections/community.vmware/issues/2019). +- Drop the outdated (and actually unmaintained) scenario guides (https://github.com/ansible-collections/community.vmware/pull/2022). +- vmware_dvswitch - Add switchIpAddress/switch_ip parameter for netflow config +- vmware_guest_tools_info - Use `toolsVersionStatus2` instead of `toolsVersionStatus` (https://github.com/ansible-collections/community.vmware/issues/2033). + +Deprecated Features +------------------- + +- vmware_guest_tools_info - `vm_tools_install_status` will be removed from next major version (5.0.0) of the collection since the API call that provides this information has been deprecated by VMware. Use `vm_tools_running_status` / `vm_tools_version_status` instead (https://github.com/ansible-collections/community.vmware/issues/2033). + +Bugfixes +-------- + +- Use `isinstance()` instead of `type()` for a typecheck (https://github.com/ansible-collections/community.vmware/pull/2011). +- vmware_guest - Fix a error while updating the VM by adding a new disk. While adding a disk to an existing VM, it leaves it in invalid state. (https://github.com/ansible-collections/community.vmware/pull/2044). +- vmware_guest - Fix a missing error message while setting a template parameter with inconsistency guest_os ID (https://github.com/ansible-collections/community.vmware/pull/2036). + v4.2.0 ====== diff --git a/ansible_collections/community/vmware/FILES.json b/ansible_collections/community/vmware/FILES.json index 82d6f277e..68fe7037b 100644 --- a/ansible_collections/community/vmware/FILES.json +++ b/ansible_collections/community/vmware/FILES.json @@ -25,14 +25,14 @@ "name": ".github/workflows/ansible-test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c7dfcceab897d76f899e9745a5ef5134a7deffe84c7c9aca9bcce00e903a7ca8", + "chksum_sha256": "75ced302218d85f3484c215700b3626db0288f380c6d549f666f13ddd05585e8", "format": 1 }, { "name": ".github/workflows/extra-docs-linting.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "19bb097e3a34621e1b74ce740716ee78818a3d6b752b1563f10e69d20450556c", + "chksum_sha256": "8d8d67559ba7e1fa9a637f9abee5cffe406f341fbb70ab75c60b71d46a2a92e0", "format": 1 }, { @@ -88,7 +88,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c77e5b2e21540ce43a2d83a648e341766d6373b8a909280c8a6f8cc160a40bc7", + "chksum_sha256": "fa92ffc48b8d5e744ed8748724d0623b9bdc81a4e57798fe99098640234cc5bc", "format": 1 }, { @@ -120,146 +120,6 @@ "format": 1 }, { - "name": "docs/docsite/rst/vmware_scenarios", - "ftype": "dir", - "chksum_type": null, - "chksum_sha256": null, - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/faq.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "930dbbb64474e63f5371f1bf3d989e7ac744c9201056a9ca0dc5bbb8be45386b", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/scenario_clone_template.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "71d07a85971e0b3da2ee1e7fc57349685d1a29c55e2ac8444b71ef76a623568c", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/scenario_find_vm_folder.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "84cccda3524f9c42bc470d6b2ef556c78a341cef15e78e628098dfa41350b1a9", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/scenario_remove_vm.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "5b80011ada8788e518ce9758f8c176581d6dd934cb1038eee3054c238467c20a", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/scenario_rename_vm.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "c3e8eb03b3317a7cbaa600c96b7db5771e85e48eb604c87a1a5383b32de23ee7", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/scenario_vmware_http.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "3442465954b3b08d445789816a235ac8f1f5e7799a0f78c705a402b03658465c", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/scenario_vmware_tools_connection.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "421865322fddfc9980e9af80cb78186cf752108aa438cf54a763a2a39c07770c", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_concepts.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "82bbd9bbc2f7e55103115b9200026f95766dad11a16f802808c3685e9de6ed6e", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_external_doc_links.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "64cc4675a425117eaaecd9e79fcf3e4296d8c8a271cc628db8a79cb7a81fa588", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_getting_started.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "f8f3bae534ece698eda5bcc1334e1f211b5593620886979de0375d9f4d3dcd08", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_intro.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "95e3b92ba05d1f3a0f22eb11471b4ac6d3c906aeb3b5d54e9eb2c0b82c86185e", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_inventory.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "01faddedba147f6ad6a03abbbbb22a8890e6d79ea9339356f4e3a394ea32d3a5", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_inventory_filters.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "61db0373933ffe8e85ea740d938ecd3b541aff3b97a9367c981cc766f7e054cf", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_inventory_hostnames.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "15c534d481f064527280739774b56da9dae37d0ab05e48707f18855840b5a610", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_inventory_vm_attributes.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "af1c7f150d450f47f4db46c96f30699dec2cd67bbd2c1cd3ea1a5acadd288b92", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_module_reference.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "973d25cc3a951fc05aa4d0a1b0e16b34444fce3389bb838a354a1f48b7f77602", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_requirements.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "5c1986dde7d60dd77db7bfacc48f6931ad366bb8429024300d7d348595be1bed", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_scenarios.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "335f2dd7e2a77e322c8e45e22f20c761e9289c46c5deb4f379d86369dc345f22", - "format": 1 - }, - { - "name": "docs/docsite/rst/vmware_scenarios/vmware_troubleshooting.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "a7b26ba15577611b5a9925b8f18ce04d03dd9308d3c36a77a1c4af628077d6b7", - "format": 1 - }, - { "name": "docs/docsite/rst/dev_guide.rst", "ftype": "file", "chksum_type": "sha256", @@ -267,17 +127,10 @@ "format": 1 }, { - "name": "docs/docsite/rst/scenario_guide.rst", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "e33043c593d5173ca6fc80bc9d4ea744ecdb31e17288c60fd41bbbf8cecf2b8e", - "format": 1 - }, - { "name": "docs/docsite/extra-docs.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a04e14a68de6ce6570daa59ec2696684760f597b1ae085c410060f7bba9ae164", + "chksum_sha256": "1e07a4f54473638944cb668af1946e6720c9fd68d0e42b50e810f80bb787f6e7", "format": 1 }, { @@ -291,7 +144,7 @@ "name": "meta/runtime.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6b8f4f91c50cad886a4518aefee3ec6b06d0ba0f8b4ca1012b9f2f5086549b2e", + "chksum_sha256": "640043f6dea01c5c53fac165595ead8d77e2c0ff2be5c17f1e5372d3be8e499f", "format": 1 }, { @@ -340,14 +193,14 @@ "name": "plugins/doc_fragments/vmware.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "06348a39b25b21a24f79031dc99652b42cc09df93f54c29445df2dce0bbddd7d", + "chksum_sha256": "66fce69c869a2fab3666a3d36142c09212827f55a3fd681afcb93df34d23404c", "format": 1 }, { "name": "plugins/doc_fragments/vmware_rest_client.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cc694d07e9412e11238a8fab29a003337a21a1acb73c836ba9ed91923a74b8e3", + "chksum_sha256": "e392382f541729a10a27b064c036cf2232da62c02e06bca7cbee0d3b5fd04d61", "format": 1 }, { @@ -424,7 +277,7 @@ "name": "plugins/module_utils/vmware.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7dc70d2619b3e76336b732af47103d65ede45c8bd780aea3a67cb324ddcf3ff8", + "chksum_sha256": "902d67e645b235e10d27e179666442625e6ea9df4a4e4589ee6ba1427376b652", "format": 1 }, { @@ -487,7 +340,7 @@ "name": "plugins/modules/vcenter_folder.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "11e5b4064182b25aaeb7ab2ab1d9e5749f1e0a89244848f90c9f40b34bc82196", + "chksum_sha256": "0c27fd723ffd81277ccff70f5babafc38b33e0b302fcf9dbd0a17529d70074ad", "format": 1 }, { @@ -519,17 +372,24 @@ "format": 1 }, { + "name": "plugins/modules/vmware_all_snapshots_info.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "90c3ebaa53599914d5d4abf60e018666e5e7ac47a176973d924daab9694ddbb6", + "format": 1 + }, + { "name": "plugins/modules/vmware_category.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "803becfbcd55ee9cbfd72cd45c462bc712506b9cb88dd1a74cdfde0dbc8e127e", + "chksum_sha256": "30c64d2900fba1ffac504b8fb9708768388bf8cfc136cab67060034cc98fc6ec", "format": 1 }, { "name": "plugins/modules/vmware_category_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4a96e1cf4a156c93b0d9d2a0460078574cd5ebb8696ec5bd358b788ff9ae3218", + "chksum_sha256": "1cbf1ddbab506852d4919512b66b36dc7c2428f69521019a1730a09018047367", "format": 1 }, { @@ -543,21 +403,21 @@ "name": "plugins/modules/vmware_cluster.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4a98362ca64844cddaaf8878893a9def9bace3193a2bc8da8a877bee1edf854a", + "chksum_sha256": "311163c84c4d0a43349afa7bbc7afedd3ab1fc43ec4fdae9cd705d004e380a21", "format": 1 }, { "name": "plugins/modules/vmware_cluster_dpm.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3f463cf81333d20291c899891abda5f48b1ff74108e949cf3b11c4b754df8683", + "chksum_sha256": "823d0eba4ad0a749924bc16b0ac8540211a54add654b4ca445c8ad246bddf250", "format": 1 }, { "name": "plugins/modules/vmware_cluster_drs.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2b9b944de75a0973e2540aefca3bd3d5853d803cf5965d967a7a79c2a4b96dc3", + "chksum_sha256": "e34a56ecad9d3a2746ead00a58e4cbb65b19e39f06331a28864cb18660c8327f", "format": 1 }, { @@ -571,56 +431,56 @@ "name": "plugins/modules/vmware_cluster_ha.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f5d91c541f5e62fa4dfa246dc8d887128ddf0f23876b15dbcb6f069973c69cce", + "chksum_sha256": "b28c2e004816ce245f6cd32bb4c36c78eaf08dc1f4f8fb3aacc26c6c9417f2fa", "format": 1 }, { "name": "plugins/modules/vmware_cluster_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "82f3e55c5865b15aa735c536c1a6798cb202c7f79a043b54852da7f3e29c3599", + "chksum_sha256": "2f1c85c2da228ca18fd165303c4bf6e3820785433f8e4c4b29da5532f097ae55", "format": 1 }, { "name": "plugins/modules/vmware_cluster_vcls.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5c40ed2776b1c51fb8bd540bd4f505a89950c86a796af60bba69a25efe4b5431", + "chksum_sha256": "775056566fd97d763e8b96ad5c98403e705003310b77a2d18bc6a34b132cb9cf", "format": 1 }, { "name": "plugins/modules/vmware_cluster_vsan.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "fc41f927567108b1d8fe017195d140378a73480f89d503011b270818e6b8728c", + "chksum_sha256": "93ecdc100e8fa5f100f2338ba2bdfbae93478e34bbf59059cda3fd5f717bdda6", "format": 1 }, { "name": "plugins/modules/vmware_content_deploy_ovf_template.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "056f5aab74cad12ff5c0bba871a38d0082afb9e3ed4f6c9f12f5b5cf4d552ce0", + "chksum_sha256": "a504f0013c4cb6c309975d8b7d4dd1d158abfd5fa0c0a08afbbf02b8c947e29b", "format": 1 }, { "name": "plugins/modules/vmware_content_deploy_template.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f72369be7754bc4e22ffef0cb6a56db07532f0d391b19011f20f2b5ecc426d84", + "chksum_sha256": "38d7265a3b17b904ffa4e70da0d0d09ee42088a07df9f2d14337dd9a563a9bcf", "format": 1 }, { "name": "plugins/modules/vmware_content_library_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e1293f0cb822b7435cb3d3e1e5170c990bc03d06ab49ae5cfcf7f32653b83285", + "chksum_sha256": "b1668dc4da6e9e41a143c7e80bc8f59bdb13d2ca30d22b10bd4e0a1a1324ec6e", "format": 1 }, { "name": "plugins/modules/vmware_content_library_manager.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4efe68143e7233415a30e91fb71b68b24fd8635305a29899462943fe6e834286", + "chksum_sha256": "0d736b6cba5b9d62cc6e63ce39bbb8e371783d5bb58f888ccacaac5646a2bf6c", "format": 1 }, { @@ -662,21 +522,21 @@ "name": "plugins/modules/vmware_datastore_cluster.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "32e575cf227fec3ae5004d97b413c3d9a2ed4bf0f0b3b6a0479b344d6c7c7147", + "chksum_sha256": "b56a80bf30230a6128d64360ea3ee2eac60df4003700db5a53adaddf28667880", "format": 1 }, { "name": "plugins/modules/vmware_datastore_cluster_manager.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d777f38acda366326fbf061e4037ef5a0ffb98384998224076a45192ee73f69c", + "chksum_sha256": "ea6224af0dfe43391aaa73e6e1601437e971bda1ad080bfe626a715ed5fcf029", "format": 1 }, { "name": "plugins/modules/vmware_datastore_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f18ba418804c7f5bc856500ab4a6d9e24fa558a15340c5dcb28495961b5e562a", + "chksum_sha256": "324deb8bd961b7c4834f581d1979ab0aba69e7a7e82879f060a4b37ec2a4edda", "format": 1 }, { @@ -690,7 +550,7 @@ "name": "plugins/modules/vmware_deploy_ovf.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7fc7ced342d72f868d3d6d8919f071732ee35bdee34af491c9dbcae1272a29c9", + "chksum_sha256": "735cafd1d64ae101d323f220cdd05384738b97f99434ee5838b820cbbb2e5930", "format": 1 }, { @@ -753,7 +613,7 @@ "name": "plugins/modules/vmware_dvswitch.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e0b58b5ff685fd093fa0b97931473dd6be059b435a6c0e332915019d342ef893", + "chksum_sha256": "be8458b48fdfadbcea5849beed4ef03651f0465a5f37cec72d7f5ac610968202", "format": 1 }, { @@ -802,7 +662,7 @@ "name": "plugins/modules/vmware_export_ovf.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "55d635752a4c3cc1af02ae255a1acf073781e4ce441195e76bcf5764551e098c", + "chksum_sha256": "d174a4d017092d89a92a0555e1e078aa39e4356370bb6215fa90979f46b2086f", "format": 1 }, { @@ -830,7 +690,7 @@ "name": "plugins/modules/vmware_guest.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "55738b294073afb1f44d52bbcd1590ebd9f4a3fd93cdf563aa663a35f9e41560", + "chksum_sha256": "e4bab2821b327625942772574bd70a12d56eb81cc9b883c2351d1636defbd235", "format": 1 }, { @@ -844,21 +704,21 @@ "name": "plugins/modules/vmware_guest_boot_manager.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "67e88707f99a21714c12a0263bccae93e7f2e7179eae4f5ce0083de4d268dbde", + "chksum_sha256": "acea9e5a58f9f23e872f0a8629d5e0c92bd729e75eef2f70c3d39379d057ba91", "format": 1 }, { "name": "plugins/modules/vmware_guest_controller.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "80c4af1521de6264c891a2e60f60fbd62d342011d072cf198cf702b52e26ce71", + "chksum_sha256": "961937472c22b53f5b6034525a9f75e33f1fa628b22f24649f3df98cbd7fc55b", "format": 1 }, { "name": "plugins/modules/vmware_guest_cross_vc_clone.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "283ac6f176ab1cd023ac5b65784fa3fbfdf5979113b86ca3ca0473f1f36ac4e8", + "chksum_sha256": "3a25bcc0ebc47ec9aee6299bf1edd5e61b6edeb982164b47654a6fe99d505e54", "format": 1 }, { @@ -879,21 +739,21 @@ "name": "plugins/modules/vmware_guest_customization_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9c78119d928cbbdb182d88571ab881b8b28c11de7c9d9b93d1f7abafcd289959", + "chksum_sha256": "00a52eaee1678b4982f4cb7811bde96449d6c49164d4caee8b6966ea9e24def5", "format": 1 }, { "name": "plugins/modules/vmware_guest_disk.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "aaadad51ac60409131ac1870bf3718e084b7a1ab931424acd68ccf430ff0c96c", + "chksum_sha256": "998605e6ca41ceae52998a664c26c9ec6cd42495c14dc98255621d4ebd8abe54", "format": 1 }, { "name": "plugins/modules/vmware_guest_disk_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5e3f6251a881e672180694dbfe1c548625acabb8a0ac525d1c675d98aafeae7e", + "chksum_sha256": "1853016016ef07e306e9a34309d4feda76e0b5f67781851cec52f29f1b11d7be", "format": 1 }, { @@ -921,14 +781,14 @@ "name": "plugins/modules/vmware_guest_instant_clone.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "13d57b323a3f9662c6ef419b0d549f03b76fb98909c5361ce90ed387213359e0", + "chksum_sha256": "c5c9cde1be64a9968211f02d5e45eb91806bf4f0a9cff4b7789e2649b1a8890b", "format": 1 }, { "name": "plugins/modules/vmware_guest_move.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a7a8c7fa21886fd90d091511ebe933e0f3848fea87b886358dcf41d5aab48112", + "chksum_sha256": "c3160b9fd746e6ec1ea229b6e6566d464389f9797e972c06fb567a265724c897", "format": 1 }, { @@ -942,28 +802,28 @@ "name": "plugins/modules/vmware_guest_powerstate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7296037dcfa5296e29eb3a2f1fa6968267e80acfbd97f8279141331197f432b1", + "chksum_sha256": "3b8c4d4347fb6db05daabcfc23ebb5d61a3eaaeba8b3fba8b323dca0869bb575", "format": 1 }, { "name": "plugins/modules/vmware_guest_register_operation.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "367d95915f41ade54a88f5277a56d76012920e990fe6e2b2f6e99914cdc0ac67", + "chksum_sha256": "4d03dc3328c6b15d025bd9a067db6e3b07d3a6d83e285ccc2ac6083362def7ec", "format": 1 }, { "name": "plugins/modules/vmware_guest_screenshot.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "581e791515b4de8f1d010a63aafb6fd032621d716f84df4ed0c8c17643d1481d", + "chksum_sha256": "098ba39e82d0f8deffe53548e620b744e1ead80f97e79c6c418b04111002a129", "format": 1 }, { "name": "plugins/modules/vmware_guest_sendkey.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b7c7233857e429495fe4590bb04bb1d5969a69e51f13e4710f1f63858c6c8029", + "chksum_sha256": "be64447bd8f19cb536bc2989e922b94a602c7bdb9252869be37aff894daeb0f6", "format": 1 }, { @@ -977,7 +837,7 @@ "name": "plugins/modules/vmware_guest_snapshot.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bf3c5339f076c95b0b0525281829f407b862ebc9e5d3c41a85127d52c85ebd64", + "chksum_sha256": "6eccf9a0a8f9330b13a0805391bcfb618379a402cb8d88a4aae7efe15312a952", "format": 1 }, { @@ -991,14 +851,14 @@ "name": "plugins/modules/vmware_guest_storage_policy.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "83de69a093891f34dd8ad71be700ad455616f00344f9aa05de00b25290b1749d", + "chksum_sha256": "9dabff116a379bfbecf992aea4326a15e82105bcc08fa83e69b84ca93808c44f", "format": 1 }, { "name": "plugins/modules/vmware_guest_tools_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b0eee01ad1315b25b15cccb47332890b7d60fb7f486e18951cda7b91678a7b3c", + "chksum_sha256": "06c9b2377a22371f9924f6bad1f18c7a99340e6628271de1204ee51ec9f8f7ae", "format": 1 }, { @@ -1019,28 +879,28 @@ "name": "plugins/modules/vmware_guest_tpm.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e73e993987116bb0a8f94f15be9a298ad523a1edc75577e70b18124f0a11fc50", + "chksum_sha256": "41d8d618e17d8bab62425550e58d62f68d627ff84838a76c69db7280c6637ca8", "format": 1 }, { "name": "plugins/modules/vmware_guest_vgpu.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bc7cef555f0688d289cfaa7fac62e32fc2f0801e406602adeb0e85150ce6ac24", + "chksum_sha256": "29a51f9bbddc129be2e3a3b937a443f586329dafcaeed1d9df63345cb52fa946", "format": 1 }, { "name": "plugins/modules/vmware_guest_vgpu_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d42e32c21a8c8b2447b869d73ee3235f893ab4ab9f0419be4bfb351b09c8711c", + "chksum_sha256": "e40a6d62d5566c22d47a2b85ad55e8a26e2fc08c95761a96f096fd9564a4f4a9", "format": 1 }, { "name": "plugins/modules/vmware_guest_video.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e9bbb46a7f1d814bc172f12339ed7c74eabcd7b1b5f2734f5cca08b44f27587b", + "chksum_sha256": "4b45e1f2708295625256a04756a2173ec443656b2195040fc2c37fac7445a7e1", "format": 1 }, { @@ -1110,7 +970,7 @@ "name": "plugins/modules/vmware_host_datastore.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d16e63c55e7f60e67c444d2e6221979bd9686fb6b505da6f4c1c1a5bac327043", + "chksum_sha256": "d8a69b96e9092b60f593fff47f29c81dad602a12ac954ee369ea6f1c414b35d8", "format": 1 }, { @@ -1131,7 +991,7 @@ "name": "plugins/modules/vmware_host_dns_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6ff0ef349e63ba77ffe530527281f057e605556e44680196a1fc7ae6af6bf52b", + "chksum_sha256": "e1e75a2146d8030295c3340f77cc6ddafbc1e1e32e4e0ceaecb5c0c3723bb1cd", "format": 1 }, { @@ -1208,14 +1068,14 @@ "name": "plugins/modules/vmware_host_lockdown.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0928b4198afb453f5112bbdfbf6c1bb79acfa727f1880c2041a68d547cf29df4", + "chksum_sha256": "2b89107bcc0f64dea4d3951287dd6eba9363fe90dd3593566fbe40930bfa6550", "format": 1 }, { "name": "plugins/modules/vmware_host_lockdown_exceptions.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f160e9dd9508feaf378f91d81756bec62fdd341c69af59cd7ca42d6a93abddae", + "chksum_sha256": "bc668da0bebbb572a0d3e6547a555c24ecc66d2d1a27f450a39f95a95284e374", "format": 1 }, { @@ -1278,7 +1138,7 @@ "name": "plugins/modules/vmware_host_scanhba.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7b3a3aafa0fd9786cfd95cd61a2d48c275f2239695ac5a7e4724c2ad79b675ab", + "chksum_sha256": "2da03b6b66863611805de12deb733040c461d01c96b29cba8faa56390df849f6", "format": 1 }, { @@ -1369,7 +1229,7 @@ "name": "plugins/modules/vmware_local_user_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e17900d6d0c71ff7f8261b0b7206529342d63ddc5b85736fdb837e278f091ddb", + "chksum_sha256": "d7aa4625a79ee1126375294702f94d4beb2d410570d72663a926c672a03447c4", "format": 1 }, { @@ -1404,7 +1264,7 @@ "name": "plugins/modules/vmware_object_rename.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "37f489b055f824b6359902d4bc137fbd8d15766089d5f48f7633eac0e424d314", + "chksum_sha256": "04145884fc9eac139b5bd2c583628987cabf994b230070e1371ad7c50e7bdfef", "format": 1 }, { @@ -1460,21 +1320,21 @@ "name": "plugins/modules/vmware_tag.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "4518b9e396ba1f7bc6e1bfc940354894de6de17fcad23a25a4fd291c9af78908", + "chksum_sha256": "80958e12ec311af76c5b86fdd163efd4459a5c0a56f369d76f86daa45b3d0d28", "format": 1 }, { "name": "plugins/modules/vmware_tag_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "44d9da854f578cb92dcd26b26470bf3cbbc9acb8de7f50f656f18852fdfc6d95", + "chksum_sha256": "614bbf9d87c86725cfb57548046e57441fa38562f4c64ebcff50632a68c5f443", "format": 1 }, { "name": "plugins/modules/vmware_tag_manager.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "71e0a9229c66e5e788e65bb80450508024efda304620562a6ab0b250474e2225", + "chksum_sha256": "92f36995dc2dbaaabb9caa790a135fcfdbb42a87ee3d55ec4b8787dc2a0c97bd", "format": 1 }, { @@ -1502,7 +1362,7 @@ "name": "plugins/modules/vmware_vc_infraprofile_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c3a9e5a035ff87eb4843be8c2a3785d16efad669d93f07d5e47c924ead2c0ef7", + "chksum_sha256": "b491bce442122162d5eb1d7b8738576ac98a9982564a6950a806875cee11d56e", "format": 1 }, { @@ -1530,7 +1390,7 @@ "name": "plugins/modules/vmware_vm_config_option.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "591504d7977d1ced5a5f538783b01a81b56a5bd8de82e5990949663058a1359d", + "chksum_sha256": "1729e863834cf6326ec25cac2532666a18b17360e3377e02962dc0e991d0ffec", "format": 1 }, { @@ -1551,7 +1411,7 @@ "name": "plugins/modules/vmware_vm_shell.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9416f7b6cd6fb70e09b9b1a5ee5aac81250544037017bca639a916da47a5690d", + "chksum_sha256": "8de5d76c004005febc9fd6bb57a94dcc6cfcc996aa27e2f0bfd0c52d159d47c4", "format": 1 }, { @@ -1733,7 +1593,7 @@ "name": "scripts/inventory/vmware_inventory.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "45f7b341f4ce6f9b4e6392ee6e78a94f5187f370a314e358b5cf30f29492295f", + "chksum_sha256": "71d1124982666d9b26fffdf287f7aa0057662df4a400e2888149ce646a6dc6f8", "format": 1 }, { @@ -6917,6 +6777,13 @@ "format": 1 }, { + "name": "tests/sanity/ignore-2.18.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5c62bddf4ca5eac160fda8aa8cc0ce0998ab1a3dccb91c37270a837c2d1e20cd", + "format": 1 + }, + { "name": "tests/unit", "ftype": "dir", "chksum_type": null, @@ -6941,7 +6808,7 @@ "name": "tests/unit/mock/loader.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3b51ec0d45347a3568300e50f688998007e346f052bd2e961c2ac6d13f7cee4d", + "chksum_sha256": "7c14b7d02a6ccfe27d0012190a7e457eec60a92ba68a6377e488f31e71da062c", "format": 1 }, { @@ -7158,7 +7025,7 @@ "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a26eb552f9062d66fdecc635a886f159a66790045e05dcfc7da4574f974140b3", + "chksum_sha256": "6b2e0c075305c8d5f1b662a7533014e70ec9d1733eb79d5f70f1e024ecc06d99", "format": 1 }, { diff --git a/ansible_collections/community/vmware/MANIFEST.json b/ansible_collections/community/vmware/MANIFEST.json index acc7f148d..d1bc8edfe 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.2.0", + "version": "4.3.0", "authors": [ "Ansible (https://github.com/ansible)" ], @@ -28,7 +28,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1ef7fbdfa909824b3ed7734c6a79135d82971bdff522b1ddd9c3cb4844c21d9a", + "chksum_sha256": "af79d3641999ba756f51b0b3c0562e0ebba66c8c764a0aff81496d5906a7398a", "format": 1 }, "format": 1 diff --git a/ansible_collections/community/vmware/changelogs/changelog.yaml b/ansible_collections/community/vmware/changelogs/changelog.yaml index f2d8cea11..2b250b5fd 100644 --- a/ansible_collections/community/vmware/changelogs/changelog.yaml +++ b/ansible_collections/community/vmware/changelogs/changelog.yaml @@ -102,3 +102,31 @@ releases: - 1995-vsphere_copy.yml - 1996 - vmware_first_class_disk_info.yml release_date: '2024-02-24' + 4.3.0: + changes: + bugfixes: + - Use `isinstance()` instead of `type()` for a typecheck (https://github.com/ansible-collections/community.vmware/pull/2011). + - vmware_guest - Fix a error while updating the VM by adding a new disk. While + adding a disk to an existing VM, it leaves it in invalid state. (https://github.com/ansible-collections/community.vmware/pull/2044). + - vmware_guest - Fix a missing error message while setting a template parameter + with inconsistency guest_os ID (https://github.com/ansible-collections/community.vmware/pull/2036). + deprecated_features: + - vmware_guest_tools_info - `vm_tools_install_status` will be removed from next + major version (5.0.0) of the collection since the API call that provides this + information has been deprecated by VMware. Use `vm_tools_running_status` / + `vm_tools_version_status` instead (https://github.com/ansible-collections/community.vmware/issues/2033). + minor_changes: + - Document that all parameters and VMware object names are case sensitive (https://github.com/ansible-collections/community.vmware/issues/2019). + - Drop the outdated (and actually unmaintained) scenario guides (https://github.com/ansible-collections/community.vmware/pull/2022). + - vmware_dvswitch - Add switchIpAddress/switch_ip parameter for netflow config + - vmware_guest_tools_info - Use `toolsVersionStatus2` instead of `toolsVersionStatus` + (https://github.com/ansible-collections/community.vmware/issues/2033). + fragments: + - 1949-dvswitch_netflow_switch_ip.yml + - 2019-doc_fragments-case-sensitive.yml + - 2022-drop_sceanrio_guides.yml + - 2024027-fix_ci.yml + - 2033-vmware_guest_tools_info.yml + - 2036-missing_error_msg_in_vmware_guest.yml + - 2044-error_in_adding_disk_to_vm_in_vmware_guest.yml + release_date: '2024-04-20' diff --git a/ansible_collections/community/vmware/docs/docsite/extra-docs.yml b/ansible_collections/community/vmware/docs/docsite/extra-docs.yml index 9acde7f20..cc63130a2 100644 --- a/ansible_collections/community/vmware/docs/docsite/extra-docs.yml +++ b/ansible_collections/community/vmware/docs/docsite/extra-docs.yml @@ -1,8 +1,5 @@ --- sections: - - title: Scenario Guide - toctree: - - scenario_guide - title: Developer Guide toctree: - dev_guide diff --git a/ansible_collections/community/vmware/docs/docsite/rst/scenario_guide.rst b/ansible_collections/community/vmware/docs/docsite/rst/scenario_guide.rst deleted file mode 100644 index 270af08cd..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/scenario_guide.rst +++ /dev/null @@ -1,33 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_ansible: - -************ -VMware Guide -************ - -Welcome to the Ansible for VMware Guide! - -The purpose of this guide is to teach you everything you need to know about using Ansible with VMware. - -To get started, please select one of the following topics. - -.. toctree:: - :maxdepth: 1 - - vmware_scenarios/vmware_intro - vmware_scenarios/vmware_concepts - vmware_scenarios/vmware_requirements - vmware_scenarios/vmware_inventory - vmware_scenarios/vmware_inventory_vm_attributes - vmware_scenarios/vmware_inventory_hostnames - vmware_scenarios/vmware_inventory_filters - vmware_scenarios/vmware_scenarios - vmware_scenarios/vmware_troubleshooting - vmware_scenarios/vmware_external_doc_links - vmware_scenarios/faq -.. comments look like this - start with two dots -.. getting_started content not ready -.. vmware_scenarios/vmware_getting_started -.. module index page not ready -.. vmware_scenarios/vmware_module_reference -.. always exclude the template file -.. vmware_scenarios/vmware_scenario_1 diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/faq.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/faq.rst deleted file mode 100644 index 52f4f729e..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/faq.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_faq: - -****************** -Ansible VMware FAQ -****************** - -vmware_guest -============ - -Can I deploy a virtual machine on a standalone ESXi server ? ------------------------------------------------------------- - -Yes. ``vmware_guest`` can deploy a virtual machine with required settings on a standalone ESXi server. -However, you must have a paid license to deploy virtual machines this way. If you are using the free version, the API is read-only. - -Is ``/vm`` required for ``vmware_guest`` module ? -------------------------------------------------- - -Prior to Ansible version 2.5, ``folder`` was an optional parameter with a default value of ``/vm``. - -The folder parameter was used to discover information about virtual machines in the given infrastructure. - -Starting with Ansible version 2.5, ``folder`` is still an optional parameter with no default value. -This parameter will be now used to identify a user's virtual machine, if multiple virtual machines or virtual -machine templates are found with same name. VMware does not restrict the system administrator from creating virtual -machines with same name. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_clone_template.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_clone_template.rst deleted file mode 100644 index 1139a2523..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_clone_template.rst +++ /dev/null @@ -1,223 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_guest_from_template: - -**************************************** -Deploy a virtual machine from a template -**************************************** - -.. contents:: - :local: - -Introduction -============ - -This guide will show you how to utilize Ansible to clone a virtual machine from already existing VMware template or existing VMware guest. - -Scenario requirements -===================== - -* Software - - * Ansible 2.5 or later must be installed - - * The Python module ``Pyvmomi`` must be installed on the Ansible (or Target host if not executing against localhost) - - * Installing the latest ``Pyvmomi`` via ``pip`` is recommended [as the OS provided packages are usually out of date and incompatible] - -* Hardware - - * vCenter Server with at least one ESXi server - -* Access / Credentials - - * Ansible (or the target server) must have network access to the either vCenter server or the ESXi server you will be deploying to - - * Username and Password - - * Administrator user with following privileges - - - ``Datastore.AllocateSpace`` on the destination datastore or datastore folder - - ``Network.Assign`` on the network to which the virtual machine will be assigned - - ``Resource.AssignVMToPool`` on the destination host, cluster, or resource pool - - ``VirtualMachine.Config.AddNewDisk`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.AddRemoveDevice`` on the datacenter or virtual machine folder - - ``VirtualMachine.Interact.PowerOn`` on the datacenter or virtual machine folder - - ``VirtualMachine.Inventory.CreateFromExisting`` on the datacenter or virtual machine folder - - ``VirtualMachine.Provisioning.Clone`` on the virtual machine you are cloning - - ``VirtualMachine.Provisioning.Customize`` on the virtual machine or virtual machine folder if you are customizing the guest operating system - - ``VirtualMachine.Provisioning.DeployTemplate`` on the template you are using - - ``VirtualMachine.Provisioning.ReadCustSpecs`` on the root vCenter Server if you are customizing the guest operating system - - Depending on your requirements, you could also need one or more of the following privileges: - - - ``VirtualMachine.Config.CPUCount`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.Memory`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.DiskExtend`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.Annotation`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.AdvancedConfig`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.EditDevice`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.Resource`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.Settings`` on the datacenter or virtual machine folder - - ``VirtualMachine.Config.UpgradeVirtualHardware`` on the datacenter or virtual machine folder - - ``VirtualMachine.Interact.SetCDMedia`` on the datacenter or virtual machine folder - - ``VirtualMachine.Interact.SetFloppyMedia`` on the datacenter or virtual machine folder - - ``VirtualMachine.Interact.DeviceConnection`` on the datacenter or virtual machine folder - -Assumptions -=========== - -- All variable names and VMware object names are case sensitive. -- VMware allows creation of virtual machine and templates with same name across datacenters and within datacenters. -- You need to use Python 2.7.9 version in order to use ``validate_certs`` option, as this version is capable of changing the SSL verification behaviours. - -Caveats -======= - -- Hosts in the ESXi cluster must have access to the datastore that the template resides on. -- Multiple templates with the same name will cause module failures. -- In order to utilize Guest Customization, VMware Tools must be installed on the template. For Linux, the ``open-vm-tools`` package is recommended, and it requires that ``Perl`` be installed. - - -Example description -=================== - -In this use case / example, we will be selecting a virtual machine template and cloning it into a specific folder in our Datacenter / Cluster. The following Ansible playbook showcases the basic parameters that are needed for this. - -.. code-block:: yaml - - --- - - name: Create a VM from a template - hosts: localhost - gather_facts: no - tasks: - - name: Clone the template - vmware_guest: - hostname: "{{ vcenter_ip }}" - username: "{{ vcenter_username }}" - password: "{{ vcenter_password }}" - validate_certs: False - name: testvm_2 - template: template_el7 - datacenter: "{{ datacenter_name }}" - folder: /DC1/vm - state: poweredon - cluster: "{{ cluster_name }}" - wait_for_ip_address: yes - - -Since Ansible utilizes the VMware API to perform actions, in this use case we will be connecting directly to the API from our localhost. This means that our playbooks will not be running from the vCenter or ESXi Server. We do not necessarily need to collect facts about our localhost, so the ``gather_facts`` parameter will be disabled. You can run these modules against another server that would then connect to the API if your localhost does not have access to vCenter. If so, the required Python modules will need to be installed on that target server. - -To begin, there are a few bits of information we will need. First and foremost is the hostname of the ESXi server or vCenter server. After this, you will need the username and password for this server. For now, you will be entering these directly, but in a more advanced playbook this can be abstracted out and stored in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_. If your vCenter or ESXi server is not setup with proper CA certificates that can be verified from the Ansible server, then it is necessary to disable validation of these certificates by using the ``validate_certs`` parameter. To do this you need to set ``validate_certs=False`` in your playbook. - -Now you need to supply the information about the virtual machine which will be created. Give your virtual machine a name, one that conforms to all VMware requirements for naming conventions. Next, select the display name of the template from which you want to clone new virtual machine. This must match what's displayed in VMware Web UI exactly. Then you can specify a folder to place this new virtual machine in. This path can either be a relative path or a full path to the folder including the Datacenter. You may need to specify a state for the virtual machine. This simply tells the module which action you want to take, in this case you will be ensure that the virtual machine exists and is powered on. An optional parameter is ``wait_for_ip_address``, this will tell Ansible to wait for the virtual machine to fully boot up and VMware Tools is running before completing this task. - - -What to expect --------------- - -- You will see a bit of JSON output after this playbook completes. This output shows various parameters that are returned from the module and from vCenter about the newly created VM. - -.. code-block:: yaml - - { - "changed": true, - "instance": { - "annotation": "", - "current_snapshot": null, - "customvalues": {}, - "guest_consolidation_needed": false, - "guest_question": null, - "guest_tools_status": "guestToolsNotRunning", - "guest_tools_version": "0", - "hw_cores_per_socket": 1, - "hw_datastores": [ - "ds_215" - ], - "hw_esxi_host": "192.0.2.44", - "hw_eth0": { - "addresstype": "assigned", - "ipaddresses": null, - "label": "Network adapter 1", - "macaddress": "00:50:56:8c:19:f4", - "macaddress_dash": "00-50-56-8c-19-f4", - "portgroup_key": "dvportgroup-17", - "portgroup_portkey": "0", - "summary": "DVSwitch: 50 0c 5b 22 b6 68 ab 89-fc 0b 59 a4 08 6e 80 fa" - }, - "hw_files": [ - "[ds_215] testvm_2/testvm_2.vmx", - "[ds_215] testvm_2/testvm_2.vmsd", - "[ds_215] testvm_2/testvm_2.vmdk" - ], - "hw_folder": "/DC1/vm", - "hw_guest_full_name": null, - "hw_guest_ha_state": null, - "hw_guest_id": null, - "hw_interfaces": [ - "eth0" - ], - "hw_is_template": false, - "hw_memtotal_mb": 512, - "hw_name": "testvm_2", - "hw_power_status": "poweredOff", - "hw_processor_count": 2, - "hw_product_uuid": "420cb25b-81e8-8d3b-dd2d-a439ee54fcc5", - "hw_version": "vmx-13", - "instance_uuid": "500cd53b-ed57-d74e-2da8-0dc0eddf54d5", - "ipv4": null, - "ipv6": null, - "module_hw": true, - "snapshots": [] - }, - "invocation": { - "module_args": { - "annotation": null, - "cdrom": {}, - "cluster": "DC1_C1", - "customization": {}, - "customization_spec": null, - "customvalues": [], - "datacenter": "DC1", - "disk": [], - "esxi_hostname": null, - "folder": "/DC1/vm", - "force": false, - "guest_id": null, - "hardware": {}, - "hostname": "192.0.2.44", - "is_template": false, - "linked_clone": false, - "name": "testvm_2", - "name_match": "first", - "networks": [], - "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", - "port": 443, - "resource_pool": null, - "snapshot_src": null, - "state": "present", - "state_change_timeout": 0, - "template": "template_el7", - "username": "administrator@vsphere.local", - "uuid": null, - "validate_certs": false, - "vapp_properties": [], - "wait_for_ip_address": true - } - } - } - -- State is changed to ``True`` which notifies that the virtual machine is built using given template. The module will not complete until the clone task in VMware is finished. This can take some time depending on your environment. - -- If you utilize the ``wait_for_ip_address`` parameter, then it will also increase the clone time as it will wait until virtual machine boots into the OS and an IP Address has been assigned to the given NIC. - - - -Troubleshooting ---------------- - -Things to inspect: - -- Check if the values provided for username and password are correct. -- Check if the datacenter you provided is available. -- Check if the template specified exists and you have permissions to access the datastore. -- Ensure the full folder path you specified already exists. It will not create folders automatically for you. - diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_find_vm_folder.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_find_vm_folder.rst deleted file mode 100644 index fccd47e26..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_find_vm_folder.rst +++ /dev/null @@ -1,121 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_guest_find_folder: - -****************************************************** -Find folder path of an existing VMware virtual machine -****************************************************** - -.. contents:: - :local: - -Introduction -============ - -This guide will show you how to utilize Ansible to find folder path of an existing VMware virtual machine. - -Scenario requirements -===================== - -* Software - - * Ansible 2.5 or later must be installed. - - * The Python module ``Pyvmomi`` must be installed on the Ansible control node (or Target host if not executing against localhost). - - * We recommend installing the latest version with pip: ``pip install Pyvmomi`` (as the OS packages are usually out of date and incompatible). - -* Hardware - - * At least one standalone ESXi server or - - * vCenter Server with at least one ESXi server - -* Access / Credentials - - * Ansible (or the target server) must have network access to the either vCenter server or the ESXi server - - * Username and Password for vCenter or ESXi server - -Caveats -======= - -- All variable names and VMware object names are case sensitive. -- You need to use Python 2.7.9 version in order to use ``validate_certs`` option, as this version is capable of changing the SSL verification behaviours. - - -Example description -=================== - -With the following Ansible playbook you can find the folder path of an existing virtual machine using name. - -.. code-block:: yaml - - --- - - name: Find folder path of an existing virtual machine - hosts: localhost - gather_facts: False - vars_files: - - vcenter_vars.yml - vars: - ansible_python_interpreter: "/usr/bin/env python3" - tasks: - - set_fact: - vm_name: "DC0_H0_VM0" - - - name: "Find folder for VM - {{ vm_name }}" - vmware_guest_find: - hostname: "{{ vcenter_server }}" - username: "{{ vcenter_user }}" - password: "{{ vcenter_pass }}" - validate_certs: False - name: "{{ vm_name }}" - delegate_to: localhost - register: vm_facts - - -Since Ansible utilizes the VMware API to perform actions, in this use case it will be connecting directly to the API from localhost. - -This means that playbooks will not be running from the vCenter or ESXi Server. - -Note that this play disables the ``gather_facts`` parameter, since you don't want to collect facts about localhost. - -You can run these modules against another server that would then connect to the API if localhost does not have access to vCenter. If so, the required Python modules will need to be installed on that target server. We recommend installing the latest version with pip: ``pip install Pyvmomi`` (as the OS packages are usually out of date and incompatible). - -Before you begin, make sure you have: - -- Hostname of the ESXi server or vCenter server -- Username and password for the ESXi or vCenter server -- Name of the existing Virtual Machine for which you want to collect folder path - -For now, you will be entering these directly, but in a more advanced playbook this can be abstracted out and stored in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_. - -If your vCenter or ESXi server is not setup with proper CA certificates that can be verified from the Ansible server, then it is necessary to disable validation of these certificates by using the ``validate_certs`` parameter. To do this you need to set ``validate_certs=False`` in your playbook. - -The name of existing virtual machine will be used as input for ``vmware_guest_find`` module via ``name`` parameter. - - -What to expect --------------- - -Running this playbook can take some time, depending on your environment and network connectivity. When the run is complete you will see - -.. code-block:: yaml - - "vm_facts": { - "changed": false, - "failed": false, - ... - "folders": [ - "/F0/DC0/vm/F0" - ] - } - - -Troubleshooting ---------------- - -If your playbook fails: - -- Check if the values provided for username and password are correct. -- Check if the datacenter you provided is available. -- Check if the virtual machine specified exists and you have respective permissions to access VMware object. -- Ensure the full folder path you specified already exists. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_remove_vm.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_remove_vm.rst deleted file mode 100644 index 59b2bf974..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_remove_vm.rst +++ /dev/null @@ -1,127 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_guest_remove_virtual_machine: - -***************************************** -Remove an existing VMware virtual machine -***************************************** - -.. contents:: - :local: - -Introduction -============ - -This guide will show you how to utilize Ansible to remove an existing VMware virtual machine. - -Scenario requirements -===================== - -* Software - - * Ansible 2.5 or later must be installed. - - * The Python module ``Pyvmomi`` must be installed on the Ansible control node (or Target host if not executing against localhost). - - * We recommend installing the latest version with pip: ``pip install Pyvmomi`` (as the OS packages are usually out of date and incompatible). - -* Hardware - - * At least one standalone ESXi server or - - * vCenter Server with at least one ESXi server - -* Access / Credentials - - * Ansible (or the target server) must have network access to the either vCenter server or the ESXi server - - * Username and Password for vCenter or ESXi server - - * Hosts in the ESXi cluster must have access to the datastore that the template resides on. - -Caveats -======= - -- All variable names and VMware object names are case sensitive. -- You need to use Python 2.7.9 version in order to use ``validate_certs`` option, as this version is capable of changing the SSL verification behaviours. -- ``vmware_guest`` module tries to mimic VMware Web UI and workflow, so the virtual machine must be in powered off state in order to remove it from the VMware inventory. - -.. warning:: - - The removal VMware virtual machine using ``vmware_guest`` module is destructive operation and can not be reverted, so it is strongly recommended to take the backup of virtual machine and related files (vmx and vmdk files) before proceeding. - -Example description -=================== - -In this use case / example, user will be removing a virtual machine using name. The following Ansible playbook showcases the basic parameters that are needed for this. - -.. code-block:: yaml - - --- - - name: Remove virtual machine - gather_facts: no - vars_files: - - vcenter_vars.yml - vars: - ansible_python_interpreter: "/usr/bin/env python3" - hosts: localhost - tasks: - - set_fact: - vm_name: "VM_0003" - datacenter: "DC1" - - - name: Remove "{{ vm_name }}" - vmware_guest: - hostname: "{{ vcenter_server }}" - username: "{{ vcenter_user }}" - password: "{{ vcenter_pass }}" - validate_certs: no - cluster: "DC1_C1" - name: "{{ vm_name }}" - state: absent - delegate_to: localhost - register: facts - - -Since Ansible utilizes the VMware API to perform actions, in this use case it will be connecting directly to the API from localhost. - -This means that playbooks will not be running from the vCenter or ESXi Server. - -Note that this play disables the ``gather_facts`` parameter, since you don't want to collect facts about localhost. - -You can run these modules against another server that would then connect to the API if localhost does not have access to vCenter. If so, the required Python modules will need to be installed on that target server. We recommend installing the latest version with pip: ``pip install Pyvmomi`` (as the OS packages are usually out of date and incompatible). - -Before you begin, make sure you have: - -- Hostname of the ESXi server or vCenter server -- Username and password for the ESXi or vCenter server -- Name of the existing Virtual Machine you want to remove - -For now, you will be entering these directly, but in a more advanced playbook this can be abstracted out and stored in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_. - -If your vCenter or ESXi server is not setup with proper CA certificates that can be verified from the Ansible server, then it is necessary to disable validation of these certificates by using the ``validate_certs`` parameter. To do this you need to set ``validate_certs=False`` in your playbook. - -The name of existing virtual machine will be used as input for ``vmware_guest`` module via ``name`` parameter. - - -What to expect --------------- - -- You will not see any JSON output after this playbook completes as compared to other operations performed using ``vmware_guest`` module. - -.. code-block:: yaml - - { - "changed": true - } - -- State is changed to ``True`` which notifies that the virtual machine is removed from the VMware inventory. This can take some time depending upon your environment and network connectivity. - - -Troubleshooting ---------------- - -If your playbook fails: - -- Check if the values provided for username and password are correct. -- Check if the datacenter you provided is available. -- Check if the virtual machine specified exists and you have permissions to access the datastore. -- Ensure the full folder path you specified already exists. It will not create folders automatically for you. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_rename_vm.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_rename_vm.rst deleted file mode 100644 index 5d72d6aea..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_rename_vm.rst +++ /dev/null @@ -1,174 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_guest_rename_virtual_machine: - -********************************** -Rename an existing virtual machine -********************************** - -.. contents:: - :local: - -Introduction -============ - -This guide will show you how to utilize Ansible to rename an existing virtual machine. - -Scenario requirements -===================== - -* Software - - * Ansible 2.5 or later must be installed. - - * The Python module ``Pyvmomi`` must be installed on the Ansible control node (or Target host if not executing against localhost). - - * We recommend installing the latest version with pip: ``pip install Pyvmomi`` (as the OS packages are usually out of date and incompatible). - -* Hardware - - * At least one standalone ESXi server or - - * vCenter Server with at least one ESXi server - -* Access / Credentials - - * Ansible (or the target server) must have network access to the either vCenter server or the ESXi server - - * Username and Password for vCenter or ESXi server - - * Hosts in the ESXi cluster must have access to the datastore that the template resides on. - -Caveats -======= - -- All variable names and VMware object names are case sensitive. -- You need to use Python 2.7.9 version in order to use ``validate_certs`` option, as this version is capable of changing the SSL verification behaviours. - - -Example description -=================== - -With the following Ansible playbook you can rename an existing virtual machine by changing the UUID. - -.. code-block:: yaml - - --- - - name: Rename virtual machine from old name to new name using UUID - gather_facts: no - vars_files: - - vcenter_vars.yml - vars: - ansible_python_interpreter: "/usr/bin/env python3" - hosts: localhost - tasks: - - set_fact: - vm_name: "old_vm_name" - new_vm_name: "new_vm_name" - datacenter: "DC1" - cluster_name: "DC1_C1" - - - name: Get VM "{{ vm_name }}" uuid - vmware_guest_facts: - hostname: "{{ vcenter_server }}" - username: "{{ vcenter_user }}" - password: "{{ vcenter_pass }}" - validate_certs: False - datacenter: "{{ datacenter }}" - folder: "/{{datacenter}}/vm" - name: "{{ vm_name }}" - register: vm_facts - - - name: Rename "{{ vm_name }}" to "{{ new_vm_name }}" - vmware_guest: - hostname: "{{ vcenter_server }}" - username: "{{ vcenter_user }}" - password: "{{ vcenter_pass }}" - validate_certs: False - cluster: "{{ cluster_name }}" - uuid: "{{ vm_facts.instance.hw_product_uuid }}" - name: "{{ new_vm_name }}" - -Since Ansible utilizes the VMware API to perform actions, in this use case it will be connecting directly to the API from localhost. - -This means that playbooks will not be running from the vCenter or ESXi Server. - -Note that this play disables the ``gather_facts`` parameter, since you don't want to collect facts about localhost. - -You can run these modules against another server that would then connect to the API if localhost does not have access to vCenter. If so, the required Python modules will need to be installed on that target server. We recommend installing the latest version with pip: ``pip install Pyvmomi`` (as the OS packages are usually out of date and incompatible). - -Before you begin, make sure you have: - -- Hostname of the ESXi server or vCenter server -- Username and password for the ESXi or vCenter server -- The UUID of the existing Virtual Machine you want to rename - -For now, you will be entering these directly, but in a more advanced playbook this can be abstracted out and stored in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_. - -If your vCenter or ESXi server is not setup with proper CA certificates that can be verified from the Ansible server, then it is necessary to disable validation of these certificates by using the ``validate_certs`` parameter. To do this you need to set ``validate_certs=False`` in your playbook. - -Now you need to supply the information about the existing virtual machine which will be renamed. For renaming virtual machine, ``vmware_guest`` module uses VMware UUID, which is unique across vCenter environment. This value is autogenerated and can not be changed. You will use ``vmware_guest_facts`` module to find virtual machine and get information about VMware UUID of the virtual machine. - -This value will be used input for ``vmware_guest`` module. Specify new name to virtual machine which conforms to all VMware requirements for naming conventions as ``name`` parameter. Also, provide ``uuid`` as the value of VMware UUID. - -What to expect --------------- - -Running this playbook can take some time, depending on your environment and network connectivity. When the run is complete you will see - -.. code-block:: yaml - - { - "changed": true, - "instance": { - "annotation": "", - "current_snapshot": null, - "customvalues": {}, - "guest_consolidation_needed": false, - "guest_question": null, - "guest_tools_status": "guestToolsNotRunning", - "guest_tools_version": "10247", - "hw_cores_per_socket": 1, - "hw_datastores": ["ds_204_2"], - "hw_esxi_host": "10.x.x.x", - "hw_eth0": { - "addresstype": "assigned", - "ipaddresses": [], - "label": "Network adapter 1", - "macaddress": "00:50:56:8c:b8:42", - "macaddress_dash": "00-50-56-8c-b8-42", - "portgroup_key": "dvportgroup-31", - "portgroup_portkey": "15", - "summary": "DVSwitch: 50 0c 3a 69 df 78 2c 7b-6e 08 0a 89 e3 a6 31 17" - }, - "hw_files": ["[ds_204_2] old_vm_name/old_vm_name.vmx", "[ds_204_2] old_vm_name/old_vm_name.nvram", "[ds_204_2] old_vm_name/old_vm_name.vmsd", "[ds_204_2] old_vm_name/vmware.log", "[ds_204_2] old_vm_name/old_vm_name.vmdk"], - "hw_folder": "/DC1/vm", - "hw_guest_full_name": null, - "hw_guest_ha_state": null, - "hw_guest_id": null, - "hw_interfaces": ["eth0"], - "hw_is_template": false, - "hw_memtotal_mb": 1024, - "hw_name": "new_vm_name", - "hw_power_status": "poweredOff", - "hw_processor_count": 1, - "hw_product_uuid": "420cbebb-835b-980b-7050-8aea9b7b0a6d", - "hw_version": "vmx-13", - "instance_uuid": "500c60a6-b7b4-8ae5-970f-054905246a6f", - "ipv4": null, - "ipv6": null, - "module_hw": true, - "snapshots": [] - } - } - -confirming that you've renamed the virtual machine. - - -Troubleshooting ---------------- - -If your playbook fails: - -- Check if the values provided for username and password are correct. -- Check if the datacenter you provided is available. -- Check if the virtual machine specified exists and you have permissions to access the datastore. -- Ensure the full folder path you specified already exists. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_vmware_http.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_vmware_http.rst deleted file mode 100644 index a831114d3..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_vmware_http.rst +++ /dev/null @@ -1,162 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_http_api_usage: - -*********************************** -Using VMware HTTP API using Ansible -*********************************** - -.. contents:: - :local: - -Introduction -============ - -This guide will show you how to utilize Ansible to use VMware HTTP APIs to automate various tasks. - -Scenario requirements -===================== - -* Software - - * Ansible 2.5 or later must be installed. - - * We recommend installing the latest version with pip: ``pip install Pyvmomi`` on the Ansible control node - (as the OS packages are usually out of date and incompatible) if you are planning to use any existing VMware modules. - -* Hardware - - * vCenter Server 6.5 and above with at least one ESXi server - -* Access / Credentials - - * Ansible (or the target server) must have network access to either the vCenter server or the ESXi server - - * Username and Password for vCenter - -Caveats -======= - -- All variable names and VMware object names are case sensitive. -- You need to use Python 2.7.9 version in order to use ``validate_certs`` option, as this version is capable of changing the SSL verification behaviours. -- VMware HTTP APIs are introduced in vSphere 6.5 and above so minimum level required in 6.5. -- There are very limited number of APIs exposed, so you may need to rely on XMLRPC based VMware modules. - - -Example description -=================== - -With the following Ansible playbook you can find the VMware ESXi host system(s) and can perform various tasks depending on the list of host systems. -This is a generic example to show how Ansible can be utilized to consume VMware HTTP APIs. - -.. code-block:: yaml - - --- - - name: Example showing VMware HTTP API utilization - hosts: localhost - gather_facts: no - vars_files: - - vcenter_vars.yml - vars: - ansible_python_interpreter: "/usr/bin/env python3" - tasks: - - name: Login into vCenter and get cookies - uri: - url: https://{{ vcenter_server }}/rest/com/vmware/cis/session - force_basic_auth: yes - validate_certs: no - method: POST - user: "{{ vcenter_user }}" - password: "{{ vcenter_pass }}" - register: login - - - name: Get all hosts from vCenter using cookies from last task - uri: - url: https://{{ vcenter_server }}/rest/vcenter/host - force_basic_auth: yes - validate_certs: no - headers: - Cookie: "{{ login.set_cookie }}" - register: vchosts - - - name: Change Log level configuration of the given hostsystem - vmware_host_config_manager: - hostname: "{{ vcenter_server }}" - username: "{{ vcenter_user }}" - password: "{{ vcenter_pass }}" - esxi_hostname: "{{ item.name }}" - options: - 'Config.HostAgent.log.level': 'error' - validate_certs: no - loop: "{{ vchosts.json.value }}" - register: host_config_results - - -Since Ansible utilizes the VMware HTTP API using the ``uri`` module to perform actions, in this use case it will be connecting directly to the VMware HTTP API from localhost. - -This means that playbooks will not be running from the vCenter or ESXi Server. - -Note that this play disables the ``gather_facts`` parameter, since you don't want to collect facts about localhost. - -Before you begin, make sure you have: - -- Hostname of the vCenter server -- Username and password for the vCenter server -- Version of vCenter is at least 6.5 - -For now, you will be entering these directly, but in a more advanced playbook this can be abstracted out and stored in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_. - -If your vCenter server is not setup with proper CA certificates that can be verified from the Ansible server, then it is necessary to disable validation of these certificates by using the ``validate_certs`` parameter. To do this you need to set ``validate_certs=False`` in your playbook. - -As you can see, we are using the ``uri`` module in first task to login into the vCenter server and storing result in the ``login`` variable using register. In the second task, using cookies from the first task we are gathering information about the ESXi host system. - -Using this information, we are changing the ESXi host system's advance configuration. - -What to expect --------------- - -Running this playbook can take some time, depending on your environment and network connectivity. When the run is complete you will see - -.. code-block:: yaml - - "results": [ - { - ... - "invocation": { - "module_args": { - "cluster_name": null, - "esxi_hostname": "10.76.33.226", - "hostname": "10.65.223.114", - "options": { - "Config.HostAgent.log.level": "error" - }, - "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", - "port": 443, - "username": "administrator@vsphere.local", - "validate_certs": false - } - }, - "item": { - "connection_state": "CONNECTED", - "host": "host-21", - "name": "10.76.33.226", - "power_state": "POWERED_ON" - }, - "msg": "Config.HostAgent.log.level changed." - ... - } - ] - - -Troubleshooting ---------------- - -If your playbook fails: - -- Check if the values provided for username and password are correct. -- Check if you are using vCenter 6.5 and onwards to use this HTTP APIs. - -.. seealso:: - - `VMware vSphere and Ansible From Zero to Useful by @arielsanchezmor <https://www.youtube.com/watch?v=0_qwOKlBlo8>`_ - vBrownBag session video related to VMware HTTP APIs - `Sample Playbooks for using VMware HTTP APIs <https://github.com/Akasurde/ansible-vmware-http>`_ - GitHub repo for examples of Ansible playbook to manage VMware using HTTP APIs diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_vmware_tools_connection.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_vmware_tools_connection.rst deleted file mode 100644 index 08a4df114..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/scenario_vmware_tools_connection.rst +++ /dev/null @@ -1,120 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_tools_connection: - -************************************ -Using vmware_tools connection plugin -************************************ - -.. contents:: - :local: - -Introduction -============ - -This guide will show you how to utilize VMware Connection plugin to communicate and automate various tasks on VMware guest machines. - -Scenario requirements -===================== - -* Software - - * Ansible 2.9 or later must be installed. - - * We recommend installing the latest version with pip: ``pip install Pyvmomi`` on the Ansible control node - (as the OS packages are usually out of date and incompatible) if you are planning to use any existing VMware modules. - -* Hardware - - * vCenter Server 6.5 and above - -* Access / Credentials - - * Ansible (or the target server) must have network access to either the vCenter server - - * Username and Password for vCenter with required permissions - - * VMware tools or openvm-tools with required dependencies like Perl installed on the given virtual machine - -Caveats -======= - -- All variable names and VMware object names are case sensitive. -- You need to use Python 2.7.9 version in order to use ``validate_certs`` option, as this version is capable of changing the SSL verification behaviors. - - -Example description -=================== - -User can run playbooks against VMware virtual machines using ``vmware_tools`` connection plugin. - -In order work with ``vmware_tools`` connection plugin, you will need to specify hostvars for the given virtual machine. - -For example, if you want to run a playbook on a virtual machine called ``centos_7`` located at ``/Asia-Datacenter1/prod/centos_7`` in the given vCenter, you will need to specify hostvars as follows: - -.. code-block:: ini - - [centos7] - host1 - - [centos7:vars] - # vmware_tools related variables - ansible_connection=vmware_tools - ansible_vmware_host=10.65.201.128 - ansible_vmware_user=administrator@vsphere.local - ansible_vmware_password=Esxi@123$% - ansible_vmware_validate_certs=no - - # Location of the virtual machine - ansible_vmware_guest_path=Asia-Datacenter1/vm/prod/centos_7 - - # Credentials - ansible_vmware_tools_user=root - ansible_vmware_tools_password=Secret123 - -Here, we are providing vCenter details and credentials for the given virtual machine to run the playbook on. -If your virtual machine path is ``Asia-Datacenter1/prod/centos_7``, you specify ``ansible_vmware_guest_path`` as ``Asia-Datacenter1/vm/prod/centos_7``. Please take a note that ``/vm`` is added in the virtual machine path, since this is a logical folder structure in the VMware inventory. - -Let us now run following playbook, - -.. code-block:: yaml - - --- - - name: Example showing VMware Connection plugin - hosts: centos7 - tasks: - - name: Gather information about temporary directory inside VM - shell: ls /tmp - - -Since Ansible utilizes the ``vmware-tools`` or ``openvm-tools`` service capabilities running in the virtual machine to perform actions, in this use case it will be connecting directly to the guest machine. - - -For now, you will be entering credentials in plain text, but in a more advanced playbook this can be abstracted out and stored in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_. - - -What to expect --------------- - -Running this playbook can take some time, depending on your environment and network connectivity. When the run is complete you will see: - -.. code-block:: yaml - - { - "changed": true, - "cmd": "ls /tmp", - "delta": "0:00:00.005440", - "end": "2020-10-01 07:30:56.940813", - "rc": 0, - "start": "2020-10-01 07:30:56.935373", - "stderr": "", - "stderr_lines": [], - "stdout": "ansible_command_payload_JzWiL9\niso", - "stdout_lines": ["ansible_command_payload_JzWiL9", "iso", "vmware-root"] - } - -Troubleshooting ---------------- - -If your playbook fails: - -- Check if the values provided for username and password are correct. -- Check if the path of virtual machine is correct. Please mind that ``/vm/`` needs to be provided while specifying virtual machine location. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_concepts.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_concepts.rst deleted file mode 100644 index 2829624ac..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_concepts.rst +++ /dev/null @@ -1,45 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_concepts: - -*************************** -Ansible for VMware Concepts -*************************** - -Some of these concepts are common to all uses of Ansible, including VMware automation; some are specific to VMware. You need to understand them to use Ansible for VMware automation. This introduction provides the background you need to follow the :ref:`scenarios<vmware_scenarios>` in this guide. - -.. contents:: - :local: - -Control Node -============ - -Any machine with Ansible installed. You can run commands and playbooks, invoking ``/usr/bin/ansible`` or ``/usr/bin/ansible-playbook``, from any control node. You can use any computer that has Python installed on it as a control node - laptops, shared desktops, and servers can all run Ansible. However, you cannot use a Windows machine as a control node. You can have multiple control nodes. - -Delegation -========== - -Delegation allows you to select the system that executes a given task. If you do not have ``pyVmomi`` installed on your control node, use the ``delegate_to`` keyword on VMware-specific tasks to execute them on any host where you have ``pyVmomi`` installed. - -Modules -======= - -The units of code Ansible executes. Each module has a particular use, from creating virtual machines on vCenter to managing distributed virtual switches in the vCenter environment. You can invoke a single module with a task, or invoke several different modules in a playbook. - -Playbooks -========= - -Ordered lists of tasks, saved so you can run those tasks in that order repeatedly. Playbooks can include variables as well as tasks. Playbooks are written in YAML and are easy to read, write, share and understand. - -pyVmomi -======= - -Ansible VMware modules are written on top of `pyVmomi <https://github.com/vmware/pyvmomi>`_. ``pyVmomi`` is the official Python SDK for the VMware vSphere API that allows user to manage ESX, ESXi, and vCenter infrastructure. - -You need to install this Python SDK on host from where you want to invoke VMware automation. For example, if you are using control node then ``pyVmomi`` must be installed on control node. - -If you are using any ``delegate_to`` host which is different from your control node then you need to install ``pyVmomi`` on that ``delegate_to`` node. - -You can install pyVmomi using pip: - -.. code-block:: bash - - $ pip install pyvmomi diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_external_doc_links.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_external_doc_links.rst deleted file mode 100644 index afd2275e9..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_external_doc_links.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_external_doc_links: - -***************************** -Other useful VMware resources -***************************** - -* `VMware API and SDK Documentation <https://www.vmware.com/support/pubs/sdk_pubs.html>`_ -* `Ansible VMware community wiki page <https://github.com/ansible/community/wiki/VMware>`_ -* `VMware's official Guest Operating system customization matrix <https://partnerweb.vmware.com/programs/guestOS/guest-os-customization-matrix.pdf>`_ -* `VMware Compatibility Guide <https://www.vmware.com/resources/compatibility/search.php>`_ diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_getting_started.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_getting_started.rst deleted file mode 100644 index 1b2d34a8f..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_getting_started.rst +++ /dev/null @@ -1,9 +0,0 @@ -:orphan: - -.. _ansible_collections.community.vmware.docsite.vmware_ansible_getting_started: - -*************************************** -Getting Started with Ansible for VMware -*************************************** - -This will have a basic "hello world" scenario/walkthrough that gets the user introduced to the basics. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_intro.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_intro.rst deleted file mode 100644 index ddc1433c6..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_intro.rst +++ /dev/null @@ -1,54 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_ansible_intro: - -********************************** -Introduction to Ansible for VMware -********************************** - -.. contents:: - :local: - -Introduction -============ - -Ansible provides various modules to manage VMware infrastructure, which includes datacenter, cluster, -host system and virtual machine. - -Requirements -============ - -Ansible VMware modules are written on top of `pyVmomi <https://github.com/vmware/pyvmomi>`_. -pyVmomi is the Python SDK for the VMware vSphere API that allows user to manage ESX, ESXi, -and vCenter infrastructure. You can install pyVmomi using pip (you may need to use pip3, depending on your OS/distro): - -.. code-block:: bash - - $ pip install pyvmomi - -Ansible VMware modules leveraging latest vSphere(6.0+) features are using `vSphere Automation Python SDK <https://github.com/vmware/vsphere-automation-sdk-python>`_. The vSphere Automation Python SDK also has client libraries, documentation, and sample code for VMware Cloud on AWS Console APIs, NSX VMware Cloud on AWS integration APIs, VMware Cloud on AWS site recovery APIs, NSX-T APIs. - -You can install vSphere Automation Python SDK using pip: - -.. code-block:: bash - - $ pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git - -Note: - Installing vSphere Automation Python SDK also installs ``pyvmomi``. A separate installation of ``pyvmomi`` is not required. - -vmware_guest module -=================== - -The :ref:`vmware_guest<ansible_collections.community.vmware.vmware_guest_module>` module manages various operations related to virtual machines in the given ESXi or vCenter server. - - -.. seealso:: - - `pyVmomi <https://github.com/vmware/pyvmomi>`_ - The GitHub Page of pyVmomi - `pyVmomi Issue Tracker <https://github.com/vmware/pyvmomi/issues>`_ - The issue tracker for the pyVmomi project - `govc <https://github.com/vmware/govmomi/tree/master/govc>`_ - govc is a vSphere CLI built on top of govmomi - :ref:`working_with_playbooks` - An introduction to playbooks - diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory.rst deleted file mode 100644 index becd718aa..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory.rst +++ /dev/null @@ -1,91 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_ansible_inventory: - -************************************* -Using VMware dynamic inventory plugin -************************************* - -.. contents:: - :local: - -VMware Dynamic Inventory Plugin -=============================== - - -The best way to interact with your hosts is to use the VMware dynamic inventory plugin, which dynamically queries VMware APIs and -tells Ansible what nodes can be managed. - -Requirements ------------- - -To use the VMware dynamic inventory plugins, you must install `pyVmomi <https://github.com/vmware/pyvmomi>`_ -on your control node (the host running Ansible). - -To include tag-related information for the virtual machines in your dynamic inventory, you also need the `vSphere Automation SDK <https://code.vmware.com/web/sdk/65/vsphere-automation-python>`_, which supports REST API features like tagging and content libraries, on your control node. -You can install the ``vSphere Automation SDK`` following `these instructions <https://github.com/vmware/vsphere-automation-sdk-python#installing-required-python-packages>`_. - -.. code-block:: bash - - $ pip install pyvmomi - -To use this VMware dynamic inventory plugin, you need to enable it first by specifying the following in the ``ansible.cfg`` file: - -.. code-block:: ini - - [inventory] - enable_plugins = vmware_vm_inventory - -Then, create a file that ends in ``.vmware.yml`` or ``.vmware.yaml`` in your working directory. - -The ``vmware_vm_inventory`` script takes in the same authentication information as any VMware module. - -Here's an example of a valid inventory file: - -.. code-block:: yaml - - plugin: vmware_vm_inventory - strict: False - hostname: 10.65.223.31 - username: administrator@vsphere.local - password: Esxi@123$% - validate_certs: False - with_tags: True - - -Executing ``ansible-inventory --list -i <filename>.vmware.yml`` will create a list of VMware instances that are ready to be configured using Ansible. - -Using vaulted configuration files -================================= - -Since the inventory configuration file contains vCenter password in plain text, a security risk, you may want to -encrypt your entire inventory configuration file. - -You can encrypt a valid inventory configuration file as follows: - -.. code-block:: bash - - $ ansible-vault encrypt <filename>.vmware.yml - New Vault password: - Confirm New Vault password: - Encryption successful - -And you can use this vaulted inventory configuration file using: - -.. code-block:: bash - - $ ansible-inventory -i filename.vmware.yml --list --vault-password-file=/path/to/vault_password_file - - -.. seealso:: - - `pyVmomi <https://github.com/vmware/pyvmomi>`_ - The GitHub Page of pyVmomi - `pyVmomi Issue Tracker <https://github.com/vmware/pyvmomi/issues>`_ - The issue tracker for the pyVmomi project - `vSphere Automation SDK GitHub Page <https://github.com/vmware/vsphere-automation-sdk-python>`_ - The GitHub Page of vSphere Automation SDK for Python - `vSphere Automation SDK Issue Tracker <https://github.com/vmware/vsphere-automation-sdk-python/issues>`_ - The issue tracker for vSphere Automation SDK for Python - :ref:`working_with_playbooks` - An introduction to playbooks - :ref:`playbooks_vault` - Using Vault in playbooks diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_filters.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_filters.rst deleted file mode 100644 index eb309cf0e..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_filters.rst +++ /dev/null @@ -1,216 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_ansible_inventory_using_filters: - -*********************************************** -Using VMware dynamic inventory plugin - Filters -*********************************************** - -.. contents:: - :local: - -VMware dynamic inventory plugin - filtering VMware guests -========================================================= - - -VMware inventory plugin allows you to filter VMware guests using the ``filters`` configuration parameter. - -This section shows how you configure ``filters`` for the given VMware guest in the inventory. - -Requirements ------------- - -To use the VMware dynamic inventory plugins, you must install `pyVmomi <https://github.com/vmware/pyvmomi>`_ -on your control node (the host running Ansible). - -To include tag-related information for the virtual machines in your dynamic inventory, you also need the `vSphere Automation SDK <https://code.vmware.com/web/sdk/65/vsphere-automation-python>`_, which supports REST API features such as tagging and content libraries, on your control node. -You can install the ``vSphere Automation SDK`` following `these instructions <https://github.com/vmware/vsphere-automation-sdk-python#installing-required-python-packages>`_. - -.. code-block:: bash - - $ pip install pyvmomi - -Starting in Ansible 2.10, the VMware dynamic inventory plugin is available in the ``community.vmware`` collection included Ansible. -Alternately, to install the latest ``community.vmware`` collection: - -.. code-block:: bash - - $ ansible-galaxy collection install community.vmware - -To use this VMware dynamic inventory plugin: - -1. Enable it first by specifying the following in the ``ansible.cfg`` file: - -.. code-block:: ini - - [inventory] - enable_plugins = community.vmware.vmware_vm_inventory - -2. Create a file that ends in ``vmware.yml`` or ``vmware.yaml`` in your working directory. - -The ``vmware_vm_inventory`` inventory plugin takes in the same authentication information as any other VMware modules does. - -Let us assume we want to list all RHEL7 VMs with the power state as "poweredOn". A valid inventory file with filters for the given VMware guest looks as follows: - -.. code-block:: yaml - - plugin: community.vmware.vmware_vm_inventory - strict: False - hostname: 10.65.223.31 - username: administrator@vsphere.local - password: Esxi@123$% - validate_certs: False - with_tags: False - hostnames: - - config.name - filters: - - config.guestId == "rhel7_64Guest" - - summary.runtime.powerState == "poweredOn" - - -Here, we have configured two filters - - -* ``config.guestId`` is equal to ``rhel7_64Guest`` -* ``summary.runtime.powerState`` is equal to ``poweredOn`` - -This retrieves all the VMs which satisfy these two conditions and populates them in the inventory. -Notice that the conditions are combined using an ``and`` operation. - -Using ``or`` conditions in filters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Let us assume you want filter RHEL7 and Ubuntu VMs. You can use multiple filters using ``or`` condition in your inventory file. - -A valid filter in the VMware inventory file for this example is: - -.. code-block:: yaml - - plugin: community.vmware.vmware_vm_inventory - strict: False - hostname: 10.65.223.31 - username: administrator@vsphere.local - password: Esxi@123$% - validate_certs: False - with_tags: False - hostnames: - - config.name - filters: - - config.guestId == "rhel7_64Guest" or config.guestId == "ubuntu64Guest" - - -You can check all allowed properties for filters for the given virtual machine at :ref:`ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes`. - -If you are using the ``properties`` parameter with custom VM properties, make sure that you include all the properties used by filters as well in your VM property list. - -For example, if we want all RHEL7 and Ubuntu VMs that are poweredOn, you can use inventory file: - -.. code-block:: yaml - - plugin: community.vmware.vmware_vm_inventory - strict: False - hostname: 10.65.223.31 - username: administrator@vsphere.local - password: Esxi@123$% - validate_certs: False - with_tags: False - hostnames: - - 'config.name' - properties: - - 'config.name' - - 'config.guestId' - - 'guest.ipAddress' - - 'summary.runtime.powerState' - filters: - - config.guestId == "rhel7_64Guest" or config.guestId == "ubuntu64Guest" - - summary.runtime.powerState == "poweredOn" - -Here, we are using minimum VM properties, that is ``config.name``, ``config.guestId``, ``summary.runtime.powerState``, and ``guest.ipAddress``. - -* ``config.name`` is used by the ``hostnames`` parameter. -* ``config.guestId`` and ``summary.runtime.powerState`` are used by the ``filters`` parameter. -* ``guest.guestId`` is used by ``ansible_host`` internally by the inventory plugin. - -Using regular expression in filters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Let us assume you want filter VMs with specific IP range. You can use regular expression in ``filters`` in your inventory file. - -For example, if we want all RHEL7 and Ubuntu VMs that are poweredOn, you can use inventory file: - -.. code-block:: yaml - - plugin: community.vmware.vmware_vm_inventory - strict: False - hostname: 10.65.223.31 - username: administrator@vsphere.local - password: Esxi@123$% - validate_certs: False - with_tags: False - hostnames: - - 'config.name' - properties: - - 'config.name' - - 'config.guestId' - - 'guest.ipAddress' - - 'summary.runtime.powerState' - filters: - - guest.ipAddress is defined and guest.ipAddress is match('192.168.*') - -Here, we are using ``guest.ipAddress`` VM property. This property is optional and depended upon VMware tools installed on VMs. -We are using ``match`` to validate the regular expression for the given IP range. - -Executing ``ansible-inventory --list -i <filename>.vmware.yml`` creates a list of the virtual machines that are ready to be configured using Ansible. - -What to expect --------------- - -You will notice that the inventory hosts are filtered depending on your ``filters`` section. - - -.. code-block:: yaml - - { - "_meta": { - "hostvars": { - "template_001": { - "config.name": "template_001", - "config.guestId": "ubuntu64Guest", - ... - "guest.toolsStatus": "toolsNotInstalled", - "summary.runtime.powerState": "poweredOn", - }, - "vm_8046": { - "config.name": "vm_8046", - "config.guestId": "rhel7_64Guest", - ... - "guest.toolsStatus": "toolsNotInstalled", - "summary.runtime.powerState": "poweredOn", - }, - ... - } - -Troubleshooting filters ------------------------ - -If the custom property specified in ``filters`` fails: - -- Check if the values provided for username and password are correct. -- Make sure it is a valid property, see :ref:`ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes`. -- Use ``strict: True`` to get more information about the error. -- Please make sure that you are using latest version of the VMware collection. - - -.. seealso:: - - `pyVmomi <https://github.com/vmware/pyvmomi>`_ - The GitHub Page of pyVmomi - `pyVmomi Issue Tracker <https://github.com/vmware/pyvmomi/issues>`_ - The issue tracker for the pyVmomi project - `vSphere Automation SDK GitHub Page <https://github.com/vmware/vsphere-automation-sdk-python>`_ - The GitHub Page of vSphere Automation SDK for Python - `vSphere Automation SDK Issue Tracker <https://github.com/vmware/vsphere-automation-sdk-python/issues>`_ - The issue tracker for vSphere Automation SDK for Python - :ref:`ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes` - Using Virtual machine attributes in VMware dynamic inventory plugin - :ref:`working_with_playbooks` - An introduction to playbooks - :ref:`playbooks_vault` - Using Vault in playbooks diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_hostnames.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_hostnames.rst deleted file mode 100644 index d89639506..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_hostnames.rst +++ /dev/null @@ -1,128 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_ansible_inventory_using_hostnames: - -************************************************* -Using VMware dynamic inventory plugin - Hostnames -************************************************* - -.. contents:: - :local: - -VMware dynamic inventory plugin - customizing hostnames -======================================================= - - -VMware inventory plugin allows you to configure hostnames using the ``hostnames`` configuration parameter. - -In this scenario guide we will see how you configure hostnames from the given VMware guest in the inventory. - -Requirements ------------- - -To use the VMware dynamic inventory plugins, you must install `pyVmomi <https://github.com/vmware/pyvmomi>`_ -on your control node (the host running Ansible). - -To include tag-related information for the virtual machines in your dynamic inventory, you also need the `vSphere Automation SDK <https://code.vmware.com/web/sdk/65/vsphere-automation-python>`_, which supports REST API features such as tagging and content libraries, on your control node. -You can install the ``vSphere Automation SDK`` following `these instructions <https://github.com/vmware/vsphere-automation-sdk-python#installing-required-python-packages>`_. - -.. code-block:: bash - - $ pip install pyvmomi - -Starting in Ansible 2.10, the VMware dynamic inventory plugin is available in the ``community.vmware`` collection included Ansible. -To install the latest ``community.vmware`` collection: - -.. code-block:: bash - - $ ansible-galaxy collection install community.vmware - -To use this VMware dynamic inventory plugin: - -1. Enable it first by specifying the following in the ``ansible.cfg`` file: - -.. code-block:: ini - - [inventory] - enable_plugins = community.vmware.vmware_vm_inventory - -2. Create a file that ends in ``vmware.yml`` or ``vmware.yaml`` in your working directory. - -The ``vmware_vm_inventory`` inventory plugin takes in the same authentication information as any other VMware modules does. - -Here's an example of a valid inventory file with custom hostname for the given VMware guest: - -.. code-block:: yaml - - plugin: community.vmware.vmware_vm_inventory - strict: False - hostname: 10.65.223.31 - username: administrator@vsphere.local - password: Esxi@123$% - validate_certs: False - with_tags: False - hostnames: - - config.name - - -Here, we have configured a custom hostname by setting the ``hostnames`` parameter to ``config.name``. This will retrieve -the ``config.name`` property from the virtual machine and populate it in the inventory. - -You can check all allowed properties for the given virtual machine at :ref:`ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes`. - -Executing ``ansible-inventory --list -i <filename>.vmware.yml`` creates a list of the virtual machines that are ready to be configured using Ansible. - -What to expect --------------- - -You will notice that instead of default behavior of representing the hostname as ``config.name + _ + config.uuid``, -the inventory hosts show value as ``config.name``. - - -.. code-block:: yaml - - { - "_meta": { - "hostvars": { - "template_001": { - "config.name": "template_001", - "guest.toolsRunningStatus": "guestToolsNotRunning", - ... - "guest.toolsStatus": "toolsNotInstalled", - "name": "template_001" - }, - "vm_8046": { - "config.name": "vm_8046", - "guest.toolsRunningStatus": "guestToolsNotRunning", - ... - "guest.toolsStatus": "toolsNotInstalled", - "name": "vm_8046" - }, - ... - } - -Troubleshooting ---------------- - -If the custom property specified in ``hostnames`` fails: - -- Check if the values provided for username and password are correct. -- Make sure it is a valid property, see :ref:`ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes`. -- Use ``strict: True`` to get more information about the error. -- Please make sure that you are using latest version VMware collection. - - -.. seealso:: - - `pyVmomi <https://github.com/vmware/pyvmomi>`_ - The GitHub Page of pyVmomi - `pyVmomi Issue Tracker <https://github.com/vmware/pyvmomi/issues>`_ - The issue tracker for the pyVmomi project - `vSphere Automation SDK GitHub Page <https://github.com/vmware/vsphere-automation-sdk-python>`_ - The GitHub Page of vSphere Automation SDK for Python - `vSphere Automation SDK Issue Tracker <https://github.com/vmware/vsphere-automation-sdk-python/issues>`_ - The issue tracker for vSphere Automation SDK for Python - :ref:`ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes` - Using Virtual machine attributes in VMware dynamic inventory plugin - :ref:`working_with_playbooks` - An introduction to playbooks - :ref:`playbooks_vault` - Using Vault in playbooks diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_vm_attributes.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_vm_attributes.rst deleted file mode 100644 index eda856ee3..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_inventory_vm_attributes.rst +++ /dev/null @@ -1,1184 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_inventory_vm_attributes: - -******************************************************************* -Using Virtual machine attributes in VMware dynamic inventory plugin -******************************************************************* - -.. contents:: - :local: - -Virtual machine attributes -========================== - -You can use virtual machine properties which can be used to populate ``hostvars`` for the given -virtual machine in a VMware dynamic inventory plugin. - -capability ----------- - -This section describes settings for the runtime capabilities of the virtual machine. - -snapshotOperationsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports snapshot operations. - -multipleSnapshotsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports multiple snapshots. - This value is not set when the virtual machine is unavailable, for instance, when it is being created or deleted. - -snapshotConfigSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports snapshot config. - -poweredOffSnapshotsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports snapshot operations in ``poweredOff`` state. - -memorySnapshotsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports memory snapshots. - -revertToSnapshotSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports reverting to a snapshot. - -quiescedSnapshotsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports quiesced snapshots. - -disableSnapshotsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not snapshots can be disabled. - -lockSnapshotsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not the snapshot tree can be locked. - -consolePreferencesSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether console preferences can be set for the virtual machine. - -cpuFeatureMaskSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether CPU feature requirements masks can be set for the virtual machine. - -s1AcpiManagementSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not a virtual machine supports ACPI S1 settings management. - -settingScreenResolutionSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not the virtual machine supports setting the screen resolution of the console window. - -toolsAutoUpdateSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Supports tools auto-update. - -vmNpivWwnSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^ - - Supports virtual machine NPIV WWN. - -npivWwnOnNonRdmVmSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Supports assigning NPIV WWN to virtual machines that do not have RDM disks. - -vmNpivWwnDisableSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the NPIV disabling operation is supported on the virtual machine. - -vmNpivWwnUpdateSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the update of NPIV WWNs are supported on the virtual machine. - -swapPlacementSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Flag indicating whether the virtual machine has a configurable (swapfile placement policy). - -toolsSyncTimeSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether asking tools to sync time with the host is supported. - -virtualMmuUsageSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not the use of nested page table hardware support can be explicitly set. - -diskSharesSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether resource settings for disks can be applied to the virtual machine. - -bootOptionsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether boot options can be configured for the virtual machine. - -bootRetryOptionsSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether automatic boot retry can be configured for the virtual machine. - -settingVideoRamSizeSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Flag indicating whether the video RAM size of the virtual machine can be configured. - -settingDisplayTopologySupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not the virtual machine supports setting the display topology of the console window. - -recordReplaySupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether record and replay functionality is supported on the virtual machine. - -changeTrackingSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates that change tracking is supported for virtual disks of the virtual machine. - However, even if change tracking is supported, it might not be available for all disks of the virtual machine. - For example, passthru raw disk mappings or disks backed by any Ver1BackingInfo cannot be tracked. - -multipleCoresPerSocketSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether multiple virtual cores per socket is supported on the virtual machine. - -hostBasedReplicationSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates that host based replication is supported on the virtual machine. - However, even if host based replication is supported, it might not be available for all disk types. - For example, passthru raw disk mappings can not be replicated. - -guestAutoLockSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not guest autolock is supported on the virtual machine. - -memoryReservationLockSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether :ref:`ansible_collections.community.vmware.docsite.memory_reservation_locked_to_max` may be set to true for the virtual machine. - -featureRequirementSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the featureRequirement feature is supported. - -poweredOnMonitorTypeChangeSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether a monitor type change is supported while the virtual machine is in the ``poweredOn`` state. - -seSparseDiskSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the virtual machine supports the Flex-SE (space-efficent, sparse) format for virtual disks. - -nestedHVSupported (bool) -^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the virtual machine supports nested hardware-assisted virtualization. - -vPMCSupported (bool) -^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the virtual machine supports virtualized CPU performance counters. - - -config ------- - -This section describes the configuration settings of the virtual machine, including the name and UUID. -This property is set when a virtual machine is created or when the ``reconfigVM`` method is called. -The virtual machine configuration is not guaranteed to be available. -For example, the configuration information would be unavailable if the server is unable to access the virtual machine files on disk, and is often also unavailable during the initial phases of virtual machine creation. - -changeVersion (str) -^^^^^^^^^^^^^^^^^^^ - - The changeVersion is a unique identifier for a given version of the configuration. - Each change to the configuration updates this value. This is typically implemented as an ever increasing count or a time-stamp. - However, a client should always treat this as an opaque string. - -modified (datetime) -^^^^^^^^^^^^^^^^^^^ - - Last time a virtual machine's configuration was modified. - -name (str) -^^^^^^^^^^ - - Display name of the virtual machine. Any / (slash), \ (backslash), character used in this name element is escaped. Similarly, any % (percent) character used in this name element is escaped, unless it is used to start an escape sequence. A slash is escaped as %2F or %2f. A backslash is escaped as %5C or %5c, and a percent is escaped as %25. - -.. _ansible_collections.community.vmware.docsite.guest_full_name: - -guestFullName (str) -^^^^^^^^^^^^^^^^^^^ - - This is the full name of the guest operating system for the virtual machine. For example: Windows 2000 Professional. See :ref:`ansible_collections.community.vmware.docsite.alternate_guest_name`. - -version (str) -^^^^^^^^^^^^^ - - The version string for the virtual machine. - -uuid (str) -^^^^^^^^^^ - - 128-bit SMBIOS UUID of a virtual machine represented as a hexadecimal string in "12345678-abcd-1234-cdef-123456789abc" format. - -instanceUuid (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - VirtualCenter-specific 128-bit UUID of a virtual machine, represented as a hexademical string. This identifier is used by VirtualCenter to uniquely identify all virtual machine instances, including those that may share the same SMBIOS UUID. - -npivNodeWorldWideName (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A 64-bit node WWN (World Wide Name). - -npivPortWorldWideName (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A 64-bit port WWN (World Wide Name). - -npivWorldWideNameType (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The source that provides/generates the assigned WWNs. - -npivDesiredNodeWwns (short, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The NPIV node WWNs to be extended from the original list of WWN numbers. - -npivDesiredPortWwns (short, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The NPIV port WWNs to be extended from the original list of WWN numbers. - -npivTemporaryDisabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - This property is used to enable or disable the NPIV capability on a desired virtual machine on a temporary basis. - -npivOnNonRdmDisks (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - This property is used to check whether the NPIV can be enabled on the Virtual machine with non-rdm disks in the configuration, so this is potentially not enabling npiv on vmfs disks. - Also this property is used to check whether RDM is required to generate WWNs for a virtual machine. - -locationId (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Hash incorporating the virtual machine's config file location and the UUID of the host assigned to run the virtual machine. - -template (bool) -^^^^^^^^^^^^^^^ - - Flag indicating whether or not a virtual machine is a template. - -guestId (str) -^^^^^^^^^^^^^ - - Guest operating system configured on a virtual machine. - -.. _ansible_collections.community.vmware.docsite.alternate_guest_name: - -alternateGuestName (str) -^^^^^^^^^^^^^^^^^^^^^^^^ - - Used as display name for the operating system if guestId isotherorother-64. See :ref:`ansible_collections.community.vmware.docsite.guest_full_name`. - -annotation (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Description for the virtual machine. - -files (vim.vm.FileInfo) -^^^^^^^^^^^^^^^^^^^^^^^ - - Information about the files associated with a virtual machine. - This information does not include files for specific virtual disks or snapshots. - -tools (vim.vm.ToolsConfigInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Configuration of VMware Tools running in the guest operating system. - -flags (vim.vm.FlagInfo) -^^^^^^^^^^^^^^^^^^^^^^^ - - Additional flags for a virtual machine. - -consolePreferences (vim.vm.ConsolePreferences, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Legacy console viewer preferences when doing power operations. - -defaultPowerOps (vim.vm.DefaultPowerOpInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Configuration of default power operations. - -hardware (vim.vm.VirtualHardware) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Processor, memory, and virtual devices for a virtual machine. - -cpuAllocation (vim.ResourceAllocationInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Resource limits for CPU. - -memoryAllocation (vim.ResourceAllocationInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Resource limits for memory. - -latencySensitivity (vim.LatencySensitivity, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The latency-sensitivity of the virtual machine. - -memoryHotAddEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Whether memory can be added while the virtual machine is running. - -cpuHotAddEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Whether virtual processors can be added while the virtual machine is running. - -cpuHotRemoveEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Whether virtual processors can be removed while the virtual machine is running. - -hotPlugMemoryLimit (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The maximum amount of memory, in MB, than can be added to a running virtual machine. - -hotPlugMemoryIncrementSize (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Memory, in MB that can be added to a running virtual machine. - -cpuAffinity (vim.vm.AffinityInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Affinity settings for CPU. - -memoryAffinity (vim.vm.AffinityInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Affinity settings for memory. - -networkShaper (vim.vm.NetworkShaperInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Resource limits for network. - -extraConfig (vim.option.OptionValue, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Additional configuration information for the virtual machine. - -cpuFeatureMask (vim.host.CpuIdInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Specifies CPU feature compatibility masks that override the defaults from the ``GuestOsDescriptor`` of the virtual machine's guest OS. - -datastoreUrl (vim.vm.ConfigInfo.DatastoreUrlPair, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Enumerates the set of datastores that the virtual machine is stored on, as well as the URL identification for each of these. - -swapPlacement (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Virtual machine swapfile placement policy. - -bootOptions (vim.vm.BootOptions, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Configuration options for the boot behavior of the virtual machine. - -ftInfo (vim.vm.FaultToleranceConfigInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Fault tolerance settings for the virtual machine. - -vAppConfig (vim.vApp.VmConfigInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - vApp meta-data for the virtual machine. - -vAssertsEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether user-configured virtual asserts will be triggered during virtual machine replay. - -changeTrackingEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether changed block tracking for the virtual machine's disks is active. - -firmware (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^ - - Information about firmware type for the virtual machine. - -maxMksConnections (int, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates the maximum number of active remote display connections that the virtual machine will support. - -guestAutoLockEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the guest operating system will logout any active sessions whenever there are no remote display connections open to the virtual machine. - -managedBy (vim.ext.ManagedByInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Specifies that the virtual machine is managed by a VC Extension. - -.. _ansible_collections.community.vmware.docsite.memory_reservation_locked_to_max: - -memoryReservationLockedToMax (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - If set true, memory resource reservation for the virtual machine will always be equal to the virtual machine's memory size; increases in memory size will be rejected when a corresponding reservation increase is not possible. - -initialOverhead (vim.vm.ConfigInfo.OverheadInfo), optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Set of values to be used only to perform admission control when determining if a host has sufficient resources for the virtual machine to power on. - -nestedHVEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the virtual machine is configured to use nested hardware-assisted virtualization. - -vPMCEnabled (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether the virtual machine have virtual CPU performance counters enabled. - -scheduledHardwareUpgradeInfo (vim.vm.ScheduledHardwareUpgradeInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Configuration of scheduled hardware upgrades and result from last attempt to run scheduled hardware upgrade. - -vFlashCacheReservation (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Specifies the total vFlash resource reservation for the vFlash caches associated with the virtual machine's virtual disks, in bytes. - -layout ------- - -Detailed information about the files that comprise the virtual machine. - -configFile (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A list of files that makes up the configuration of the virtual machine (excluding the .vmx file, since that file is represented in the FileInfo). - These are relative paths from the configuration directory. - A slash is always used as a separator. - This list will typically include the NVRAM file, but could also include other meta-data files. - -logFile (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^ - - A list of files stored in the virtual machine's log directory. - These are relative paths from the ``logDirectory``. - A slash is always used as a separator. - -disk (vim.vm.FileLayout.DiskLayout, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Files making up each virtual disk. - -snapshot (vim.vm.FileLayout.SnapshotLayout, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Files of each snapshot. - -swapFile (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^ - - The swapfile specific to the virtual machine, if any. This is a complete datastore path, not a relative path. - - -layoutEx --------- - -Detailed information about the files that comprise the virtual machine. - -file (vim.vm.FileLayoutEx.FileInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Information about all the files that constitute the virtual machine including configuration files, disks, swap file, suspend file, log files, core files, memory file and so on. - -disk (vim.vm.FileLayoutEx.DiskLayout, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Layout of each virtual disk attached to the virtual machine. - For a virtual machine with snaphots, this property gives only those disks that are attached to it at the current point of running. - -snapshot (vim.vm.FileLayoutEx.SnapshotLayout, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Layout of each snapshot of the virtual machine. - -timestamp (datetime) -^^^^^^^^^^^^^^^^^^^^ - - Time when values in this structure were last updated. - -storage (vim.vm.StorageInfo) ----------------------------- - -Storage space used by the virtual machine, split by datastore. - -perDatastoreUsage (vim.vm.StorageInfo.UsageOnDatastore, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Storage space used by the virtual machine on all datastores that it is located on. - Total storage space committed to the virtual machine across all datastores is simply an aggregate of the property ``committed`` - -timestamp (datetime) -^^^^^^^^^^^^^^^^^^^^ - - Time when values in this structure were last updated. - -environmentBrowser (vim.EnvironmentBrowser) -------------------------------------------- - -The current virtual machine's environment browser object. -This contains information on all the configurations that can be used on the virtual machine. -This is identical to the environment browser on the ComputeResource to which the virtual machine belongs. - -datastoreBrowser (vim.host.DatastoreBrowser) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - DatastoreBrowser to browse datastores that are available on this entity. - -resourcePool (vim.ResourcePool) -------------------------------- - -The current resource pool that specifies resource allocation for the virtual machine. -This property is set when a virtual machine is created or associated with a different resource pool. -Returns null if the virtual machine is a template or the session has no access to the resource pool. - -summary (vim.ResourcePool.Summary) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Basic information about a resource pool. - -runtime (vim.ResourcePool.RuntimeInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Runtime information about a resource pool. - -owner (vim.ComputeResource) -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The ComputeResource to which this set of one or more nested resource pools belong. - -resourcePool (vim.ResourcePool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The set of child resource pools. - -vm (vim.VirtualMachine) -^^^^^^^^^^^^^^^^^^^^^^^ - - The set of virtual machines associated with this resource pool. - -config (vim.ResourceConfigSpec) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Configuration of this resource pool. - -childConfiguration (vim.ResourceConfigSpec) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The resource configuration of all direct children (VirtualMachine and ResourcePool) of this resource group. - -parentVApp (vim.ManagedEntity) ------------------------------- - -Reference to the parent vApp. - -parent (vim.ManagedEntity) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Parent of this entity. - This value is null for the root object and for (VirtualMachine) objects that are part of a (VirtualApp). - -customValue (vim.CustomFieldsManager.Value) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Custom field values. - -overallStatus (vim.ManagedEntity.Status) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - General health of this managed entity. - -configStatus (vim.ManagedEntity.Status) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The configStatus indicates whether or not the system has detected a configuration issue involving this entity. - For example, it might have detected a duplicate IP address or MAC address, or a host in a cluster might be out of ``compliance.property``. - -configIssue (vim.event.Event) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current configuration issues that have been detected for this entity. - -effectiveRole (int) -^^^^^^^^^^^^^^^^^^^ - - Access rights the current session has to this entity. - -permission (vim.AuthorizationManager.Permission) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - List of permissions defined for this entity. - -name (str) -^^^^^^^^^^ - - Name of this entity, unique relative to its parent. - Any / (slash), \ (backslash), character used in this name element will be escaped. - Similarly, any % (percent) character used in this name element will be escaped, unless it is used to start an escape sequence. - A slash is escaped as %2F or %2f. A backslash is escaped as %5C or %5c, and a percent is escaped as %25. - -disabledMethod (str) -^^^^^^^^^^^^^^^^^^^^ - - List of operations that are disabled, given the current runtime state of the entity. - For example, a power-on operation always fails if a virtual machine is already powered on. - -recentTask (vim.Task) -^^^^^^^^^^^^^^^^^^^^^ - - The set of recent tasks operating on this managed entity. - A task in this list could be in one of the four states: pending, running, success or error. - -declaredAlarmState (vim.alarm.AlarmState) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A set of alarm states for alarms that apply to this managed entity. - -triggeredAlarmState (vim.alarm.AlarmState) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A set of alarm states for alarms triggered by this entity or by its descendants. - -alarmActionsEnabled (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Whether alarm actions are enabled for this entity. True if enabled; false otherwise. - -tag (vim.Tag) -^^^^^^^^^^^^^ - - The set of tags associated with this managed entity. Experimental. Subject to change. - -resourceConfig (vim.ResourceConfigSpec) ---------------------------------------- - - The resource configuration for a virtual machine. - -entity (vim.ManagedEntity, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Reference to the entity with this resource specification: either a VirtualMachine or a ResourcePool. - -changeVersion (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The changeVersion is a unique identifier for a given version of the configuration. Each change to the configuration will update this value. - This is typically implemented as an ever increasing count or a time-stamp. - - -lastModified (datetime, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Timestamp when the resources were last modified. This is ignored when the object is used to update a configuration. - -cpuAllocation (vim.ResourceAllocationInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Resource allocation for CPU. - -memoryAllocation (vim.ResourceAllocationInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Resource allocation for memory. - -runtime (vim.vm.RuntimeInfo) ----------------------------- - -Execution state and history for the virtual machine. - -device (vim.vm.DeviceRuntimeInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Per-device runtime info. This array will be empty if the host software does not provide runtime info for any of the device types currently in use by the virtual machine. - -host (vim.HostSystem, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The host that is responsible for running a virtual machine. - This property is null if the virtual machine is not running and is not assigned to run on a particular host. - -connectionState (vim.VirtualMachine.ConnectionState) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Indicates whether or not the virtual machine is available for management. - -powerState (vim.VirtualMachine.PowerState) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The current power state of the virtual machine. - -faultToleranceState (vim.VirtualMachine.FaultToleranceState) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The fault tolerance state of the virtual machine. - -dasVmProtection (vim.vm.RuntimeInfo.DasProtectionState, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The vSphere HA protection state for a virtual machine. - Property is unset if vSphere HA is not enabled. - -toolsInstallerMounted (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Flag to indicate whether or not the VMware Tools installer is mounted as a CD-ROM. - -suspendTime (datetime, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The timestamp when the virtual machine was most recently suspended. - This property is updated every time the virtual machine is suspended. - -bootTime (datetime, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The timestamp when the virtual machine was most recently powered on. - This property is updated when the virtual machine is powered on from the poweredOff state, and is cleared when the virtual machine is powered off. - This property is not updated when a virtual machine is resumed from a suspended state. - -suspendInterval (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The total time the virtual machine has been suspended since it was initially powered on. - This time excludes the current period, if the virtual machine is currently suspended. - This property is updated when the virtual machine resumes, and is reset to zero when the virtual machine is powered off. - -question (vim.vm.QuestionInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The current question, if any, that is blocking the virtual machine's execution. - -memoryOverhead (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The amount of memory resource (in bytes) that will be used by the virtual machine above its guest memory requirements. - This value is set if and only if the virtual machine is registered on a host that supports memory resource allocation features. - For powered off VMs, this is the minimum overhead required to power on the VM on the registered host. - For powered on VMs, this is the current overhead reservation, a value which is almost always larger than the minimum overhead, and which grows with time. - -maxCpuUsage (int, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current upper-bound on CPU usage. - The upper-bound is based on the host the virtual machine is current running on, as well as limits configured on the virtual machine itself or any parent resource pool. - Valid while the virtual machine is running. - -maxMemoryUsage (int, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current upper-bound on memory usage. - The upper-bound is based on memory configuration of the virtual machine, as well as limits configured on the virtual machine itself or any parent resource pool. - Valid while the virtual machine is running. - -numMksConnections (int) -^^^^^^^^^^^^^^^^^^^^^^^ - - Number of active MKS connections to the virtual machine. - -recordReplayState (vim.VirtualMachine.RecordReplayState) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Record / replay state of the virtual machine. - -cleanPowerOff (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - For a powered off virtual machine, indicates whether the virtual machine's last shutdown was an orderly power off or not. - Unset if the virtual machine is running or suspended. - -needSecondaryReason (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - If set, indicates the reason the virtual machine needs a secondary. - -onlineStandby (bool) -^^^^^^^^^^^^^^^^^^^^ - - This property indicates whether the guest has gone into one of the s1, s2 or s3 standby modes. False indicates the guest is awake. - -minRequiredEVCModeKey (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - For a powered-on or suspended virtual machine in a cluster with Enhanced VMotion Compatibility (EVC) enabled, this identifies the least-featured EVC mode (among those for the appropriate CPU vendor) that could admit the virtual machine. - This property will be unset if the virtual machine is powered off or is not in an EVC cluster. - This property may be used as a general indicator of the CPU feature baseline currently in use by the virtual machine. - However, the virtual machine may be suppressing some of the features present in the CPU feature baseline of the indicated mode, either explicitly (in the virtual machine's configured ``cpuFeatureMask``) or implicitly (in the default masks for the ``GuestOsDescriptor`` appropriate for the virtual machine's configured guest OS). - -consolidationNeeded (bool) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Whether any disk of the virtual machine requires consolidation. - This can happen for example when a snapshot is deleted but its associated disk is not committed back to the base disk. - -offlineFeatureRequirement (vim.vm.FeatureRequirement, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - These requirements must have equivalent host capabilities ``featureCapability`` in order to power on. - -featureRequirement (vim.vm.FeatureRequirement, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - These requirements must have equivalent host capabilities ``featureCapability`` in order to power on, resume, or migrate to the host. - -featureMask (vim.host.FeatureMask, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - The masks applied to an individual virtual machine as a result of its configuration. - -vFlashCacheAllocation (long, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Specifies the total allocated vFlash resource for the vFlash caches associated with VM's VMDKs when VM is powered on, in bytes. - - -guest (vim.vm.GuestInfo) ------------------------- - -Information about VMware Tools and about the virtual machine from the perspective of VMware Tools. -Information about the guest operating system is available in VirtualCenter. -Guest operating system information reflects the last known state of the virtual machine. -For powered on machines, this is current information. -For powered off machines, this is the last recorded state before the virtual machine was powered off. - -toolsStatus (vim.vm.GuestInfo.ToolsStatus, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current status of VMware Tools in the guest operating system, if known. - -toolsVersionStatus (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current version status of VMware Tools in the guest operating system, if known. - -toolsVersionStatus2 (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current version status of VMware Tools in the guest operating system, if known. - -toolsRunningStatus (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current running status of VMware Tools in the guest operating system, if known. - -toolsVersion (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current version of VMware Tools, if known. - -guestId (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^ - - Guest operating system identifier (short name), if known. - -guestFamily (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest operating system family, if known. - -guestFullName (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - See :ref:`ansible_collections.community.vmware.docsite.guest_full_name`. - -hostName (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^ - - Hostname of the guest operating system, if known. - -ipAddress (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^ - - Primary IP address assigned to the guest operating system, if known. - -net (vim.vm.GuestInfo.NicInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest information about network adapters, if known. - -ipStack (vim.vm.GuestInfo.StackInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest information about IP networking stack, if known. - -disk (vim.vm.GuestInfo.DiskInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest information about disks. - You can obtain Linux guest disk information for the following file system types only: Ext2, Ext3, Ext4, ReiserFS, ZFS, NTFS, VFAT, UFS, PCFS, HFS, and MS-DOS. - -screen (vim.vm.GuestInfo.ScreenInfo, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest screen resolution info, if known. - -guestState (str) -^^^^^^^^^^^^^^^^ - - Operation mode of guest operating system. - -appHeartbeatStatus (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Application heartbeat status. - -appState (str, optional) -^^^^^^^^^^^^^^^^^^^^^^^^ - - Application state. - If vSphere HA is enabled and the vm is configured for Application Monitoring and this field's value is ``appStateNeedReset`` then HA will attempt immediately reset the virtual machine. - There are some system conditions which may delay the immediate reset. - The immediate reset will be performed as soon as allowed by vSphere HA and ESX. - If during these conditions the value is changed to ``appStateOk`` the reset will be cancelled. - -guestOperationsReady (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest Operations availability. If true, the vitrual machine is ready to process guest operations. - -interactiveGuestOperationsReady (bool, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Interactive Guest Operations availability. If true, the virtual machine is ready to process guest operations as the user interacting with the guest desktop. - -generationInfo (vim.vm.GuestInfo.NamespaceGenerationInfo, privilege: VirtualMachine.Namespace.EventNotify, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A list of namespaces and their corresponding generation numbers. Only namespaces with non-zero ``maxSizeEventsFromGuest`` are guaranteed to be present here. - - -summary (vim.vm.Summary) ------------------------- - - Basic information about the virtual machine. - -vm (vim.VirtualMachine, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Reference to the virtual machine managed object. - -runtime (vim.vm.RuntimeInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Runtime and state information of a running virtual machine. - Most of this information is also available when a virtual machine is powered off. - In that case, it contains information from the last run, if available. - -guest (vim.vm.Summary.GuestSummary, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Guest operating system and VMware Tools information. - -config (vim.vm.Summary.ConfigSummary) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Basic configuration information about the virtual machine. - This information is not available when the virtual machine is unavailable, for instance, when it is being created or deleted. - -storage (vim.vm.Summary.StorageSummary, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Storage information of the virtual machine. - -quickStats (vim.vm.Summary.QuickStats) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - A set of statistics that are typically updated with near real-time regularity. - -overallStatus (vim.ManagedEntity.Status) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Overall alarm status on this node. - -customValue (vim.CustomFieldsManager.Value, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Custom field values. - - -datastore (vim.Datastore) -------------------------- - - A collection of references to the subset of datastore objects in the datacenter that is used by the virtual machine. - -info (vim.Datastore.Info) -^^^^^^^^^^^^^^^^^^^^^^^^^ - - Specific information about the datastore. - -summary (vim.Datastore.Summary) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Global properties of the datastore. - -host (vim.Datastore.HostMount) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Hosts attached to this datastore. - -vm (vim.VirtualMachine) -^^^^^^^^^^^^^^^^^^^^^^^ - - Virtual machines stored on this datastore. - -browser (vim.host.DatastoreBrowser) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - DatastoreBrowser used to browse this datastore. - -capability (vim.Datastore.Capability) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Capabilities of this datastore. - -iormConfiguration (vim.StorageResourceManager.IORMConfigInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Configuration of storage I/O resource management for the datastore. - Currently VMware only support storage I/O resource management on VMFS volumes of a datastore. - This configuration may not be available if the datastore is not accessible from any host, or if the datastore does not have VMFS volume. - -network (vim.Network) ---------------------- - - A collection of references to the subset of network objects in the datacenter that is used by the virtual machine. - -name (str) -^^^^^^^^^^ - - Name of this network. - -summary (vim.Network.Summary) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Properties of a network. - -host (vim.HostSystem) -^^^^^^^^^^^^^^^^^^^^^ - - Hosts attached to this network. - -vm (vim.VirtualMachine) -^^^^^^^^^^^^^^^^^^^^^^^ - - Virtual machines using this network. - - -snapshot (vim.vm.SnapshotInfo) -------------------------------- - -Current snapshot and tree. -The property is valid if snapshots have been created for the virtual machine. - -currentSnapshot (vim.vm.Snapshot, optional) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Current snapshot of the virtual machineThis property is set by calling ``Snapshot.revert`` or ``VirtualMachine.createSnapshot``. - This property will be empty when the working snapshot is at the root of the snapshot tree. - -rootSnapshotList (vim.vm.SnapshotTree) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Data for the entire set of snapshots for one virtual machine. - -rootSnapshot (vim.vm.Snapshot) ------------------------------- - -The roots of all snapshot trees for the virtual machine. - -config (vim.vm.ConfigInfo) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - - Information about the configuration of the virtual machine when this snapshot was taken. - The datastore paths for the virtual machine disks point to the head of the disk chain that represents the disk at this given snapshot. - -childSnapshot (vim.vm.Snapshot) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - All snapshots for which this snapshot is the parent. - -guestHeartbeatStatus (vim.ManagedEntity.Status) ------------------------------------------------ - - The guest heartbeat. - -.. seealso:: - - `pyVmomi <https://github.com/vmware/pyvmomi>`_ - The GitHub Page of pyVmomi - `pyVmomi Issue Tracker <https://github.com/vmware/pyvmomi/issues>`_ - The issue tracker for the pyVmomi project - rst/scenario_guides/guide_vmware.rst - The GitHub Page of vSphere Automation SDK for Python - `vSphere Automation SDK Issue Tracker <https://github.com/vmware/vsphere-automation-sdk-python/issues>`_ - The issue tracker for vSphere Automation SDK for Python - :ref:`working_with_playbooks` - An introduction to playbooks - :ref:`playbooks_vault` - Using Vault in playbooks diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_module_reference.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_module_reference.rst deleted file mode 100644 index 9a9a36e98..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_module_reference.rst +++ /dev/null @@ -1,9 +0,0 @@ -:orphan: - -.. _ansible_collections.community.vmware.docsite.vmware_ansible_module_index: - -*************************** -Ansible VMware Module Guide -*************************** - -This will be a listing similar to the module index in our core docs. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_requirements.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_requirements.rst deleted file mode 100644 index 8244afe2f..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_requirements.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_requirements: - -******************** -VMware Prerequisites -******************** - -.. contents:: - :local: - -ESXi License -============ - -Access to the vSphere API is governed by the various vSphere Editions which provides both read and write access to the API. -If you are using vSphere Hypervisor (free edition of ESXi), the vSphere API will only be available as read-only. -All modules requires API write access to perform various actions. Hence, a free ESXi license will not be supported. -Please check `this blog post <https://blogs.vmware.com/vsphere/2012/02/introduction-to-the-vsphere-api-part-1.html>`_ for more details. - - -Installing SSL Certificates -=========================== - -All vCenter and ESXi servers require SSL encryption on all connections to enforce secure communication. You must enable SSL encryption for Ansible by installing the server's SSL certificates on your Ansible control node or delegate node. - -If the SSL certificate of your vCenter or ESXi server is not correctly installed on your Ansible control node, you will see the following warning when using Ansible VMware modules: - -``Unable to connect to vCenter or ESXi API at xx.xx.xx.xx on TCP/443: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)`` - -To install the SSL certificate for your VMware server, and run your Ansible VMware modules in encrypted mode, please follow the instructions for the server you are running with VMware. - -Installing vCenter SSL certificates for Ansible ------------------------------------------------ - -* From any web browser, go to the base URL of the vCenter Server without port number like ``https://vcenter-domain.example.com`` - -* Click the "Download trusted root CA certificates" link at the bottom of the grey box on the right and download the file. - -* Change the extension of the file to .zip. The file is a ZIP file of all root certificates and all CRLs. - -* Extract the contents of the zip file. The extracted directory contains a ``.certs`` directory that contains two types of files. Files with a number as the extension (.0, .1, and so on) are root certificates. - -* Install the certificate files are trusted certificates by the process that is appropriate for your operating system. - - -Installing ESXi SSL certificates for Ansible --------------------------------------------- - -* Enable SSH Service on ESXi either by using Ansible VMware module `vmware_host_service_manager <https://github.com/ansible-collections/vmware/blob/main/plugins/modules/vmware_host_config_manager.py>`_ or manually using vSphere Web interface. - -* SSH to ESXi server using administrative credentials, and navigate to directory ``/etc/vmware/ssl`` - -* Secure copy (SCP) ``rui.crt`` located in ``/etc/vmware/ssl`` directory to Ansible control node. - -* Install the certificate file by the process that is appropriate for your operating system. - -Using custom path for SSL certificates --------------------------------------- - -If you need to use a custom path for SSL certificates, you can set the ``REQUESTS_CA_BUNDLE`` environment variable in your playbook. - -For example, if ``/var/vmware/certs/vcenter1.crt`` is the SSL certificate for your vCenter Server, you can use the :ref:`environment <playbooks_environment>` keyword to pass it to the modules: - -.. code-block:: yaml - - - name: Gather all tags from vCenter - community.vmware.vmware_tag_info: - validate_certs: True - hostname: '{{ vcenter_hostname }}' - username: '{{ vcenter_username }}' - password: '{{ vcenter_password }}' - environment: - REQUESTS_CA_BUNDLE: /var/vmware/certs/vcenter1.crt - -There is a `known issue <https://github.com/psf/requests/issues/3829>`_ in ``requests`` library (version 2) which you may want to consider when using this environment variable. Basically, setting ``REQUESTS_CA_BUNDLE`` environment variable on managed nodes overrides the ``validate_certs`` value. This may result in unexpected behavior while running the playbook. Please see `community.vmware issue 601 <https://github.com/ansible-collections/community.vmware/issues/601>`_ and `vmware issue 254 <https://github.com/vmware/vsphere-automation-sdk-python/issues/254>`_ for more information. diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_scenarios.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_scenarios.rst deleted file mode 100644 index e34aa43d5..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_scenarios.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_scenarios: - -**************************** -Ansible for VMware Scenarios -**************************** - -These scenarios teach you how to accomplish common VMware tasks using Ansible. To get started, please select the task you want to accomplish. - -.. toctree:: - :maxdepth: 1 - - scenario_clone_template - scenario_rename_vm - scenario_remove_vm - scenario_find_vm_folder - scenario_vmware_http - scenario_vmware_tools_connection diff --git a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_troubleshooting.rst b/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_troubleshooting.rst deleted file mode 100644 index b0243c28c..000000000 --- a/ansible_collections/community/vmware/docs/docsite/rst/vmware_scenarios/vmware_troubleshooting.rst +++ /dev/null @@ -1,103 +0,0 @@ -.. _ansible_collections.community.vmware.docsite.vmware_troubleshooting: - -********************************** -Troubleshooting Ansible for VMware -********************************** - -.. contents:: - :local: - -This section lists things that can go wrong and possible ways to fix them. - -Debugging Ansible for VMware -============================ - -When debugging or creating a new issue, you will need information about your VMware infrastructure. You can get this information using -`govc <https://github.com/vmware/govmomi/tree/master/govc>`_, For example: - - -.. code-block:: bash - - $ export GOVC_USERNAME=ESXI_OR_VCENTER_USERNAME - $ export GOVC_PASSWORD=ESXI_OR_VCENTER_PASSWORD - $ export GOVC_URL=https://ESXI_OR_VCENTER_HOSTNAME:443 - $ govc find / - -Known issues with Ansible for VMware -==================================== - - -Network settings with vmware_guest in Ubuntu 18.04 --------------------------------------------------- - -Setting the network with ``vmware_guest`` in Ubuntu 18.04 is known to be broken, due to missing support for ``netplan`` in the ``open-vm-tools``. -This issue is tracked via: - -* https://github.com/vmware/open-vm-tools/issues/240 -* https://github.com/ansible/ansible/issues/41133 - -Potential Workarounds -^^^^^^^^^^^^^^^^^^^^^ - -There are several workarounds for this issue. - -1) Modify the Ubuntu 18.04 images and installing ``ifupdown`` in them via ``sudo apt install ifupdown``. - If so you need to remove ``netplan`` via ``sudo apt remove netplan.io`` and you need stop ``systemd-networkd`` via ``sudo systemctl disable systemctl-networkd``. - -2) Generate the ``systemd-networkd`` files with a task in your VMware Ansible role: - -.. code-block:: yaml - - - name: make sure cache directory exists - file: path="{{ inventory_dir }}/cache" state=directory - delegate_to: localhost - - - name: generate network templates - template: src=network.j2 dest="{{ inventory_dir }}/cache/{{ inventory_hostname }}.network" - delegate_to: localhost - - - name: copy generated files to vm - vmware_guest_file_operation: - hostname: "{{ vmware_general.hostname }}" - username: "{{ vmware_username }}" - password: "{{ vmware_password }}" - datacenter: "{{ vmware_general.datacenter }}" - validate_certs: "{{ vmware_general.validate_certs }}" - vm_id: "{{ inventory_hostname }}" - vm_username: root - vm_password: "{{ template_password }}" - copy: - src: "{{ inventory_dir }}/cache/{{ inventory_hostname }}.network" - dest: "/etc/systemd/network/ens160.network" - overwrite: False - delegate_to: localhost - - - name: restart systemd-networkd - vmware_vm_shell: - hostname: "{{ vmware_general.hostname }}" - username: "{{ vmware_username }}" - password: "{{ vmware_password }}" - datacenter: "{{ vmware_general.datacenter }}" - folder: /vm - vm_id: "{{ inventory_hostname}}" - vm_username: root - vm_password: "{{ template_password }}" - vm_shell: /bin/systemctl - vm_shell_args: " restart systemd-networkd" - delegate_to: localhost - - - name: restart systemd-resolved - vmware_vm_shell: - hostname: "{{ vmware_general.hostname }}" - username: "{{ vmware_username }}" - password: "{{ vmware_password }}" - datacenter: "{{ vmware_general.datacenter }}" - folder: /vm - vm_id: "{{ inventory_hostname}}" - vm_username: root - vm_password: "{{ template_password }}" - vm_shell: /bin/systemctl - vm_shell_args: " restart systemd-resolved" - delegate_to: localhost - -3) Wait for ``netplan`` support in ``open-vm-tools`` diff --git a/ansible_collections/community/vmware/meta/runtime.yml b/ansible_collections/community/vmware/meta/runtime.yml index 92196f500..621c815bd 100644 --- a/ansible_collections/community/vmware/meta/runtime.yml +++ b/ansible_collections/community/vmware/meta/runtime.yml @@ -11,6 +11,7 @@ action_groups: - vcenter_root_password_expiration - vcenter_standard_key_provider - vmware_about_info + - vmware_all_snapshots_info - vmware_category - vmware_category_info - vmware_cfg_backup diff --git a/ansible_collections/community/vmware/plugins/doc_fragments/vmware.py b/ansible_collections/community/vmware/plugins/doc_fragments/vmware.py index 5df2762c1..18fe01972 100644 --- a/ansible_collections/community/vmware/plugins/doc_fragments/vmware.py +++ b/ansible_collections/community/vmware/plugins/doc_fragments/vmware.py @@ -15,6 +15,7 @@ class ModuleDocFragment(object): DOCUMENTATION = r''' notes: - All modules requires API write access and hence is not supported on a free ESXi license. + - All variables and VMware object names are case sensitive. options: hostname: description: diff --git a/ansible_collections/community/vmware/plugins/doc_fragments/vmware_rest_client.py b/ansible_collections/community/vmware/plugins/doc_fragments/vmware_rest_client.py index f852173d6..50af0ba50 100644 --- a/ansible_collections/community/vmware/plugins/doc_fragments/vmware_rest_client.py +++ b/ansible_collections/community/vmware/plugins/doc_fragments/vmware_rest_client.py @@ -12,6 +12,9 @@ __metaclass__ = type class ModuleDocFragment(object): # Parameters for VMware REST Client based modules DOCUMENTATION = r''' +notes: + - All modules requires API write access and hence is not supported on a free ESXi license. + - All variables and VMware object names are case sensitive. options: hostname: description: diff --git a/ansible_collections/community/vmware/plugins/module_utils/vmware.py b/ansible_collections/community/vmware/plugins/module_utils/vmware.py index a7b61bdae..12bdf5107 100644 --- a/ansible_collections/community/vmware/plugins/module_utils/vmware.py +++ b/ansible_collections/community/vmware/plugins/module_utils/vmware.py @@ -1088,11 +1088,11 @@ def option_diff(options, current_options, truthy_strings_as_bool=True): for option_key, option_value in options.items(): if truthy_strings_as_bool and is_boolean(option_value): option_value = VmomiSupport.vmodlTypes['bool'](is_truthy(option_value)) - elif type(option_value) is int: + elif isinstance(option_value, int): option_value = VmomiSupport.vmodlTypes['int'](option_value) - elif type(option_value) is float: + elif isinstance(option_value, float): option_value = VmomiSupport.vmodlTypes['float'](option_value) - elif type(option_value) is str: + elif isinstance(option_value, str): option_value = VmomiSupport.vmodlTypes['string'](option_value) if option_key not in current_options_dict or current_options_dict[option_key] != option_value: diff --git a/ansible_collections/community/vmware/plugins/modules/vcenter_folder.py b/ansible_collections/community/vmware/plugins/modules/vcenter_folder.py index 7103e6285..46be0df4b 100644 --- a/ansible_collections/community/vmware/plugins/modules/vcenter_folder.py +++ b/ansible_collections/community/vmware/plugins/modules/vcenter_folder.py @@ -30,14 +30,12 @@ options: folder_name: description: - Name of folder to be managed. - - This is case sensitive parameter. - Folder name should be under 80 characters. This is a VMware restriction. required: true type: str parent_folder: description: - Name of the parent folder under which new folder needs to be created. - - This is case sensitive parameter. - "If user wants to create a folder under '/DC0/vm/vm_folder', this value will be 'vm_folder'." - "If user wants to create a folder under '/DC0/vm/folder1/folder2', this value will be 'folder1/folder2'." required: false diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_all_snapshots_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_all_snapshots_info.py new file mode 100644 index 000000000..934781a6c --- /dev/null +++ b/ansible_collections/community/vmware/plugins/modules/vmware_all_snapshots_info.py @@ -0,0 +1,204 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2018, Ansible Project +# Copyright: (c) 2024, Fernando Mendieta <fernandomendietaovejero@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''' +--- +module: vmware_all_snapshots_info +short_description: Gathers information about all snapshots across virtual machines in a specified vmware datacenter +description: +- This module collects detailed information of all the snapshots of the datacenter, can be used with filter options +author: +- Fernando Mendieta (@valkiriaaquatica) +options: + datacenter: + description: + - The name of the datacenter to gather snapshot information from. You can get it in the vmware UI. + required: true + type: str + filters: + description: + - Optional filters to apply to the snapshot data being gathered, you can apply one or more. + - Filters are applied based on the variable match_type specified. If match_type exact, filters require exact matches. + - On the other hand when match_type includes it gets the values that contain that value. + - Available filter options creation_time, description, folder, id, name, quiesced, state, vm_name. + - Multiple filters can be applied the snapshot must meet all filter criteria to be included in the results. + required: false + type: dict + default: {} + match_type: + description: + - Indicates whether the filter match should be exact or includes. + - For example when you want to get all the snapshots that contain in their name the word test you place the filter name test and the match_type includes. + - For example when you want to get all snapshots that are in state poweredOn you skip the match_type default is exact or you write match_type exact. + required: false + type: str + choices: ['exact', 'includes'] + default: exact +extends_documentation_fragment: +- community.vmware.vmware.documentation +''' + +EXAMPLES = r''' + - name: Gather information about all snapshots in VMware vCenter + vmware_snapshot_info_all: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: no + datacenter: '{{ datacenter_name }}' + delegate_to: localhost + - name: Gather information of a snapshot with filters applied and match_type in exacts. + vmware_snapshot_info_all: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: yes + datacenter: '{{ datacenter_name }}' + filters: + state: "poweredOn" + vm_name: "you_marchine_name" + delegate_to: localhost + - name: Gather information of snapshots that in their name contain the "test" in their name. + vmware_snapshot_info_all: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: yes + datacenter: '{{ datacenter_name }}' + match_type: "includes" + filters: + name: "test" + delegate_to: localhost +''' + +RETURN = r''' +vmware_all_snapshots_info: + description: A list of all snapshots information across all virtual machines in the specified datacenter + returned: always + type: list + elements: dict + contains: + vm_name: + description: The name of the virtual machine that appears in the iu. + type: str + returned: always + folder: + description: The folder path of the virtual machine in the datacenter, normally is vm + type: str + returned: always + name: + description: The name of the snapshot + type: str + returned: always + description: + description: The description of the snapshot. + type: str + returned: when it exists because depends if it has or not + creation_time: + description: The time the snapshot was created + type: str + returned: always + state: + description: The state of the virtual machine at the snapshot (powered on/off) + type: str + returned: always + id: + description: The unique identifier of the snapshot + type: int + returned: always + quiesced: + description: Indicates if the snapshot was created with the virtual machines file system quiesced + type: bool + returned: always +''' + + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.vmware.plugins.module_utils.vmware import ( + PyVmomi, + vmware_argument_spec, + list_snapshots_recursively, +) + +try: + from pyVmomi import vim +except ImportError: + pass + + +class VMwareSnapshotInfo(PyVmomi): + def __init__(self, module): + super(VMwareSnapshotInfo, self).__init__(module) + + def list_snapshots(self, vm): + return ( + list_snapshots_recursively(vm.snapshot.rootSnapshotList) + if vm.snapshot + else [] + ) + + def get_all_vms(self): + content = self.content + container = content.viewManager.CreateContainerView( + content.rootFolder, [vim.VirtualMachine], True + ) + vms = container.view + container.Destroy() + return vms + + def gather_snapshots_info(self, filters, match_type): + snapshot_data = [] + for vm in self.get_all_vms(): + for snapshot in self.list_snapshots(vm): + snapshot_info = { + "vm_name": vm.name, + "folder": vm.parent.name, + **snapshot, + } + if self.passes_filters(snapshot_info, filters, match_type): + snapshot_data.append(snapshot_info) + return snapshot_data + + def passes_filters(self, snapshot_info, filters, match_type): + for key, value in filters.items(): + if key not in snapshot_info: + continue + actual_value = str(snapshot_info[key]).lower() + desired_value = str(value).lower() + + if match_type == "exact" and actual_value != desired_value: + return False + elif match_type == "includes" and desired_value not in actual_value: + return False + return True + + +def main(): + argument_spec = vmware_argument_spec() + argument_spec.update( + datacenter=dict(required=True, type="str"), + filters=dict(required=False, type="dict", default={}), + match_type=dict( + required=False, type="str", choices=["exact", "includes"], default="exact" + ), + ) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) + vmware_snapshot_info = VMwareSnapshotInfo(module) + filters = module.params.get("filters") + match_type = module.params.get("match_type") + all_snapshots = vmware_snapshot_info.gather_snapshots_info(filters, match_type) + module.exit_json(changed=False, vmware_all_snapshots_info=all_snapshots) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_category.py b/ansible_collections/community/vmware/plugins/modules/vmware_category.py index c107c4f13..6e76a8b97 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_category.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_category.py @@ -17,7 +17,6 @@ short_description: Manage VMware categories description: - This module can be used to create / delete / update VMware categories. - Tag feature is introduced in vSphere 6 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_category_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_category_info.py index 10fdb162f..71d228f83 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_category_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_category_info.py @@ -17,7 +17,6 @@ short_description: Gather info about VMware tag categories description: - This module can be used to gather information about VMware tag categories. - Tag feature is introduced in vSphere 6 version, so this module is not supported in earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster.py index 479d31520..8af4d881c 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster.py @@ -17,7 +17,6 @@ short_description: Manage VMware vSphere clusters description: - Adds or removes VMware vSphere clusters. - To manage DRS, HA and VSAN related configurations, use the modules vmware_cluster_drs, vmware_cluster_ha and vmware_cluster_vsan. - - All values and VMware object names are case sensitive. author: - Joseph Callen (@jcpowermac) - Abhijeet Kasurde (@Akasurde) 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 61551263c..1215f52c3 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_dpm.py @@ -17,7 +17,6 @@ module: vmware_cluster_dpm short_description: Manage Distributed Power Management (DPM) on VMware vSphere clusters description: - Manages DPM on VMware vSphere clusters. - - All values and VMware object names are case sensitive. author: - Olivia Luetolf (@olilu) options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_drs.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_drs.py index 3027c2910..873e87709 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_drs.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_drs.py @@ -16,7 +16,6 @@ module: vmware_cluster_drs short_description: Manage Distributed Resource Scheduler (DRS) on VMware vSphere clusters description: - Manages DRS on VMware vSphere clusters. - - All values and VMware object names are case sensitive. author: - Joseph Callen (@jcpowermac) - Abhijeet Kasurde (@Akasurde) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_ha.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_ha.py index 1ad532d4b..cad1eb519 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_ha.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_ha.py @@ -17,7 +17,6 @@ module: vmware_cluster_ha short_description: Manage High Availability (HA) on VMware vSphere clusters description: - Manages HA configuration on VMware vSphere clusters. - - All values and VMware object names are case sensitive. author: - Joseph Callen (@jcpowermac) - Abhijeet Kasurde (@Akasurde) 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 a015b6fc3..24ca77bc8 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_info.py @@ -16,7 +16,6 @@ module: vmware_cluster_info short_description: Gather info about clusters available in given vCenter description: - This module can be used to gather information about clusters in VMWare infrastructure. - - All values and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) - Christian Neugum (@digifuchsi) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vcls.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vcls.py index f553adcdb..19d07ad86 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vcls.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vcls.py @@ -17,7 +17,6 @@ short_description: Override the default vCLS (vSphere Cluster Services) VM disk description: - Override the default vCLS VM disk placement for this cluster. - Some datastores cannot be selected for vCLS 'Allowed' as they are blocked by solutions as SRM or vSAN maintenance mode where vCLS cannot be configured. - - All values and VMware object names are case sensitive. author: - Joseph Callen (@jcpowermac) - Nina Loser (@Nina2244) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vsan.py b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vsan.py index 9f82aada8..0f4eb9cad 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vsan.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_cluster_vsan.py @@ -16,7 +16,6 @@ module: vmware_cluster_vsan short_description: Manages virtual storage area network (vSAN) configuration on VMware vSphere clusters description: - Manages vSAN on VMware vSphere clusters. - - All values and VMware object names are case sensitive. author: - Joseph Callen (@jcpowermac) - Abhijeet Kasurde (@Akasurde) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_ovf_template.py b/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_ovf_template.py index c74151904..f2a76bab2 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_ovf_template.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_ovf_template.py @@ -15,7 +15,6 @@ module: vmware_content_deploy_ovf_template short_description: Deploy Virtual Machine from ovf template stored in content library. description: - Module to deploy virtual machine from ovf template in content library. -- All variables and VMware object names are case sensitive. author: - Lev Goncharv (@ultral) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_template.py b/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_template.py index 3e0603373..31050a84a 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_template.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_content_deploy_template.py @@ -19,7 +19,6 @@ description: - Content Library feature is introduced in vSphere 6.0 version. - vmtx templates feature is introduced in vSphere 67U1 and APIs for clone template from content library in 67U2. - This module does not work with vSphere version older than 67U2. -- All variables and VMware object names are case sensitive. author: - Pavan Bidkar (@pgbidkar) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_content_library_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_content_library_info.py index 69cbb7cd0..abd3d0a44 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_content_library_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_content_library_info.py @@ -18,7 +18,6 @@ description: - Module to list the content libraries. - Module to get information about specific content library. - Content Library feature is introduced in vSphere 6.0 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Pavan Bidkar (@pgbidkar) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_content_library_manager.py b/ansible_collections/community/vmware/plugins/modules/vmware_content_library_manager.py index 932b77b6d..38ba6ba42 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_content_library_manager.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_content_library_manager.py @@ -17,7 +17,6 @@ short_description: Create, update and delete VMware content library description: - Module to manage VMware content Library - Content Library feature is introduced in vSphere 6.0 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Pavan Bidkar (@pgbidkar) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster.py b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster.py index 7a7dccbaf..9922499b4 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster.py @@ -16,7 +16,6 @@ module: vmware_datastore_cluster short_description: Manage VMware vSphere datastore clusters description: - This module can be used to add and delete datastore cluster in given VMware environment. - - All parameters and VMware object values are case sensitive. author: - Abhijeet Kasurde (@Akasurde) options: @@ -43,7 +42,6 @@ options: description: - Destination folder, absolute path to place datastore cluster in. - The folder should include the datacenter. - - This parameter is case sensitive. - You must specify either a O(folder) or a O(datacenter_name). - 'Examples:' - ' folder: /datacenter1/datastore' diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster_manager.py b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster_manager.py index b36b45af1..cfd7c0ea9 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster_manager.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_cluster_manager.py @@ -16,7 +16,6 @@ module: vmware_datastore_cluster_manager short_description: Manage VMware vSphere datastore cluster's members description: - This module can be used to add datastore in the datastore cluster. - - All parameters and VMware object values are case sensitive. author: - Abhijeet Kasurde (@Akasurde) options: 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 053c1bb1f..4c3fdc1e1 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_datastore_info.py @@ -16,7 +16,6 @@ module: vmware_datastore_info short_description: Gather info about datastores available in given vCenter description: - This module can be used to gather information about datastores in VMWare infrastructure. - - All values and VMware object names are case sensitive. author: - Tim Rightnour (@garbled1) options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_deploy_ovf.py b/ansible_collections/community/vmware/plugins/modules/vmware_deploy_ovf.py index 06ca29f74..da59cda4d 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_deploy_ovf.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_deploy_ovf.py @@ -36,14 +36,12 @@ options: - Cluster to deploy to. - This is a required parameter, if O(esxi_hostname) is not set and O(hostname) is set to the vCenter server. - O(esxi_hostname) and O(cluster) are mutually exclusive parameters. - - This parameter is case sensitive. type: str esxi_hostname: description: - The ESXi hostname where the virtual machine will run. - This is a required parameter, if O(cluster) is not set and O(hostname) is set to the vCenter server. - O(esxi_hostname) and O(cluster) are mutually exclusive parameters. - - This parameter is case sensitive. type: str datastore: default: datastore1 diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch.py b/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch.py index 604385568..4ab0d4c07 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_dvswitch.py @@ -167,7 +167,6 @@ options: description: - Destination folder, absolute path to place dvswitch in. - The folder should include the datacenter. - - This parameter is case sensitive. - Required if O(datacenter) is not provided. - Mutually exclusive with O(datacenter) parameter. - 'Examples:' @@ -195,6 +194,13 @@ options: type: int description: Identifies the information related to the switch. default: 0 + switch_ip: + type: str + description: + - Assign an IP address to see the distributed switch as a single network device in the NetFlow collector. + - This is instead of as multiple devices corresponding to each host. + - In an IPv6 environment, the ESXi hosts ignore the switch IP address. + version_added: '4.3.0' active_flow_timeout: type: int description: The time, in seconds, to wait before sending information after the flow is initiated. @@ -268,6 +274,7 @@ EXAMPLES = r''' collector_ip: 192.168.10.50 collector_port: 50034 observation_domain_id: 0 + switch_ip: 192.168.10.40 active_flow_timeout: 60 idle_flow_timeout: 15 sampling_rate: 4096 @@ -306,6 +313,7 @@ result: "net_flow_collector_ip": "192.168.10.50", "net_flow_collector_port": 50034, "net_flow_observation_domain_id": 0, + "net_flow_switch_ip": "192.168.10.40", "net_flow_active_flow_timeout": 60, "net_flow_idle_flow_timeout": 15, "net_flow_sampling_rate": 4096, @@ -393,6 +401,7 @@ class VMwareDvSwitch(PyVmomi): self.netFlow_collector_ip = self.module.params['net_flow'].get('collector_ip') or None self.netFlow_collector_port = self.module.params['net_flow'].get('collector_port') self.netFlow_observation_domain_id = self.module.params['net_flow'].get('observation_domain_id') + self.netFlow_switch_ip = self.module.params['net_flow'].get('switch_ip') self.netFlow_active_flow_timeout = self.module.params['net_flow'].get('active_flow_timeout') self.netFlow_idle_flow_timeout = self.module.params['net_flow'].get('idle_flow_timeout') self.netFlow_sampling_rate = self.module.params['net_flow'].get('sampling_rate') @@ -529,11 +538,13 @@ class VMwareDvSwitch(PyVmomi): results['net_flow_idle_flow_timeout'] = self.netFlow_idle_flow_timeout results['net_flow_sampling_rate'] = self.netFlow_sampling_rate results['net_flow_internal_flows_only'] = self.netFlow_internal_flows_only + results['net_flow_switch_ip'] = self.netFlow_switch_ip result = self.check_netFlow_config() - changed_netFlow = result[1] + changed_netFlow = result[2] if changed_netFlow: spec.ipfixConfig = result[0] + spec.switchIpAddress = result[1] if changed_multicast or changed_network_policy or changed_netFlow: self.update_dvs_config(self.dvs, spec) @@ -663,15 +674,22 @@ class VMwareDvSwitch(PyVmomi): def check_netFlow_config(self): """Check NetFlow config""" changed = changed_collectorIpAddress = changed_collectorPort = changed_observationDomainId = \ - changed_activeFlowTimeout = changed_idleFlowTimeout = changed_samplingRate = changed_internalFlowsOnly = False + changed_activeFlowTimeout = changed_idleFlowTimeout = changed_samplingRate = changed_internalFlowsOnly = \ + changed_switchIpAddress = False collectorIpAddress_previous = collectorPort_previous = observationDomainId_previous = activeFlowTimeout_previous = \ - idleFlowTimeout_previous = samplingRate_previous = internalFlowsOnly_previous = None + idleFlowTimeout_previous = samplingRate_previous = internalFlowsOnly_previous = switchIpAddress_previous = None current_config = self.dvs.config.ipfixConfig if current_config is None: new_config = vim.dvs.VmwareDistributedVirtualSwitch.IpfixConfig() else: new_config = current_config + current_switchIpAddress = self.dvs.config.switchIpAddress + if current_switchIpAddress is None: + new_config_spec = vim.dvs.VmwareDistributedVirtualSwitch.ConfigSpec() + new_switchIpAddress = new_config_spec.switchIpAddress + else: + new_switchIpAddress = current_switchIpAddress if self.netFlow_collector_ip is not None: if current_config.collectorIpAddress != self.netFlow_collector_ip: @@ -702,11 +720,16 @@ class VMwareDvSwitch(PyVmomi): changed = changed_internalFlowsOnly = True internalFlowsOnly_previous = current_config.internalFlowsOnly new_config.internalFlowsOnly = self.netFlow_internal_flows_only + if self.netFlow_switch_ip is not None and current_switchIpAddress != self.netFlow_switch_ip: + changed = changed_switchIpAddress = True + switchIpAddress_previous = current_switchIpAddress + new_switchIpAddress = self.netFlow_switch_ip - return (new_config, changed, changed_collectorIpAddress, collectorIpAddress_previous, + return (new_config, new_switchIpAddress, changed, changed_collectorIpAddress, collectorIpAddress_previous, changed_collectorPort, collectorPort_previous, changed_observationDomainId, observationDomainId_previous, changed_activeFlowTimeout, activeFlowTimeout_previous, changed_idleFlowTimeout, idleFlowTimeout_previous, - changed_samplingRate, samplingRate_previous, changed_internalFlowsOnly, internalFlowsOnly_previous) + changed_samplingRate, samplingRate_previous, changed_internalFlowsOnly, internalFlowsOnly_previous, + changed_switchIpAddress, switchIpAddress_previous) def exit_unchanged(self): """Exit with status message""" @@ -905,10 +928,12 @@ class VMwareDvSwitch(PyVmomi): results['net_flow_idle_flow_timeout'] = self.netFlow_idle_flow_timeout results['net_flow_sampling_rate'] = self.netFlow_sampling_rate results['net_flow_internal_flows_only'] = self.netFlow_internal_flows_only - (ipfixConfig, changed_netFlow, changed_collectorIpAddress, collectorIpAddress_previous, - changed_collectorPort, collectorPort_previous, changed_observationDomainId, observationDomainId_previous, - changed_activeFlowTimeout, activeFlowTimeout_previous, changed_idleFlowTimeout, idleFlowTimeout_previous, - changed_samplingRate, samplingRate_previous, changed_internalFlowsOnly, internalFlowsOnly_previous) = self.check_netFlow_config() + results['net_flow_switch_ip'] = self.netFlow_switch_ip + + (ipfixConfig, switchIpAddress_netFlow, changed_netFlow, changed_collectorIpAddress, collectorIpAddress_previous, + changed_collectorPort, collectorPort_previous, changed_observationDomainId, observationDomainId_previous, changed_activeFlowTimeout, + activeFlowTimeout_previous, changed_idleFlowTimeout, idleFlowTimeout_previous, changed_samplingRate, samplingRate_previous, + changed_internalFlowsOnly, internalFlowsOnly_previous, changed_switchIpAddress, switchIpAddress_previous) = self.check_netFlow_config() if changed_netFlow: changed = changed_settings = True changed_list.append("netFlow") @@ -926,8 +951,11 @@ class VMwareDvSwitch(PyVmomi): results['net_flow_sampling_rate_previous'] = samplingRate_previous if changed_internalFlowsOnly: results['net_flow_internal_flows_only_previous'] = internalFlowsOnly_previous + if changed_switchIpAddress: + results['net_flow_switch_ip_previous'] = switchIpAddress_previous config_spec.ipfixConfig = ipfixConfig + config_spec.switchIpAddress = switchIpAddress_netFlow if changed: if self.module.check_mode: @@ -1020,6 +1048,7 @@ def main(): collector_ip=dict(type='str'), collector_port=dict(type='int', default=0), observation_domain_id=dict(type='int', default=0), + switch_ip=dict(type='str'), active_flow_timeout=dict(type='int', default=60), idle_flow_timeout=dict(type='int', default=15), sampling_rate=dict(type='int', default=4096), diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_export_ovf.py b/ansible_collections/community/vmware/plugins/modules/vmware_export_ovf.py index 6ea440a4e..1c40cdfc3 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_export_ovf.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_export_ovf.py @@ -39,13 +39,11 @@ options: default: ha-datacenter description: - Datacenter name of the virtual machine to export. - - This parameter is case sensitive. type: str folder: description: - Destination folder, absolute path to find the specified guest. - The folder should include the datacenter. ESX datacenter is ha-datacenter. - - This parameter is case sensitive. - 'If multiple machines are found with same name, this parameter is used to identify' - 'Examples:' - ' folder: /ha-datacenter/vm' diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest.py index 1f5a0a818..eb3923038 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest.py @@ -64,7 +64,6 @@ options: identify uniqueness of the virtual machine. - This parameter is required, if O(state=poweredon), O(state=powered-on), O(state=poweredoff), O(state=powered-off), O(state=present), O(state=restarted), O(state=suspended) and virtual machine does not exists. - - This parameter is case sensitive. type: str name_match: description: @@ -89,7 +88,6 @@ options: - Template or existing virtual machine used to create new virtual machine. - If this value is not set, virtual machine is created without using a template. - If the virtual machine already exists, this parameter will be ignored. - - This parameter is case sensitive. - From version 2.8 onwards, absolute path to virtual machine or template can be used. aliases: [ 'template_src' ] type: str @@ -107,7 +105,6 @@ options: description: - Destination folder, absolute path to find an existing guest or create the new guest. - "The folder should include the datacenter. ESXi's datacenter is ha-datacenter." - - This parameter is case sensitive. - 'If multiple machines are found with same name, this parameter is used to identify' - 'uniqueness of the virtual machine.' - 'Examples:' @@ -126,7 +123,6 @@ options: default: {} description: - "Manage virtual machine's hardware attributes." - - All parameters case sensitive. suboptions: hotadd_cpu: type: bool @@ -243,7 +239,6 @@ options: default: {} description: - Manage virtual machine encryption settings - - All parameters case sensitive. version_added: '3.9.0' suboptions: encrypted_vmotion: @@ -258,7 +253,6 @@ options: type: str description: - Set the guest ID. - - This parameter is case sensitive. - This field is required when creating a virtual machine, not required when creating from the template. - > Valid values are referenced here: @@ -266,7 +260,6 @@ options: disk: description: - A list of disks to add. - - This parameter is case sensitive. - Shrinking disks is not supported. - Removing existing disks of the virtual machine is not supported. - 'Attributes O(disk.controller_type), O(disk.controller_number), O(disk.unit_number) are used to configure multiple types of disk @@ -419,7 +412,6 @@ options: resource_pool: description: - Use the given resource pool for virtual machine operation. - - This parameter is case sensitive. - Resource pool should be child of the selected host parent. - When not specified I(Resources) is taken as default value. type: str @@ -459,7 +451,6 @@ options: snapshot_src: description: - Name of the existing snapshot to use to create a clone of a virtual machine. - - This parameter is case sensitive. - While creating linked clone using O(linked_clone) parameter, this parameter is required. type: str linked_clone: @@ -485,7 +476,6 @@ options: datacenter: description: - Destination datacenter for the deploy operation. - - This parameter is case sensitive. default: ha-datacenter type: str cluster: @@ -493,14 +483,12 @@ options: - The cluster name where the virtual machine will run. - This is a required parameter, if O(esxi_hostname) is not set. - O(esxi_hostname) and O(cluster) are mutually exclusive parameters. - - This parameter is case sensitive. type: str esxi_hostname: description: - The ESXi hostname where the virtual machine will run. - This is a required parameter, if O(cluster) is not set. - O(esxi_hostname) and O(cluster) are mutually exclusive parameters. - - This parameter is case sensitive. type: str advanced_settings: description: @@ -527,10 +515,9 @@ options: description: - A list of networks (in the order of the NICs). - Removing NICs is not allowed, while reconfiguring the virtual machine. - - All parameters and VMware object names are case sensitive. - The I(type), I(ip), I(netmask), I(gateway), I(domain), I(dns_servers) options don't set to a guest when creating a blank new virtual machine. They are set by the customization via vmware-tools. - If you want to set the value of the options to a guest, you need to clone from a template with installed OS and vmware-tools(also Perl when Linux). + If you want to set the value of the options to a guest, you need to clone from a template with installed OS and vmware-tools (also Perl when Linux). type: list default: [] elements: dict @@ -648,7 +635,6 @@ options: - Not all operating systems are supported for customization with respective vCenter version, please check VMware documentation for respective OS customization. - For supported customization operating system matrix, (see U(http://partnerweb.vmware.com/programs/guestOS/guest-os-customization-matrix.pdf)) - - All parameters and VMware object names are case sensitive. - Linux based OSes requires Perl package to be installed for OS customizations. suboptions: existing_vm: @@ -747,7 +733,7 @@ options: orgname: type: str description: - - Organisation name. + - Organization name. - Specific to Windows customization. - If unset, "ACME" will be used as a fall-back. password: @@ -797,7 +783,6 @@ options: customization_spec: description: - Unique name identifying the requested customization specification. - - This parameter is case sensitive. - If set, then overrides O(customization) parameter values. type: str datastore: @@ -2670,6 +2655,7 @@ class PyVmomiHelper(PyVmomi): diskspec.device = disks[disk_index] else: diskspec = self.device_helper.create_hard_disk(scsi_ctl, disk_index) + diskspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add disk_modified = True # increment index for next disk search @@ -2698,11 +2684,10 @@ class PyVmomiHelper(PyVmomi): if expected_disk_spec['filename']: self.add_existing_vmdk(vm_obj, expected_disk_spec, diskspec, scsi_ctl) continue - if vm_obj is None or self.params['template']: - # We are creating new VM or from Template - # Only create virtual device if not backed by vmdk in original template - if diskspec.device.backing.fileName == '': - diskspec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.create + + # Only create virtual device if not backed by vmdk in original template + if diskspec.device.backing.fileName == '': + diskspec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.create # which datastore? if expected_disk_spec.get('datastore'): @@ -2977,6 +2962,14 @@ class PyVmomiHelper(PyVmomi): vm_obj = self.get_vm_or_template(template_name=self.params['template']) if vm_obj is None: self.module.fail_json(msg="Could not find a template named %(template)s" % self.params) + if self.params['guest_id'] is not None and vm_obj.summary.config.guestId is not None and self.params['guest_id'] != vm_obj.summary.config.guestId: + details = { + 'vm_guest_id': self.params['guest_id'], + 'template_guest_id': vm_obj.summary.config.guestId, + } + self.module.fail_json(msg="Could not create vm from template with different guest_ids", + details=details) + else: vm_obj = None diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_boot_manager.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_boot_manager.py index ad89e6aed..2700ff4ba 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_boot_manager.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_boot_manager.py @@ -53,7 +53,6 @@ options: elements: str boot_hdd_name: description: - - Name of disk to be set as boot disk, which is case sensitive, e.g., 'Hard disk 1'. - This parameter is optional, if not set, will use the first virtual disk found in VM device list. type: str version_added: '3.2.0' diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_controller.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_controller.py index df92a9a05..7084d9a21 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_controller.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_controller.py @@ -16,7 +16,6 @@ module: vmware_guest_controller short_description: Manage disk or USB controllers related to virtual machine in given vCenter infrastructure description: - This module can be used to add, remove disk controllers or USB controllers belonging to given virtual machine. - - All parameters and VMware object names are case sensitive. author: - Diane Wang (@Tomorrow9) <dianew@vmware.com> options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_cross_vc_clone.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_cross_vc_clone.py index 8d7c4abac..748948c5e 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_cross_vc_clone.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_cross_vc_clone.py @@ -83,7 +83,6 @@ options: destination_vm_folder: description: - Destination folder, absolute path to deploy the cloned vm. - - This parameter is case sensitive. - 'Examples:' - ' folder: vm' - ' folder: ha-datacenter/vm' diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_customization_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_customization_info.py index 3f97c533b..5fd637d36 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_customization_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_customization_info.py @@ -16,7 +16,6 @@ module: vmware_guest_customization_info short_description: Gather info about VM customization specifications description: - This module can be used to gather information about customization specifications. - - All parameters and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk.py index 56251b444..20ebc14ca 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk.py @@ -16,7 +16,6 @@ module: vmware_guest_disk short_description: Manage disks related to virtual machine in given vCenter infrastructure description: - This module can be used to add, remove and update disks belonging to given virtual machine. - - All parameters and VMware object names are case sensitive. - This module is destructive in nature, please read documentation carefully before proceeding. - Be careful while removing disk specified as this may lead to data loss. author: @@ -67,7 +66,6 @@ options: description: - A list of disks to add or remove. - The virtual disk related information is provided using this list. - - All values and parameters are case sensitive. suboptions: size: description: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk_info.py index 06c5d3565..2be78c64b 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_disk_info.py @@ -17,7 +17,6 @@ module: vmware_guest_disk_info short_description: Gather info about disks of given virtual machine description: - This module can be used to gather information about disks belonging to given virtual machine. - - All parameters and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) <akasurde@redhat.com> options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_instant_clone.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_instant_clone.py index 2b824338c..3b8c17972 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_instant_clone.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_instant_clone.py @@ -18,7 +18,6 @@ short_description: Instant Clone VM description: - This module can be used for Creating a powered-on Instant Clone of a virtual machine. -- All variables and VMware object names are case sensitive. - M(community.vmware.vmware_guest) module is needed for creating a VM with poweredon state which would be used as a parent VM. - M(community.vmware.vmware_guest_powerstate) module is also needed to poweroff the instant cloned module. - The powered off VM would in turn be deleted by again using M(community.vmware.vmware_guest) module. @@ -75,7 +74,6 @@ options: folder: description: - Destination folder, absolute path to deploy the cloned vm. - - This parameter is case sensitive. - 'Examples:' - 'folder: ha-datacenter/vm' - 'folder: /datacenter1/vm' diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_move.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_move.py index 53f27adb3..2b7e4ae5a 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_move.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_move.py @@ -49,7 +49,6 @@ options: description: - Absolute path to move an existing guest - The dest_folder should include the datacenter. ESX's datacenter is ha-datacenter. - - This parameter is case sensitive. - 'Examples:' - ' dest_folder: /ha-datacenter/vm' - ' dest_folder: ha-datacenter/vm' diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_powerstate.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_powerstate.py index aaff49d45..1391c6181 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_powerstate.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_powerstate.py @@ -21,7 +21,6 @@ options: datacenter: description: - The datacenter where the VM you'd like to operate the power. - - This parameter is case sensitive. default: ha-datacenter type: str state: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_register_operation.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_register_operation.py index bd99f1ca4..6873b35d5 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_register_operation.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_register_operation.py @@ -20,7 +20,6 @@ options: datacenter: description: - Destination datacenter for the register/unregister operation. - - This parameter is case sensitive. type: str default: ha-datacenter cluster: @@ -31,7 +30,6 @@ options: description: - Description folder, absolute path of the target folder. - The folder should include the datacenter. ESX's datacenter is ha-datacenter. - - This parameter is case sensitive. - 'Examples:' - ' folder: /ha-datacenter/vm' - ' folder: ha-datacenter/vm' @@ -53,7 +51,6 @@ options: esxi_hostname: description: - The ESXi hostname where the virtual machine will run. - - This parameter is case sensitive. type: str template: description: @@ -70,7 +67,6 @@ options: resource_pool: description: - Specify a resource pool name to register VM. - - This parameter is case sensitive. - Resource pool should be child of the selected host parent. type: str state: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_screenshot.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_screenshot.py index 7c71997c7..5ba4eb784 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_screenshot.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_screenshot.py @@ -16,7 +16,6 @@ module: vmware_guest_screenshot short_description: Create a screenshot of the Virtual Machine console. description: - This module is used to take screenshot of the given virtual machine when virtual machine is powered on. - - All parameters and VMware object names are case sensitive. author: - Diane Wang (@Tomorrow9) <dianew@vmware.com> options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_sendkey.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_sendkey.py index 8d1c56cff..5340a2da6 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_sendkey.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_sendkey.py @@ -16,7 +16,6 @@ module: vmware_guest_sendkey short_description: Send USB HID codes to the Virtual Machine's keyboard. description: - This module is used to send keystrokes to given virtual machine. - - All parameters and VMware object names are case sensitive. author: - Diane Wang (@Tomorrow9) <dianew@vmware.com> options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_snapshot.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_snapshot.py index da0cf5565..7d7dbfecd 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_snapshot.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_snapshot.py @@ -16,7 +16,6 @@ module: vmware_guest_snapshot short_description: Manages virtual machines snapshots in vCenter description: - This module can be used to create, delete and update snapshot(s) of the given virtual machine. - - All parameters and VMware object names are case sensitive. author: - Loic Blot (@nerzhul) <loic.blot@unix-experience.fr> options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_storage_policy.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_storage_policy.py index 2c855eac5..7ae239d85 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_storage_policy.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_storage_policy.py @@ -69,14 +69,12 @@ options: vm_home: description: - A storage profile policy to set on VM Home. - - All values and parameters are case sensitive. - At least one of O(disk) or O(vm_home) are required parameters. required: false type: str disk: description: - A list of disks with storage profile policies to enforce. - - All values and parameters are case sensitive. - At least one of O(disk) and O(vm_home) are required parameters. required: false type: list diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_info.py index e707cc82c..e01c25753 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_tools_info.py @@ -143,13 +143,18 @@ class PyVmomiHelper(PyVmomi): vm_ipaddress=self.current_vm_obj.summary.guest.ipAddress, vm_tools_running_status=self.current_vm_obj.summary.guest.toolsRunningStatus, vm_tools_install_status=self.current_vm_obj.summary.guest.toolsStatus, - vm_tools_version_status=self.current_vm_obj.summary.guest.toolsVersionStatus, + vm_tools_version_status=self.current_vm_obj.summary.guest.toolsVersionStatus2, vm_tools_install_type=self.current_vm_obj.config.tools.toolsInstallType, vm_tools_version=self.current_vm_obj.config.tools.toolsVersion, vm_tools_upgrade_policy=self.current_vm_obj.config.tools.toolsUpgradePolicy, vm_tools_last_install_count=self.current_vm_obj.config.tools.lastInstallInfo.counter, ) + self.module.deprecate( + msg="The API providing vm_tools_install_status has been deprecated by VMware; use vm_tools_running_status / vm_tools_version_status instead", + version="5.0.0", + collection_name="community.vmware" + ) return {'changed': False, 'failed': False, 'vmtools_info': vmtools_info} diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_tpm.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_tpm.py index 2b0178474..1e60caf2c 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_tpm.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_tpm.py @@ -52,7 +52,6 @@ options: datacenter: description: - The vCenter datacenter name used to get specified cluster or host. - - This parameter is case sensitive. type: str required: true state: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu.py index 1c8557681..b3ecd5244 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu.py @@ -16,7 +16,6 @@ module: vmware_guest_vgpu short_description: Modify vGPU video card profile of the specified virtual machine in the given vCenter infrastructure description: - This module is used to reconfigure vGPU card profile of the given virtual machine. - - All parameters and VMware object names are case sensitive. - VM must be power off M(community.vmware.vmware_guest_powerstate) module can perform that task. author: - Mohamed Alibi (@Medalibi) @@ -57,7 +56,6 @@ options: default: ha-datacenter description: - The datacenter name to which virtual machine belongs to. - - This parameter is case sensitive. type: str state: default: present diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu_info.py index 090c71588..1bdeae6f2 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_vgpu_info.py @@ -17,7 +17,6 @@ version_added: '3.3.0' short_description: Gather information about vGPU profiles of the specified virtual machine in the given vCenter infrastructure description: - This module is used to gather metadata about vGPU profiles of the given virtual machine. - - All parameters and VMware object names are case sensitive. author: - Jared Priddy (@jdptechnc) options: @@ -56,7 +55,6 @@ options: default: ha-datacenter description: - The datacenter name to which virtual machine belongs to. - - This parameter is case sensitive. type: str use_instance_uuid: description: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_guest_video.py b/ansible_collections/community/vmware/plugins/modules/vmware_guest_video.py index de5e4c628..62c3ad9c7 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_guest_video.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_guest_video.py @@ -16,7 +16,6 @@ module: vmware_guest_video short_description: Modify video card configurations of specified virtual machine in given vCenter infrastructure description: - This module is used to reconfigure video card settings of given virtual machine. - - All parameters and VMware object names are case sensitive. author: - Diane Wang (@Tomorrow9) <dianew@vmware.com> options: @@ -55,7 +54,6 @@ options: default: ha-datacenter description: - The datacenter name to which virtual machine belongs to. - - This parameter is case sensitive. type: str gather_video_facts: description: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_host_datastore.py b/ansible_collections/community/vmware/plugins/modules/vmware_host_datastore.py index db8b9be91..fa41c0ade 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_host_datastore.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_host_datastore.py @@ -18,7 +18,6 @@ description: - This module can be used to mount/umount datastore on ESXi host. - This module only supports NFS (NFS v3 or NFS v4.1) and VMFS datastores. - For VMFS datastore, available device must already be connected on ESXi host. -- All parameters and VMware object names are case sensitive. author: - Ludovic Rivallain (@lrivallain) <ludovic.rivallain@gmail.com> - Christian Kotte (@ckotte) <christian.kotte@gmx.de> diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_host_dns_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_host_dns_info.py index bee8c58eb..b03c25d42 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_host_dns_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_host_dns_info.py @@ -15,7 +15,6 @@ module: vmware_host_dns_info short_description: Gathers info about an ESXi host's DNS configuration information description: - This module can be used to gather information about an ESXi host's DNS configuration information when ESXi hostname or Cluster name is given. -- All parameters and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) options: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown.py b/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown.py index 023f116b7..a5b1da457 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown.py @@ -15,7 +15,6 @@ module: vmware_host_lockdown short_description: Manage administrator permission for the local administrative account for the ESXi host description: - This module can be used to manage administrator permission for the local administrative account for the host when ESXi hostname is given. -- All parameters and VMware objects values are case sensitive. - This module is destructive as administrator permission are managed using APIs used, please read options carefully and proceed. - Please specify O(hostname) as vCenter IP or hostname only, as lockdown operations are not possible from standalone ESXi server. author: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown_exceptions.py b/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown_exceptions.py index 892daeb39..709243ee0 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown_exceptions.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_host_lockdown_exceptions.py @@ -16,7 +16,6 @@ version_added: '3.1.0' short_description: Manage Lockdown Mode Exception Users description: - This module can be used to manage Lockdown Mode Exception Users. -- All parameters and VMware objects values are case sensitive. - Please specify O(hostname) as vCenter IP or hostname only, as lockdown operations are not possible from standalone ESXi server. author: - Mario Lenz (@mariolenz) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_host_scanhba.py b/ansible_collections/community/vmware/plugins/modules/vmware_host_scanhba.py index 0087c8a2c..54addd438 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_host_scanhba.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_host_scanhba.py @@ -18,7 +18,6 @@ description: - This module can force a rescan of the hosts HBA subsystem which is needed when wanting to mount a new datastore. - You could use this before using M(community.vmware.vmware_host_datastore) to mount a new datastore to ensure your device/volume is ready. - You can also optionally force a Refresh of the Storage System in vCenter/ESXi Web Client. -- All parameters and VMware object names are case sensitive. - You can supply an esxi_hostname or a cluster_name author: - Michael Eaton (@michaeldeaton) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_local_user_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_local_user_info.py index bd4ef522f..d5bf17e35 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_local_user_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_local_user_info.py @@ -16,7 +16,6 @@ module: vmware_local_user_info short_description: Gather info about users on the given ESXi host description: - This module can be used to gather information about users present on the given ESXi host system in VMware infrastructure. - - All variables and VMware object names are case sensitive. - User must hold the 'Authorization.ModifyPermissions' privilege to invoke this module. author: - Abhijeet Kasurde (@Akasurde) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_object_rename.py b/ansible_collections/community/vmware/plugins/modules/vmware_object_rename.py index 8f5cbb752..6b5be8471 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_object_rename.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_object_rename.py @@ -15,7 +15,6 @@ module: vmware_object_rename short_description: Renames VMware objects description: - This module can be used to rename VMware objects. -- All variables and VMware object names are case sensitive. - Renaming Host and Network is not supported by VMware APIs. author: - Abhijeet Kasurde (@Akasurde) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_tag.py b/ansible_collections/community/vmware/plugins/modules/vmware_tag.py index c37f310a7..fdb33c811 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_tag.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_tag.py @@ -17,7 +17,6 @@ short_description: Manage VMware tags description: - This module can be used to create / delete / update VMware tags. - Tag feature is introduced in vSphere 6 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_tag_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_tag_info.py index 25132efa8..fcc545576 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_tag_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_tag_info.py @@ -17,7 +17,6 @@ short_description: Manage VMware tag info description: - This module can be used to collect information about VMware tags. - Tag feature is introduced in vSphere 6 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_tag_manager.py b/ansible_collections/community/vmware/plugins/modules/vmware_tag_manager.py index 109188b45..d78a5a3dc 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_tag_manager.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_tag_manager.py @@ -17,7 +17,6 @@ short_description: Manage association of VMware tags with VMware objects description: - This module can be used to assign / remove VMware tags from the given VMware objects. - Tag feature is introduced in vSphere 6 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Abhijeet Kasurde (@Akasurde) - Frederic Van Reet (@GBrawl) diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_vc_infraprofile_info.py b/ansible_collections/community/vmware/plugins/modules/vmware_vc_infraprofile_info.py index a4312e62e..af5594416 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_vc_infraprofile_info.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_vc_infraprofile_info.py @@ -17,7 +17,6 @@ short_description: List and Export VMware vCenter infra profile configs. description: - Module to manage VMware vCenter infra profile configs. - vCenter infra profile Library feature is introduced in vSphere 7.0 version, so this module is not supported in the earlier versions of vSphere. -- All variables and VMware object names are case sensitive. author: - Naveenkumar G P (@ngp) requirements: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_vm_config_option.py b/ansible_collections/community/vmware/plugins/modules/vmware_vm_config_option.py index fd1e67837..9201d2724 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_vm_config_option.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_vm_config_option.py @@ -26,7 +26,6 @@ options: datacenter: description: - The datacenter name used to get specified cluster or host. - - This parameter is case sensitive. default: ha-datacenter type: str cluster_name: diff --git a/ansible_collections/community/vmware/plugins/modules/vmware_vm_shell.py b/ansible_collections/community/vmware/plugins/modules/vmware_vm_shell.py index 76f1d5308..51d1230eb 100644 --- a/ansible_collections/community/vmware/plugins/modules/vmware_vm_shell.py +++ b/ansible_collections/community/vmware/plugins/modules/vmware_vm_shell.py @@ -47,6 +47,7 @@ options: - ' folder: /folder1/datacenter1/vm' - ' folder: folder1/datacenter1/vm' - ' folder: /folder1/datacenter1/vm/folder2' + - Required if O(vm_id_type=inventory_path) type: str vm_id: description: diff --git a/ansible_collections/community/vmware/scripts/inventory/vmware_inventory.py b/ansible_collections/community/vmware/scripts/inventory/vmware_inventory.py index 618e09e20..c265a2620 100644 --- a/ansible_collections/community/vmware/scripts/inventory/vmware_inventory.py +++ b/ansible_collections/community/vmware/scripts/inventory/vmware_inventory.py @@ -283,7 +283,7 @@ class VMWareInventory(object): self.maxlevel = int(config.get('vmware', 'max_object_level')) self.debugl('max object level is %s' % self.maxlevel) self.lowerkeys = config.get('vmware', 'lower_var_keys') - if type(self.lowerkeys) != bool: + if not isinstance(self.lowerkeys, bool): if str(self.lowerkeys).lower() in ['yes', 'true', '1']: self.lowerkeys = True else: diff --git a/ansible_collections/community/vmware/tests/sanity/ignore-2.18.txt b/ansible_collections/community/vmware/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..4a0d49a7d --- /dev/null +++ b/ansible_collections/community/vmware/tests/sanity/ignore-2.18.txt @@ -0,0 +1,4 @@ +plugins/modules/vmware_deploy_ovf.py replace-urlopen!skip +plugins/modules/vmware_deploy_ovf.py use-argspec-type-path!skip +scripts/inventory/vmware_inventory.py pep8!skip +tests/unit/mock/loader.py pep8!skip diff --git a/ansible_collections/community/vmware/tests/unit/mock/loader.py b/ansible_collections/community/vmware/tests/unit/mock/loader.py index e5dff78c1..edeac4526 100644 --- a/ansible_collections/community/vmware/tests/unit/mock/loader.py +++ b/ansible_collections/community/vmware/tests/unit/mock/loader.py @@ -30,7 +30,7 @@ class DictDataLoader(DataLoader): def __init__(self, file_mapping=None): file_mapping = {} if file_mapping is None else file_mapping - assert type(file_mapping) == dict + assert isinstance(file_mapping, dict) super(DictDataLoader, self).__init__() |