diff options
Diffstat (limited to 'ansible_collections/hetzner')
157 files changed, 2048 insertions, 1769 deletions
diff --git a/ansible_collections/hetzner/hcloud/.ansible-lint b/ansible_collections/hetzner/hcloud/.ansible-lint index b8282450d..aaa42e776 100644 --- a/ansible_collections/hetzner/hcloud/.ansible-lint +++ b/ansible_collections/hetzner/hcloud/.ansible-lint @@ -11,12 +11,10 @@ exclude_paths: - tests/integration/targets/load_balancer_network - tests/integration/targets/load_balancer_service - tests/integration/targets/load_balancer_target - - tests/integration/targets/network - tests/integration/targets/placement_group - tests/integration/targets/primary_ip - tests/integration/targets/route - tests/integration/targets/server - - tests/integration/targets/server_network - tests/integration/targets/ssh_key - tests/integration/targets/volume diff --git a/ansible_collections/hetzner/hcloud/.azure-pipelines/azure-pipelines.yml b/ansible_collections/hetzner/hcloud/.azure-pipelines/azure-pipelines.yml index 8300381b4..aaf5c21e6 100644 --- a/ansible_collections/hetzner/hcloud/.azure-pipelines/azure-pipelines.yml +++ b/ansible_collections/hetzner/hcloud/.azure-pipelines/azure-pipelines.yml @@ -77,16 +77,6 @@ stages: - name: Sanity test: 2.14/sanity - - stage: Sanity_2_13 - displayName: Sanity 2.13 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: Sanity - test: 2.13/sanity - ### Units - stage: Units_devel displayName: Units devel @@ -128,16 +118,6 @@ stages: - name: (py3.9) test: 2.14/units/3.9 - - stage: Units_2_13 - displayName: Units 2.13 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - targets: - - name: (py3.8) - test: 2.13/units/3.8 - ## Integration - stage: Integration_devel displayName: Integration devel @@ -183,17 +163,6 @@ stages: - name: (py3.9) test: 2.14/integration/3.9 - - stage: Integration_2_13 - displayName: Integration 2.13 - dependsOn: [] - jobs: - - template: templates/matrix.yml - parameters: - groups: [1, 2, 3] - targets: - - name: (py3.8) - test: 2.13/integration/3.8 - ### Finally - stage: Summary condition: succeededOrFailed() @@ -202,16 +171,13 @@ stages: - Sanity_2_16 - Sanity_2_15 - Sanity_2_14 - - Sanity_2_13 - Units_devel - Units_2_16 - Units_2_15 - Units_2_14 - - Units_2_13 - Integration_devel - Integration_2_16 - Integration_2_15 - Integration_2_14 - - Integration_2_13 jobs: - template: templates/coverage.yml diff --git a/ansible_collections/hetzner/hcloud/.github/release-please-manifest.json b/ansible_collections/hetzner/hcloud/.github/release-please-manifest.json index b2b35cf9b..c313fd610 100644 --- a/ansible_collections/hetzner/hcloud/.github/release-please-manifest.json +++ b/ansible_collections/hetzner/hcloud/.github/release-please-manifest.json @@ -1 +1 @@ -{".":"2.5.0"} +{".":"3.1.1"} diff --git a/ansible_collections/hetzner/hcloud/.gitlab-ci.yml b/ansible_collections/hetzner/hcloud/.gitlab-ci.yml index 3387f825b..a18356f58 100644 --- a/ansible_collections/hetzner/hcloud/.gitlab-ci.yml +++ b/ansible_collections/hetzner/hcloud/.gitlab-ci.yml @@ -25,7 +25,7 @@ sanity: - tags parallel: matrix: - - ANSIBLE_VERSION: ["devel", "2.13", "2.14", "2.15"] + - ANSIBLE_VERSION: ["devel", "2.14", "2.15"] GROUP: [1] script: - bash tests/utils/gitlab/gitlab.sh ${ANSIBLE_VERSION}/sanity/${GROUP} diff --git a/ansible_collections/hetzner/hcloud/.pre-commit-config.yaml b/ansible_collections/hetzner/hcloud/.pre-commit-config.yaml index d1d1c6a4d..8ce6dcf4e 100644 --- a/ansible_collections/hetzner/hcloud/.pre-commit-config.yaml +++ b/ansible_collections/hetzner/hcloud/.pre-commit-config.yaml @@ -4,7 +4,7 @@ exclude: ^plugins/module_utils/vendor/hcloud/.*$ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -28,7 +28,7 @@ repos: exclude: ^changelogs/(dev-changelog\.md|changelog\.yaml)$ - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.2 hooks: - id: pyupgrade args: [--py38-plus] @@ -39,24 +39,24 @@ repos: - id: isort - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.1.1 + rev: 24.4.0 hooks: - id: black - repo: https://github.com/ansible-community/antsibull-changelog - rev: 0.23.0 + rev: 0.26.0 hooks: - id: antsibull-changelog-lint - id: antsibull-changelog-lint-changelog-yaml - repo: https://github.com/ansible/ansible-lint - rev: v6.22.2 + rev: v24.2.2 hooks: - id: ansible-lint name: ansible-lint args: [--offline] additional_dependencies: - - ansible-core>=2.13.3 + - ansible-core>=2.14 - netaddr - repo: local diff --git a/ansible_collections/hetzner/hcloud/CHANGELOG.rst b/ansible_collections/hetzner/hcloud/CHANGELOG.rst index 2a40778f4..3ef5b1595 100644 --- a/ansible_collections/hetzner/hcloud/CHANGELOG.rst +++ b/ansible_collections/hetzner/hcloud/CHANGELOG.rst @@ -4,6 +4,61 @@ Hetzner Cloud Ansible Collection Release Notes .. contents:: Topics +v3.1.1 +====== + +Bugfixes +-------- + +- inventory - Ensure inventory host variables are serializable and can be cached. + +v3.1.0 +====== + +Minor Changes +------------- + +- primary_ip - Use the `server` option to assign a Primary IP being created to a server. +- server - Allow passing Datacenter name or ID to the `datacenter` argument. +- server - Allow passing Image name or ID to the `image` argument. +- server - Allow passing Location name or ID to the `location` argument. +- server - Allow passing SSH Keys names or IDs to the `ssh_keys` argument. +- server - Allow passing Volume names or IDs to the `volumes` argument. +- server - Renamed the `allow_deprecated_image` option to `image_allow_deprecated`. + +Bugfixes +-------- + +- primary_ip - Added the missing `auto_delete` field to the return values. +- primary_ip - The `auto_delete` option is now used when creating or updating a Primary IP. +- primary_ip_info - Added the missing `auto_delete` field to the return values. +- server - Do not remove the server from its placement group when the `placement_group` argument is not specified. +- server - Pass an empty string to the `placement_group` argument to remove a server from its placement group. +- server_network - The returned `alias_ips` list is now sorted. + +v3.0.0 +====== + +Minor Changes +------------- + +- inventory - Add `hostname` option used to template the hostname of the instances. +- network - Allow renaming networks. + +Breaking Changes / Porting Guide +-------------------------------- + +- Drop support for ansible-core 2.13. +- certificate - The `not_valid_before` and `not_valid_after` values are now returned as ISO-8601 formatted strings. +- certificate_info - The `not_valid_before` and `not_valid_after` values are now returned as ISO-8601 formatted strings. +- inventory - Remove the deprecated `api_token_env` option, you may use the `ansible.builtin.env` lookup as alternative. +- iso_info - The `deprecated` value is now returned as ISO-8601 formatted strings. + +Bugfixes +-------- + +- load_balancer_info - Correctly return the `cookie_lifetime` value. +- load_balancer_service - Correctly return the `cookie_lifetime` value. v2.5.0 ====== diff --git a/ansible_collections/hetzner/hcloud/FILES.json b/ansible_collections/hetzner/hcloud/FILES.json index 7fc09f2f0..8a784cf6b 100644 --- a/ansible_collections/hetzner/hcloud/FILES.json +++ b/ansible_collections/hetzner/hcloud/FILES.json @@ -109,7 +109,7 @@ "name": ".azure-pipelines/azure-pipelines.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "2caa1318c14d2aa8d9ea75178d1fd142762b00712708d0dced4482bb254db4da", + "chksum_sha256": "cb7fba963afef16466bd794e359b91b9b6458acf64201f073603f849bba95ab8", "format": 1 }, { @@ -165,7 +165,7 @@ "name": ".github/release-please-manifest.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "042044c5e6e65c58917f2ca482ea5c6ba22d79d9cd6cd42f422ac9e041573955", + "chksum_sha256": "452a1b09a942c02e79c75643dc76181261d8d33b371a67de101e3437d9742309", "format": 1 }, { @@ -200,7 +200,7 @@ "name": "changelogs/changelog.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be4d9f48a034d816590f2e2d5d3f3fe866273f355963f9ad4ab67460b0e72b76", + "chksum_sha256": "525f7af28d069f1f418d7ec67d6ec49d64d02c404e9956dd8b0225c757e35012", "format": 1 }, { @@ -214,7 +214,7 @@ "name": "changelogs/dev-changelog.md", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ac62c11d1513004587ad3042473970d71d5f767e468f0e42905556df0456bc6c", + "chksum_sha256": "44232c68c5766f09ca5a57188dafcdb9d5fc5808335270d0424753609488bec3", "format": 1 }, { @@ -312,7 +312,7 @@ "name": "meta/runtime.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d5bd163e45ad774369d04d500f630d969dd3305dfe292cd49406c5d3912c3bb1", + "chksum_sha256": "9ea46a78c28566419b1580d17a2a953cc882657e7efa7f1507d1f4f340865609", "format": 1 }, { @@ -361,7 +361,7 @@ "name": "plugins/inventory/hcloud.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ab8a8501df0fca5d3947fbebb82a979ec23e3ff03752fedcf8a1a94b427ff76f", + "chksum_sha256": "c5cf395f3f98db8d4206dddbdd6d5e99e3f0572cdbb52433c2df39f52f5b729e", "format": 1 }, { @@ -466,7 +466,7 @@ "name": "plugins/module_utils/vendor/hcloud/core/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6ccbb73a325759635e5259657164db8f29de49c6b45d7ae1bca3abed12198c0d", + "chksum_sha256": "b43bb979ef79e056fce148043117b6fac30a0fa82f78197eedae8d0f4cc28069", "format": 1 }, { @@ -543,7 +543,7 @@ "name": "plugins/module_utils/vendor/hcloud/firewalls/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5dae67805c04fc8edf2d7d80501fdb52f03e6d2225bc4d196c9fa16893322a21", + "chksum_sha256": "aa376bb455d70faa5a2698c58948700b33af31fdf4a185af57c1e5198fffaf2b", "format": 1 }, { @@ -571,7 +571,7 @@ "name": "plugins/module_utils/vendor/hcloud/floating_ips/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5f08d0091db38b48e8984c2cc7d56150dd9fe4cd8f0b606b81f699dc816ff194", + "chksum_sha256": "ff2ab946fecfe020473fe0b59f2398f8bbc59e9f00c574281aa709f19cb913a8", "format": 1 }, { @@ -613,7 +613,7 @@ "name": "plugins/module_utils/vendor/hcloud/images/client.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1c2ac5b28d51381625fb7f667173ff0f66ab45f78ced21dbcd1feb26662b2c62", + "chksum_sha256": "76e372d76df1dedbbf072a4f693c2a352f8c61a52d06c32faa3659cd0e87ce38", "format": 1 }, { @@ -704,7 +704,7 @@ "name": "plugins/module_utils/vendor/hcloud/load_balancers/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "040f6ed68c8a9a3c17e3844a84cee66e8c8aa65d9d198008b2a159dbf2c248c2", + "chksum_sha256": "4e98cfc6d81c9080567c5c6d87b14a9cb6b97a81237afe17697f8cf59c88ade5", "format": 1 }, { @@ -781,7 +781,7 @@ "name": "plugins/module_utils/vendor/hcloud/networks/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "966de8dfbde97299aa023f3782aed0d0125c6cca3381a793908721fb0581e29e", + "chksum_sha256": "c0f687b9f679f48134b30e9721010e134f145911794d3f574df554bca063f6a0", "format": 1 }, { @@ -809,7 +809,7 @@ "name": "plugins/module_utils/vendor/hcloud/placement_groups/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c45a8e918b2ad87c7393180da6a1798a1d31ab69099cef858feff9e05caf28db", + "chksum_sha256": "cd76dcfd57be70e24967f00588dc577299148abf3f235d22f755d5e5909e5100", "format": 1 }, { @@ -837,7 +837,7 @@ "name": "plugins/module_utils/vendor/hcloud/primary_ips/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5e19cd121863e11beab0981443834f28f4a75094a0c7e0a5a061401f2e4f63c2", + "chksum_sha256": "1300517378c1e8f6d101320e34d4b474db47e6ede7978dca3039210958a29a24", "format": 1 }, { @@ -893,7 +893,7 @@ "name": "plugins/module_utils/vendor/hcloud/servers/domain.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1d3f2802d9bcfe35a430f1f52986c353da6601deb864d496f2ec9d5a2d0cc4aa", + "chksum_sha256": "2e654701ac99e8efaaa192dd3a4a4c9aa3068edb40d691b02af310c8f78772d6", "format": 1 }, { @@ -977,7 +977,7 @@ "name": "plugins/module_utils/vendor/hcloud/_version.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3480ae676e9f8016a95ede33f2afba76e90a15747c9a568ea19164c4a4819289", + "chksum_sha256": "1ece049e077b5c8c3a5f67c4d9272668a227ecd22ec5ac8d07a8ede8fbc1d4df", "format": 1 }, { @@ -1019,14 +1019,14 @@ "name": "plugins/module_utils/hcloud.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "757b549f7087e0a78b69143c190177f46344d1ba510d3b17d34e73534c129b4f", + "chksum_sha256": "a405ed9424bd38a924ca0062ddf40f047faed5bee36954e28adad90ec4c4b086", "format": 1 }, { "name": "plugins/module_utils/version.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ba0c1aca62f6adfabff56202492b5d4941e5ff0a5ef3686821cc046e882baca3", + "chksum_sha256": "7466f47c316d7323ee6776953807350f60d2f90f82f5cb5fe3c1090becbacb66", "format": 1 }, { @@ -1047,231 +1047,231 @@ "name": "plugins/modules/certificate.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "09c842e0a9d0933c9abd6d5fae99e861e3a85dcbbcdd21d3ac91287e3ac8b086", + "chksum_sha256": "b6c9c50d48a7451f8e4c1da4b01cde2d733e11e43a5381b3e4bcadb19540597a", "format": 1 }, { "name": "plugins/modules/certificate_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "f8f161a4e958682a52dbfec80232469482a7017d5eb9fc33c62fac1a8a25e06c", + "chksum_sha256": "fe57d2e3810c90c4b25bc2d3019f6d7167df92714ca2a5ad3ed72b98561b96d4", "format": 1 }, { "name": "plugins/modules/datacenter_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "72c739e5039fa088da5705985099c2a089546971d2e312ba836f8e9338d10c58", + "chksum_sha256": "84825fdb060c721fb6b88d2bce50f8f5514e93ed05c130395ee9359eb3019b7d", "format": 1 }, { "name": "plugins/modules/firewall.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "376cdd1493b06f30375afa678898262f1f60061ddff3c8b9269681cc190d3353", + "chksum_sha256": "e5a5ff659a468f99c6be5f9f0f8dc6249217ceff3da0e0734272457fd0f37ac1", "format": 1 }, { "name": "plugins/modules/firewall_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "981f7f9230b0046aebd6b1dee180e52c81b88f79e560d38f7398e49cc20210ba", + "chksum_sha256": "bc3dfb1050ef837e171cdfd14dca09fdbad23e7e43bd9a9f24c59c72d7aae98b", "format": 1 }, { "name": "plugins/modules/firewall_resource.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "04a07b4ecaa1549c3fa8e6d79e11c98d360a8602bcb36faf1c3c8bf3166f2b2f", + "chksum_sha256": "a6f27e0dac6e27b90a1c41924e7f315e4b7aff9f2bd2fb7bed09b18f9194615d", "format": 1 }, { "name": "plugins/modules/floating_ip.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "3d716b8875aad3a6aa7ac4dab5070c1959e4829fc283a606dafbaa4ced11ccbb", + "chksum_sha256": "2c6461a03116926636f95e6450927a8a7cd245cde37e4d3c52cae6f08e17e2d0", "format": 1 }, { "name": "plugins/modules/floating_ip_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "907a9c87aaaabf470f08a49d1407b8f6e2991988f5d9ee5f53562f3d9ffff3b4", + "chksum_sha256": "1f773dd7e6e195578cf9bf861f5773b70bd2587af07314864d13ddeb7baee270", "format": 1 }, { "name": "plugins/modules/image_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "e66fedae39facbc1d89b4cd7be1813b980f294990cf3799dc4554833cb43bb81", + "chksum_sha256": "7439259793e503b280170956973966fa624555583824b27a3102aa1a37106873", "format": 1 }, { "name": "plugins/modules/iso_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9366ae2eb9d6fb18d02bd82c776eb6c92ef0e47087aae86dd3b7c2be87f0ae8c", + "chksum_sha256": "c9ea2879d3cfffd1881950771181bc414c2b317674a24eec11f44094e8c5e71e", "format": 1 }, { "name": "plugins/modules/load_balancer.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b4f3515b0a9f2eff4907025f7a852d017084e2ab4fc60512a5d97b8f32b9f106", + "chksum_sha256": "d2c5e520bdfe044eb4721809691019efa98f7b90376cfd3fcd4d4e401810fe10", "format": 1 }, { "name": "plugins/modules/load_balancer_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "707101d55ed354171668ec60f1c0769de8976d5fad9c9001a90199e075ed2280", + "chksum_sha256": "68dbf2f84404f92d51fa021b0ec79c11fefbbd53b8fb944e6d3a762115047191", "format": 1 }, { "name": "plugins/modules/load_balancer_network.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "29bc3cc6725abc235f597ce9ebb074613cd74788c135bf6b896ba5e42a9b056d", + "chksum_sha256": "fa761743dfb898e535f125467ffedd6164b28cb3d70c40ebaa091881b3bf8023", "format": 1 }, { "name": "plugins/modules/load_balancer_service.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c40d3e075bc53481bce19d3e50a0f216075c1da864e00bc0b4c1bea2b347f4f5", + "chksum_sha256": "c29477d46b8b82cda49fb978f2a4063c176a1048b0077843aacc041e53ca9321", "format": 1 }, { "name": "plugins/modules/load_balancer_target.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ee8c10b5a44fd09723854cb3dd814d1e4f1dea0a5f62107a75ef81bd2e4f2ca3", + "chksum_sha256": "41aa1b537bcc941d0c2043a903bb5b03b7d569dd01abc06a8c77036c38f6dc66", "format": 1 }, { "name": "plugins/modules/load_balancer_type_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "302a5953254603e46ecac5fb04021228f13ca2e66b67a4dfd57fdbaef4fc3153", + "chksum_sha256": "81d3d7db68a3f20260777232953251afe9f5790cd470ecea6950fb4f3baf2c53", "format": 1 }, { "name": "plugins/modules/location_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "15571d3c16960ff15fad111d9602d688acbdd49febc5314a9fc0d57841b07c40", + "chksum_sha256": "be6e30b3877597b97a27c60459f01a607f96e8f9dd20fb099171ee8dba963bff", "format": 1 }, { "name": "plugins/modules/network.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7a1eb9cfafb175e0ca130179a0f692263b98823897bc036565d2a48ed723c4ff", + "chksum_sha256": "154f8309be228781449981b74a2033dafb00d0ce05728cfb9a2b4d2e3288cd5d", "format": 1 }, { "name": "plugins/modules/network_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d89fee964c48a06d0255049ad9981fb4184af29d94a6d4290defb0d54529253f", + "chksum_sha256": "0fd0ac3f386c798890f6deac1cfcab679ee051991287098469a300248243035c", "format": 1 }, { "name": "plugins/modules/placement_group.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8a77ff1cefd870cce48b03d1a344eca233ed7de3a469977c8b9d35bfb4f18ac0", + "chksum_sha256": "132d24fa570a56c7481cea6b1416c7b6980c830a9b9b1086b0f9808d5c8d3010", "format": 1 }, { "name": "plugins/modules/primary_ip.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8642642c6e944824959d671dd536c45f0fcf4c02515515749c56ee0e7778a548", + "chksum_sha256": "823b85d119057f22e29a665a5700e3711afaeeead1274b0ce27f8491864de5e7", "format": 1 }, { "name": "plugins/modules/primary_ip_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a5957f795d0abb11f0389d6d9bc6f1aafb4ff09ed52b0baf48cf593dd3a8507f", + "chksum_sha256": "936d28e9b7fef3833ddb0e370e003e3776bc96f21e0489fc620d4a80f11d086e", "format": 1 }, { "name": "plugins/modules/rdns.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9734b7c3f08137511a5f6c122e95c3ea003e5f9dc69e12076f5bf5c6614a0d8a", + "chksum_sha256": "47a9a4da94109edbe8d957b72a166fe91cace43ca916907fe9f81e2394d400a9", "format": 1 }, { "name": "plugins/modules/route.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1b7f689e4ff302ef28daf7a80b07835b6b6da96f545ec1abdd5213d089a8a4e7", + "chksum_sha256": "2ef1f610f62d62f476036d201857abb2cc0290e5d530be3d594b33f646c4be6f", "format": 1 }, { "name": "plugins/modules/server.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a451eac9d2620aba7956e52729842ab4f3297954c0dfcb074d7d2b71a4bed90d", + "chksum_sha256": "e739024f0a843baabf1542d1bfaacd7a8387409cae4f7df2e08ca0b2015163c0", "format": 1 }, { "name": "plugins/modules/server_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cb88b4ff41204761144380ed9854388f53df45e1bd6da6e8da9446ba128ce9e3", + "chksum_sha256": "0ccf126ef04ff8db2d394abc725a3c7b7707ed3ad079ecf327dcd273e2a70ffe", "format": 1 }, { "name": "plugins/modules/server_network.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "376f6464ab45438fa5e5f04168c8d666aaab3ee3916daf6bad6bd64c5349cc5f", + "chksum_sha256": "0fbabbf31c6b7d2c34a309c8865612347e418635089bdbf4bfbbb451f275919c", "format": 1 }, { "name": "plugins/modules/server_type_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b0f5c0186d54da14115c2a65867e80b7fae4a60e49a7e385faad192ac572d87a", + "chksum_sha256": "5415a22a580d91a15d7a4a646d14c4753fbe9f096f44e205ac226016cc4c00d0", "format": 1 }, { "name": "plugins/modules/ssh_key.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9560f0f9d6ac83fa89acaa7986308cd04d0e4e7464f5fe115c567173fbcdb9f8", + "chksum_sha256": "618938f3a602cad78f498edd71e2f8899fa96af736f790847f9f663509998c81", "format": 1 }, { "name": "plugins/modules/ssh_key_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ab0a6ea5ffdb1f98525be155ff1e999abdf7d10056c45ef5b2a203803b455606", + "chksum_sha256": "1d424bb04603ea341ba7bdd840979ab50c4d53f43f5278cde7c9229d5ea737fa", "format": 1 }, { "name": "plugins/modules/subnetwork.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "908458ed99857ebd8dd05ef3eaf18786beaa8877657bf464ae8481082c9f3699", + "chksum_sha256": "85c7e6ecb4b7a849f210b0234fdb0a299a0c6c1a1f77511cce66f195a15c8f32", "format": 1 }, { "name": "plugins/modules/volume.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0b9363ac9df20b307046c6f8ec1f05c93660e020ff831117a1e74144820aa47f", + "chksum_sha256": "19f99fdb4aa2ca35b675d1144053ef8699fc04824314c6bee78ffc196e7411b0", "format": 1 }, { "name": "plugins/modules/volume_info.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5cb42a56726cab37af48ce4f6742efbadcb413ecdfac82bfbf1852f46cfa9a5e", + "chksum_sha256": "22466e5279e3a5310b69efc919ada00e2e9f01f32b581ec9d220f8a4439d29d2", "format": 1 }, { @@ -1299,7 +1299,7 @@ "name": "scripts/vendor.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d750276690c449d94acffc1c4a65b3d53279f09297a6c296ba99a5b4bc2ed6b9", + "chksum_sha256": "cdf751a10893cc8ac851c9b3bfb3da6a63332a94cec343992dfb36ed24155634", "format": 1 }, { @@ -1341,7 +1341,7 @@ "name": "tests/integration/common/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d8c30f5355ba8e803396d6ea50c3544369aaff6e21a01bfd8aa580c411a8cfe3", + "chksum_sha256": "8c877b8600f9bea68dac7a5044b9ce139bd6d5ef97a7898d109da2bd3555cc4c", "format": 1 }, { @@ -1390,7 +1390,7 @@ "name": "tests/integration/targets/certificate/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1446,7 +1446,7 @@ "name": "tests/integration/targets/certificate/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -1474,7 +1474,7 @@ "name": "tests/integration/targets/certificate_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1537,7 +1537,7 @@ "name": "tests/integration/targets/certificate_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -1565,7 +1565,7 @@ "name": "tests/integration/targets/datacenter_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1600,7 +1600,7 @@ "name": "tests/integration/targets/datacenter_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -1628,7 +1628,7 @@ "name": "tests/integration/targets/firewall/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1649,7 +1649,7 @@ "name": "tests/integration/targets/firewall/tasks/cleanup.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8dd870926bba2e051a95750ce3b4eecef5a3833377e161e6bef078928274ad92", + "chksum_sha256": "66517a65a873e2ed97fb6e929e59cfda9390f20b9cb0a2e7a9005c8e0f1fb3fa", "format": 1 }, { @@ -1670,14 +1670,14 @@ "name": "tests/integration/targets/firewall/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ba26d33321fa93dca7304bfb232a2ee64886eb4262db53f561fd3f35eb3905d0", + "chksum_sha256": "c014033d9eadcd33ba59747085c1a1c288e6adf05773c3defb6f26a5ca864c29", "format": 1 }, { "name": "tests/integration/targets/firewall/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -1705,7 +1705,7 @@ "name": "tests/integration/targets/firewall_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1726,7 +1726,7 @@ "name": "tests/integration/targets/firewall_info/tasks/cleanup.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8dd870926bba2e051a95750ce3b4eecef5a3833377e161e6bef078928274ad92", + "chksum_sha256": "66517a65a873e2ed97fb6e929e59cfda9390f20b9cb0a2e7a9005c8e0f1fb3fa", "format": 1 }, { @@ -1754,7 +1754,7 @@ "name": "tests/integration/targets/firewall_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -1782,7 +1782,7 @@ "name": "tests/integration/targets/firewall_resource/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1803,7 +1803,7 @@ "name": "tests/integration/targets/firewall_resource/tasks/cleanup.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8dd870926bba2e051a95750ce3b4eecef5a3833377e161e6bef078928274ad92", + "chksum_sha256": "66517a65a873e2ed97fb6e929e59cfda9390f20b9cb0a2e7a9005c8e0f1fb3fa", "format": 1 }, { @@ -1831,7 +1831,7 @@ "name": "tests/integration/targets/firewall_resource/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -1859,7 +1859,7 @@ "name": "tests/integration/targets/floating_ip/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1887,14 +1887,14 @@ "name": "tests/integration/targets/floating_ip/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "16ab089febd775cfa9f5a8a3056011c532a93b1d1f950651a915d62e24d7f19a", + "chksum_sha256": "2b3eacb99ca6db155235d496e06b9d7fceda09a43811f9e5ad2793337f9674da", "format": 1 }, { "name": "tests/integration/targets/floating_ip/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -1922,7 +1922,7 @@ "name": "tests/integration/targets/floating_ip_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -1971,7 +1971,7 @@ "name": "tests/integration/targets/floating_ip_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -1999,7 +1999,7 @@ "name": "tests/integration/targets/image_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2062,7 +2062,7 @@ "name": "tests/integration/targets/image_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -2090,7 +2090,7 @@ "name": "tests/integration/targets/iso_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2125,7 +2125,7 @@ "name": "tests/integration/targets/iso_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -2153,7 +2153,7 @@ "name": "tests/integration/targets/load_balancer/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2188,14 +2188,14 @@ "name": "tests/integration/targets/load_balancer/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "fce600c1ef1affccfe85e9dcff37aec4b0871d71d56f2c11120dd3a702a0092a", + "chksum_sha256": "c5591a55999f388c9d7f6745578a97c0721980ecad0363afe923763375454084", "format": 1 }, { "name": "tests/integration/targets/load_balancer/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2223,7 +2223,7 @@ "name": "tests/integration/targets/load_balancer_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2272,7 +2272,7 @@ "name": "tests/integration/targets/load_balancer_info/tasks/prepare.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b24030c8971a1d5cf054c44707ad97ed13c74083e2662a156f99f1f67bd27809", + "chksum_sha256": "a1ed2c93f712ca60de6f40ce0544f6ced9a50337cd5bc9691ab99f77aaaee814", "format": 1 }, { @@ -2286,7 +2286,7 @@ "name": "tests/integration/targets/load_balancer_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2314,7 +2314,7 @@ "name": "tests/integration/targets/load_balancer_network/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2349,7 +2349,7 @@ "name": "tests/integration/targets/load_balancer_network/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2377,7 +2377,7 @@ "name": "tests/integration/targets/load_balancer_service/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2412,7 +2412,7 @@ "name": "tests/integration/targets/load_balancer_service/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2440,7 +2440,7 @@ "name": "tests/integration/targets/load_balancer_target/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2468,14 +2468,14 @@ "name": "tests/integration/targets/load_balancer_target/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "ba13cee3ba0ed0d0ba97e4b518f78db4a4c452006aac77b79328da174dc13bd2", + "chksum_sha256": "fc4f35338a60e127868e9aed40aaaa9f00410d80a04c0375663a07564a3f10c1", "format": 1 }, { "name": "tests/integration/targets/load_balancer_target/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2503,7 +2503,7 @@ "name": "tests/integration/targets/load_balancer_type_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2538,7 +2538,7 @@ "name": "tests/integration/targets/load_balancer_type_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -2566,7 +2566,7 @@ "name": "tests/integration/targets/location_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2601,7 +2601,7 @@ "name": "tests/integration/targets/location_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -2629,14 +2629,14 @@ "name": "tests/integration/targets/network/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { "name": "tests/integration/targets/network/defaults/main/main.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "6ebb966b0125a1f2d47085ec0ec1b7bf5fe77546b0c20e7aa611e5030d6d9858", + "chksum_sha256": "198cc6e4f9cfdacce2d589208c673f7f14bf8275c47b8bced31a3bbd6f773576", "format": 1 }, { @@ -2647,6 +2647,13 @@ "format": 1 }, { + "name": "tests/integration/targets/network/tasks/cleanup.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a5269525807e9843a939b1e5953ee9ce827f6be8afa561e38281487e8e7ef4b5", + "format": 1 + }, + { "name": "tests/integration/targets/network/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", @@ -2657,14 +2664,14 @@ "name": "tests/integration/targets/network/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0431a784bc8a2466094fd6c62232127726e53f8edaec2a49427005ecd2dcba89", + "chksum_sha256": "104b13a03a18a961cc07e167020188a45b75ce50e0cd943773c62470fbf4eaeb", "format": 1 }, { "name": "tests/integration/targets/network/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "9581657d21f8bc0c17584836cc436825d28f40fb04208162424c3e8f5cbd1d17", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2692,7 +2699,7 @@ "name": "tests/integration/targets/network_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2741,7 +2748,7 @@ "name": "tests/integration/targets/network_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -2769,7 +2776,7 @@ "name": "tests/integration/targets/placement_group/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2825,14 +2832,14 @@ "name": "tests/integration/targets/placement_group/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "912665632b18f00f5a4e9d5f1d38d6c5ae1500682bd43486cf84e3e2f1fb68d9", + "chksum_sha256": "498ec7dbfb133a743d8956720657de6ae2a9afcac5c02825a280a00d5807b034", "format": 1 }, { "name": "tests/integration/targets/placement_group/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -2860,7 +2867,7 @@ "name": "tests/integration/targets/primary_ip/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2878,6 +2885,13 @@ "format": 1 }, { + "name": "tests/integration/targets/primary_ip/tasks/cleanup.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5a8978de32c6ba869cce995129a01bc32642da3f4ac5c9005e6b06a8d9668967", + "format": 1 + }, + { "name": "tests/integration/targets/primary_ip/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", @@ -2885,17 +2899,24 @@ "format": 1 }, { + "name": "tests/integration/targets/primary_ip/tasks/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "691b022c35633330e5363082d2f16a32c1a5921ec0660d0844c6b345a9908de4", + "format": 1 + }, + { "name": "tests/integration/targets/primary_ip/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "41dad71607635d485207ada2c6b36b2241bbe8dc625ece233666fa6663dbdced", + "chksum_sha256": "0a63acbfcc1b07c91b2544fd2d73499ea0bd4065d98caa3594a32a6eeaa0d856", "format": 1 }, { "name": "tests/integration/targets/primary_ip/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -2923,7 +2944,7 @@ "name": "tests/integration/targets/primary_ip_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -2972,7 +2993,7 @@ "name": "tests/integration/targets/primary_ip_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -3000,7 +3021,7 @@ "name": "tests/integration/targets/rdns/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3049,7 +3070,7 @@ "name": "tests/integration/targets/rdns/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -3077,7 +3098,7 @@ "name": "tests/integration/targets/route/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3112,7 +3133,7 @@ "name": "tests/integration/targets/route/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "7487e3a1fe3da170468c7132137f40e49195c30d9a6657f44b055c9c641e3953", + "chksum_sha256": "9dcd2dc48825a03978b00602039ef02c5a71f84e2fb0e466cdafa24b801f2d8c", "format": 1 }, { @@ -3140,7 +3161,7 @@ "name": "tests/integration/targets/server/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3203,14 +3224,14 @@ "name": "tests/integration/targets/server/tasks/test_basic.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "bbaa1a6325538510af5f484a375db05fa78e0c01d5eba621c47bb4d1334c6165", + "chksum_sha256": "c146badd3871984365f368034f8a2893805587f04c598b4bfca6d6ae15df86a8", "format": 1 }, { "name": "tests/integration/targets/server/tasks/test_firewalls.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "1ddcad3dccc8d45a0a35579b57ffad87a4837a296e3503dbb98e18af06c8b618", + "chksum_sha256": "3d81087413bb81afed8aa55bd44b6a2df5c93afcd3cd4d61916b0a028cc76f55", "format": 1 }, { @@ -3231,14 +3252,14 @@ "name": "tests/integration/targets/server/tasks/test_validation.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "36a7a338d06d69fa47aac6fcbf3ff5204d59836548d41c255cfd38726aad6fa5", + "chksum_sha256": "36168c16df59bf8a887cf3c85cbc204edaa8a6d8f5ae43372ece52f6a236a402", "format": 1 }, { "name": "tests/integration/targets/server/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -3266,7 +3287,7 @@ "name": "tests/integration/targets/server_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3301,7 +3322,7 @@ "name": "tests/integration/targets/server_info/tasks/prepare.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "09186e955def1c3db23eeeef46aa27cdc43a43c12b5242bf886fbd78504f76a1", + "chksum_sha256": "4f55fa3605d530877e393b70cfd2b7f7f681154203fd8cfbdb6b82764aa532eb", "format": 1 }, { @@ -3315,7 +3336,7 @@ "name": "tests/integration/targets/server_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3343,7 +3364,7 @@ "name": "tests/integration/targets/server_network/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3361,6 +3382,13 @@ "format": 1 }, { + "name": "tests/integration/targets/server_network/tasks/cleanup.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e0ded2b4a3682e923a20de97c558c679c26687b7d11ce3ef6c99b22c78a010e2", + "format": 1 + }, + { "name": "tests/integration/targets/server_network/tasks/main.yml", "ftype": "file", "chksum_type": "sha256", @@ -3368,17 +3396,24 @@ "format": 1 }, { + "name": "tests/integration/targets/server_network/tasks/prepare.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8085f99f3edaa6eb351d9434b7666166b3ce553560bb373bba91f86c737ee703", + "format": 1 + }, + { "name": "tests/integration/targets/server_network/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "c8720a7da054c73c059f61d0ed72ddaa434e2cc77bb9593d5bf931c5dccdb7f6", + "chksum_sha256": "198f839eb79ac6c9ad2d8e7fbd71bd95e382f631b708159922177690c3ef00cc", "format": 1 }, { "name": "tests/integration/targets/server_network/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "0258aae2182ba7af39814062303251139ba3f539c4bd6abcc33c735021c1936f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3406,7 +3441,7 @@ "name": "tests/integration/targets/server_type_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3441,7 +3476,7 @@ "name": "tests/integration/targets/server_type_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3532,7 +3567,7 @@ "name": "tests/integration/targets/ssh_key/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3581,14 +3616,14 @@ "name": "tests/integration/targets/ssh_key/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "a989382c4723e0cc5fa7132c0bcbdf1ed98c20f714a70ff1f70b99c3927d3c24", + "chksum_sha256": "454f9a473a3316dd7c42626ff5ee394f39b91e32c4c2f439e808dca08db32e63", "format": 1 }, { "name": "tests/integration/targets/ssh_key/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3616,7 +3651,7 @@ "name": "tests/integration/targets/ssh_key_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3679,7 +3714,7 @@ "name": "tests/integration/targets/ssh_key_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3707,7 +3742,7 @@ "name": "tests/integration/targets/subnetwork/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3756,7 +3791,7 @@ "name": "tests/integration/targets/subnetwork/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "8f69b796700c4a65ac5e4f99e98e9ed67c924a70ac01a47dc24e97e95ba74cd6", + "chksum_sha256": "b061bc633f1ba78ab727b63d080c52926e98cd34c5c8c8561d916b6ba6574f43", "format": 1 }, { @@ -3784,7 +3819,7 @@ "name": "tests/integration/targets/volume/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3812,14 +3847,14 @@ "name": "tests/integration/targets/volume/tasks/test.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d647af7b292a38d1c68d348b99fbaea7e40244a3588cb63f6658e44f1dd806c2", + "chksum_sha256": "2c53074dd755bcc711df53fde0b11f18c06e71a8d605155ae65687d060a12aab", "format": 1 }, { "name": "tests/integration/targets/volume/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3847,7 +3882,7 @@ "name": "tests/integration/targets/volume_info/defaults/main/common.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "be14638f15126802a9e86e2cf7080d6fa592a357eb6bc7330d243a8546ea6218", + "chksum_sha256": "743f1b304d140b1cdbd4af4286b84bf070ffe12682305c13108cf8d3747c1cfc", "format": 1 }, { @@ -3896,7 +3931,7 @@ "name": "tests/integration/targets/volume_info/aliases", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "d924d2bc6bd615c6717c4d8b837fb0c9f5e4bd8df1c4ae94e3f649265d9ed19f", + "chksum_sha256": "e7b5096c1fc8e3f8805e369daec3c86fad0039aa4b598cac8d911d962599aa50", "format": 1 }, { @@ -3907,6 +3942,13 @@ "format": 1 }, { + "name": "tests/integration/cloud-config-hcloud.ini.in", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a22a6ed9f10bdeff1fe82593fa1f7e657a8ab7ccda9edd482c4068bd4bf14a09", + "format": 1 + }, + { "name": "tests/integration/requirements.txt", "ftype": "file", "chksum_type": "sha256", @@ -3921,13 +3963,6 @@ "format": 1 }, { - "name": "tests/sanity/ignore-2.13.txt", - "ftype": "file", - "chksum_type": "sha256", - "chksum_sha256": "6cd38282c4ae22a82047d6491cf2c203b54a59dad3f30b73f760404aaab212b6", - "format": 1 - }, - { "name": "tests/sanity/ignore-2.14.txt", "ftype": "file", "chksum_type": "sha256", @@ -3956,6 +3991,20 @@ "format": 1 }, { + "name": "tests/unit/inventory", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/inventory/test_hcloud.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9622d716bd68b0cc3ba837f6f6d58d654bbd046379f845cc3882d54ebf652f0d", + "format": 1 + }, + { "name": "tests/unit/module_utils", "ftype": "dir", "chksum_type": null, @@ -3966,7 +4015,14 @@ "name": "tests/unit/module_utils/test_hcloud.py", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "548d821beaa35a1804b6f3dc2b3dbd08a1a678ec0ba93a4f6a474d68fc3ed90f", + "chksum_sha256": "4889752907a357b5e0f81c3b772ab1f7afd40694decbffdbc2af92734cb25d58", + "format": 1 + }, + { + "name": "tests/unit/conftest.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "745a352a6467383d4751be595bb3647daf2eacb2d52163d8fef128830ca9a2b9", "format": 1 }, { @@ -4050,7 +4106,7 @@ "name": ".ansible-lint", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "cf689ed57f2490cabb563d4e59b6abc0fd8d236bf635cf3da4c434cf55f892a7", + "chksum_sha256": "5f4261003b2f3140736e3b679e1c6bc38d186810d5e2c42ba4ca7f1e7d36a7fb", "format": 1 }, { @@ -4071,21 +4127,21 @@ "name": ".gitlab-ci.yml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "eb567b2e12c80f6541f0afa43e50e8c8b5345ac802ccf7c6b37459ad7b240769", + "chksum_sha256": "eaaf02c5966e378937fa64534ed07632f4312eb6fdd23dafe56895d530c7640d", "format": 1 }, { "name": ".pre-commit-config.yaml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "da31f2118bc2255609a17b9d3cc0e1890355b0b5fbc3d03918afaba12913a1cb", + "chksum_sha256": "71bae726deb8a87eb83d2daf72a42ff0236485adcaf8dad1f860828e195db622", "format": 1 }, { "name": "CHANGELOG.rst", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "367305440cc3eb10145002d97843578480820303a33ba94efad87790c113090c", + "chksum_sha256": "c0e39c8518499422f53651eccff5f19445a8f2cab3a03c40380aa51f5a736c26", "format": 1 }, { @@ -4099,7 +4155,7 @@ "name": "Makefile", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "aafc23f45f3a932b4cb743f04ba476e20334967e6f694b1c60e8e45e95ea7b67", + "chksum_sha256": "44d34f8b2b50f583dbdcca29033e1636f4135fa02cfd3fcbf40a5219fbed7478", "format": 1 }, { @@ -4113,7 +4169,7 @@ "name": "pyproject.toml", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "b3d7daeee52b89e89e6d9ae221c798c93e534aab36d40ce2a5779fc407ee4a2b", + "chksum_sha256": "b09498ae517c8f34f701b39e8b809c64262bdcba1bb1065b8c9e65a62d5e1d4e", "format": 1 }, { @@ -4127,7 +4183,7 @@ "name": "requirements.txt", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "5bd140232f60ddf13de976b1fb62d039e9e095c3d3e61ea0a2f85b2e2ff56f19", + "chksum_sha256": "84535c2459b50b494e55f318902eb460b18dd773acd845a3ac82e159f9d0075a", "format": 1 } ], diff --git a/ansible_collections/hetzner/hcloud/MANIFEST.json b/ansible_collections/hetzner/hcloud/MANIFEST.json index 9a5a2871e..c9643d913 100644 --- a/ansible_collections/hetzner/hcloud/MANIFEST.json +++ b/ansible_collections/hetzner/hcloud/MANIFEST.json @@ -2,7 +2,7 @@ "collection_info": { "namespace": "hetzner", "name": "hcloud", - "version": "2.5.0", + "version": "3.1.1", "authors": [ "Hetzner Cloud (github.com/hetznercloud)" ], @@ -27,7 +27,7 @@ "name": "FILES.json", "ftype": "file", "chksum_type": "sha256", - "chksum_sha256": "afff741537d1ee1b0ef966debfc999feb8bcab30ee5b5780613c7de284cfbb58", + "chksum_sha256": "1b2cc041fd036b62e37bb26b7e29b36f5763208bb2f8c04afa47a665172c4f1c", "format": 1 }, "format": 1 diff --git a/ansible_collections/hetzner/hcloud/Makefile b/ansible_collections/hetzner/hcloud/Makefile index 48c411d64..12a2521ea 100644 --- a/ansible_collections/hetzner/hcloud/Makefile +++ b/ansible_collections/hetzner/hcloud/Makefile @@ -1,5 +1,8 @@ SHELL := bash -.PHONY: vendor clean +.PHONY: vendor clean dev + +dev: + cat tests/integration/cloud-config-hcloud.ini.in | envsubst > tests/integration/cloud-config-hcloud.ini vendor: python3 scripts/vendor.py @@ -21,8 +24,7 @@ lint-docs: venv . clean: - git clean -xdf \ - -e tests/integration/cloud-config-hcloud.ini + git clean -xdf sanity: ansible-test sanity --color --truncate 0 -v \ diff --git a/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml b/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml index cba509728..235544b9b 100644 --- a/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml +++ b/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml @@ -488,3 +488,64 @@ releases: name: firewall_resource namespace: '' release_date: '2024-02-02' + 3.0.0: + changes: + breaking_changes: + - Drop support for ansible-core 2.13. + - certificate - The `not_valid_before` and `not_valid_after` values are now + returned as ISO-8601 formatted strings. + - certificate_info - The `not_valid_before` and `not_valid_after` values are + now returned as ISO-8601 formatted strings. + - inventory - Remove the deprecated `api_token_env` option, you may use the + `ansible.builtin.env` lookup as alternative. + - iso_info - The `deprecated` value is now returned as ISO-8601 formatted strings. + bugfixes: + - load_balancer_info - Correctly return the `cookie_lifetime` value. + - load_balancer_service - Correctly return the `cookie_lifetime` value. + minor_changes: + - inventory - Add `hostname` option used to template the hostname of the instances. + - network - Allow renaming networks. + fragments: + - add-inventory-hostname-option.yml + - allow-renaming-networks.yml + - drop-support-for-ansible-core-2.13.yml + - fix-always-return-iso-8601-formatted-datetime.yml + - fix-load-balancer-cookie-lifetime.yml + - remove-inventory-api_token_env-option.yml + release_date: '2024-02-05' + 3.1.0: + changes: + bugfixes: + - primary_ip - Added the missing `auto_delete` field to the return values. + - primary_ip - The `auto_delete` option is now used when creating or updating + a Primary IP. + - primary_ip_info - Added the missing `auto_delete` field to the return values. + - server - Do not remove the server from its placement group when the `placement_group` + argument is not specified. + - server - Pass an empty string to the `placement_group` argument to remove + a server from its placement group. + - server_network - The returned `alias_ips` list is now sorted. + minor_changes: + - primary_ip - Use the `server` option to assign a Primary IP being created + to a server. + - server - Allow passing Datacenter name or ID to the `datacenter` argument. + - server - Allow passing Image name or ID to the `image` argument. + - server - Allow passing Location name or ID to the `location` argument. + - server - Allow passing SSH Keys names or IDs to the `ssh_keys` argument. + - server - Allow passing Volume names or IDs to the `volumes` argument. + - server - Renamed the `allow_deprecated_image` option to `image_allow_deprecated`. + fragments: + - primary-ip-assigned-to-server.yml + - primary-ip-auto-delete.yml + - server-empty-string-arguments.yml + - server-rename-image_allow_deprecated-argument.yml + - server-use-id-or-name.yml + - sort-alias-ips-in-server-network.yml + release_date: '2024-04-15' + 3.1.1: + changes: + bugfixes: + - inventory - Ensure inventory host variables are serializable and can be cached. + fragments: + - inventory-fix-serialization.yml + release_date: '2024-04-16' diff --git a/ansible_collections/hetzner/hcloud/changelogs/dev-changelog.md b/ansible_collections/hetzner/hcloud/changelogs/dev-changelog.md index 9fbbf81a3..7b8a0b5d8 100644 --- a/ansible_collections/hetzner/hcloud/changelogs/dev-changelog.md +++ b/ansible_collections/hetzner/hcloud/changelogs/dev-changelog.md @@ -1,5 +1,50 @@ # Changelog +## [3.1.1](https://github.com/ansible-collections/hetzner.hcloud/compare/3.1.0...3.1.1) (2024-04-16) + + +### Bug Fixes + +* **inventory:** ensure host ipv6 variable is json serializable ([#496](https://github.com/ansible-collections/hetzner.hcloud/issues/496)) ([a98cf72](https://github.com/ansible-collections/hetzner.hcloud/commit/a98cf72f927bf36ec9745a03bba16c13728154e2)) + +## [3.1.0](https://github.com/ansible-collections/hetzner.hcloud/compare/3.0.0...3.1.0) (2024-04-15) + + +### Features + +* assign primary ip to a server on create ([#465](https://github.com/ansible-collections/hetzner.hcloud/issues/465)) ([51afb23](https://github.com/ansible-collections/hetzner.hcloud/commit/51afb2316639d3b996b29544534aaeff6122904c)) +* rename server `image_allow_deprecated` option ([#487](https://github.com/ansible-collections/hetzner.hcloud/issues/487)) ([d88ecdb](https://github.com/ansible-collections/hetzner.hcloud/commit/d88ecdbccc0da0a61338d23673adf6a6fded211c)) +* use resources name or ID in server module arguments ([#484](https://github.com/ansible-collections/hetzner.hcloud/issues/484)) ([7fdefcf](https://github.com/ansible-collections/hetzner.hcloud/commit/7fdefcfa0243b84a3edb58566ec710e4f4a6db8d)) + + +### Bug Fixes + +* improve actions waiting timeout based on data ([#488](https://github.com/ansible-collections/hetzner.hcloud/issues/488)) ([0709552](https://github.com/ansible-collections/hetzner.hcloud/commit/07095529a4a23dc380ab4678963da9dceb665fd4)) +* return sorted `alias_ips` in `server_network` module ([#458](https://github.com/ansible-collections/hetzner.hcloud/issues/458)) ([1ae6769](https://github.com/ansible-collections/hetzner.hcloud/commit/1ae6769210b1a845084c88c58a545bebc067ca48)) +* use empty string to remove server from its placement group ([#489](https://github.com/ansible-collections/hetzner.hcloud/issues/489)) ([00a4fdd](https://github.com/ansible-collections/hetzner.hcloud/commit/00a4fdd58aba74ab7e8e1a26ff59beea452c2add)) + +## [3.0.0](https://github.com/ansible-collections/hetzner.hcloud/compare/2.5.0...3.0.0) (2024-02-05) + + +### âš BREAKING CHANGES + +* drop support for ansible-core 2.13 ([#450](https://github.com/ansible-collections/hetzner.hcloud/issues/450)) +* always return iso-8601 formatted date time ([#453](https://github.com/ansible-collections/hetzner.hcloud/issues/453)) +* remove inventory `api_token_env` option ([#454](https://github.com/ansible-collections/hetzner.hcloud/issues/454)) + +### Features + +* drop support for ansible-core 2.13 ([#450](https://github.com/ansible-collections/hetzner.hcloud/issues/450)) ([96f8009](https://github.com/ansible-collections/hetzner.hcloud/commit/96f8009214d5d57357cf165bfa5e7c3507d0d6e1)), closes [#400](https://github.com/ansible-collections/hetzner.hcloud/issues/400) +* **inventory:** allow templating instances hostname ([#455](https://github.com/ansible-collections/hetzner.hcloud/issues/455)) ([be404ef](https://github.com/ansible-collections/hetzner.hcloud/commit/be404ef18165c933fbdd7de92773d38e3426efec)) +* remove inventory `api_token_env` option ([#454](https://github.com/ansible-collections/hetzner.hcloud/issues/454)) ([d0c82ae](https://github.com/ansible-collections/hetzner.hcloud/commit/d0c82aec86f844ccb1dcc07ec4acf9eedc87730d)) + + +### Bug Fixes + +* allow renaming networks ([#449](https://github.com/ansible-collections/hetzner.hcloud/issues/449)) ([742cfe6](https://github.com/ansible-collections/hetzner.hcloud/commit/742cfe6d7446d0b54240de5342ef8bb9679cff64)) +* always return iso-8601 formatted date time ([#453](https://github.com/ansible-collections/hetzner.hcloud/issues/453)) ([55d2616](https://github.com/ansible-collections/hetzner.hcloud/commit/55d26162b329cbb5bcff8ed63e5960bef4a897c8)) +* load balancer invalid cookie lifetime value returned ([#452](https://github.com/ansible-collections/hetzner.hcloud/issues/452)) ([86b7662](https://github.com/ansible-collections/hetzner.hcloud/commit/86b76620daf9684edffefcb0f3d3d0220bbe5f2c)) + ## [2.5.0](https://github.com/ansible-collections/hetzner.hcloud/compare/2.4.1...2.5.0) (2024-02-02) diff --git a/ansible_collections/hetzner/hcloud/meta/runtime.yml b/ansible_collections/hetzner/hcloud/meta/runtime.yml index 9891ce73a..7f12a86c7 100644 --- a/ansible_collections/hetzner/hcloud/meta/runtime.yml +++ b/ansible_collections/hetzner/hcloud/meta/runtime.yml @@ -1,4 +1,4 @@ -requires_ansible: ">=2.13.0" +requires_ansible: ">=2.14.0" action_groups: all: diff --git a/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py b/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py index 449342271..d1050c92b 100644 --- a/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py +++ b/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py @@ -32,21 +32,10 @@ options: description: - The API Token for the Hetzner Cloud. type: str - required: false # TODO: Mark as required once 'api_token_env' is removed. + required: true aliases: [token] env: - name: HCLOUD_TOKEN - api_token_env: - description: - - Environment variable name to load the Hetzner Cloud API Token from. - type: str - default: HCLOUD_TOKEN - aliases: [token_env] - deprecated: - why: The option is adding too much complexity, while the alternatives are preferred. - collection_name: hetzner.hcloud - version: 3.0.0 - alternatives: Use the P(ansible.builtin.env#lookup) lookup plugin instead. api_endpoint: description: - The API Endpoint for the Hetzner Cloud. @@ -120,6 +109,14 @@ options: - The suffix for host variables names coming from Hetzner Cloud. type: str version_added: 2.5.0 + + hostname: + description: + - A template for the instances hostname, if not provided the Hetzner Cloud server name will be used. + - Available variables are the Hetzner Cloud host variables. + - The available variables names are provide with the O(hostvars_prefix) or O(hostvars_suffix) modifications. + type: str + version_added: 3.0.0 """ EXAMPLES = """ @@ -153,9 +150,43 @@ keyed_groups: separator: "" - key: status prefix: server_status + +--- +# Use a custom hostname template. +plugin: hetzner.hcloud.hcloud + +# Available variables are for example: +## Server +# id: 42984895 +# name: "my-server" +# labels: +# foo: "bar" +# status: "running" +## Server Type +# type: "cx11" +# server_type: "cx11" +# architecture: "x86" +## Image +# image_id: 114690387 +# image_name: "debian-12" +# image_os_flavor: "debian" +## Datacenter +# datacenter: "hel1-dc2" +# location: "hel1" +## Network +# ipv4: "65.109.140.95" # Value is optional! +# ipv6: "2a01:4f9:c011:b83f::1" # Value is optional! +# ipv6_network: 2a01:4f9:c011:b83f::" # Value is optional! +# ipv6_network_mask: "64" # Value is optional! +# private_ipv4: "10.0.0.3" # Value is optional! +# private_networks: +# - id: 114690387 +# name: "my-private-network" +# ip: "10.0.0.3" +# +hostname: "my-prefix-{{ datacenter }}-{{ name }}-{{ server_type }}" """ -import os import sys from ipaddress import IPv6Network @@ -164,6 +195,7 @@ from ansible.inventory.manager import InventoryData from ansible.module_utils.common.text.converters import to_native from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable from ansible.utils.display import Display +from ansible.utils.vars import combine_vars from ..module_utils.client import ( Client, @@ -229,7 +261,7 @@ def first_ipv6_address(network: str) -> str: :param network: IPv6 Network. """ - return next(IPv6Network(network).hosts()) + return str(next(IPv6Network(network).hosts())) class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): @@ -243,30 +275,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): network: Network | None def _configure_hcloud_client(self): - # If api_token_env is not the default, print a deprecation warning and load the - # environment variable. - api_token_env = self.get_option("api_token_env") - if api_token_env != "HCLOUD_TOKEN": - self.display.deprecated( - "The 'api_token_env' option is deprecated, please use the 'HCLOUD_TOKEN' " - "environment variable or use the 'ansible.builtin.env' lookup instead.", - version="3.0.0", - collection_name="hetzner.hcloud", - ) - if api_token_env in os.environ: - self.set_option("api_token", os.environ.get(api_token_env)) - api_token = self.get_option("api_token") api_endpoint = self.get_option("api_endpoint") - if api_token is None: # TODO: Remove once I(api_token_env) is removed. - raise AnsibleError( - "No setting was provided for required configuration setting: " - "plugin_type: inventory " - "plugin: hetzner.hcloud.hcloud " - "setting: api_token" - ) - # Resolve template string api_token = self.templar.template(api_token) @@ -325,43 +336,43 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): def _build_inventory_server(self, server: Server) -> InventoryServer: server_dict: InventoryServer = {} server_dict["id"] = server.id - server_dict["name"] = to_native(server.name) - server_dict["status"] = to_native(server.status) + server_dict["name"] = server.name + server_dict["status"] = server.status # Server Type - server_dict["type"] = to_native(server.server_type.name) - server_dict["server_type"] = to_native(server.server_type.name) - server_dict["architecture"] = to_native(server.server_type.architecture) + server_dict["type"] = server.server_type.name + server_dict["server_type"] = server.server_type.name + server_dict["architecture"] = server.server_type.architecture # Network if server.public_net.ipv4: - server_dict["ipv4"] = to_native(server.public_net.ipv4.ip) + server_dict["ipv4"] = server.public_net.ipv4.ip if server.public_net.ipv6: - server_dict["ipv6"] = to_native(first_ipv6_address(server.public_net.ipv6.ip)) - server_dict["ipv6_network"] = to_native(server.public_net.ipv6.network) - server_dict["ipv6_network_mask"] = to_native(server.public_net.ipv6.network_mask) + server_dict["ipv6"] = first_ipv6_address(server.public_net.ipv6.ip) + server_dict["ipv6_network"] = server.public_net.ipv6.network + server_dict["ipv6_network_mask"] = server.public_net.ipv6.network_mask server_dict["private_networks"] = [ - {"id": v.network.id, "name": to_native(v.network.name), "ip": to_native(v.ip)} for v in server.private_net + {"id": v.network.id, "name": v.network.name, "ip": v.ip} for v in server.private_net ] if self.get_option("network"): for private_net in server.private_net: # Set private_ipv4 if user filtered for one network if private_net.network.id == self.network.id: - server_dict["private_ipv4"] = to_native(private_net.ip) + server_dict["private_ipv4"] = private_net.ip break # Datacenter - server_dict["datacenter"] = to_native(server.datacenter.name) - server_dict["location"] = to_native(server.datacenter.location.name) + server_dict["datacenter"] = server.datacenter.name + server_dict["location"] = server.datacenter.location.name # Image if server.image is not None: server_dict["image_id"] = server.image.id - server_dict["image_os_flavor"] = to_native(server.image.os_flavor) - server_dict["image_name"] = to_native(server.image.name or server.image.description) + server_dict["image_os_flavor"] = server.image.os_flavor + server_dict["image_name"] = server.image.name or server.image.description # Labels server_dict["labels"] = dict(server.labels) @@ -380,28 +391,28 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): def _get_server_ansible_host(self, server: Server): if self.get_option("connect_with") == "public_ipv4": if server.public_net.ipv4: - return to_native(server.public_net.ipv4.ip) + return server.public_net.ipv4.ip raise AnsibleError("Server has no public ipv4, but connect_with=public_ipv4 was specified") if self.get_option("connect_with") == "public_ipv6": if server.public_net.ipv6: - return to_native(first_ipv6_address(server.public_net.ipv6.ip)) + return first_ipv6_address(server.public_net.ipv6.ip) raise AnsibleError("Server has no public ipv6, but connect_with=public_ipv6 was specified") if self.get_option("connect_with") == "hostname": # every server has a name, no need to guard this - return to_native(server.name) + return server.name if self.get_option("connect_with") == "ipv4_dns_ptr": if server.public_net.ipv4: - return to_native(server.public_net.ipv4.dns_ptr) + return server.public_net.ipv4.dns_ptr raise AnsibleError("Server has no public ipv4, but connect_with=ipv4_dns_ptr was specified") if self.get_option("connect_with") == "private_ipv4": if self.get_option("network"): for private_net in server.private_net: if private_net.network.id == self.network.id: - return to_native(private_net.ip) + return private_net.ip else: raise AnsibleError("You can only connect via private IPv4 if you specify a network") @@ -466,9 +477,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): hostvars_prefix = self.get_option("hostvars_prefix") hostvars_suffix = self.get_option("hostvars_suffix") + hostname_template = self.get_option("hostname") for server in servers: - self.inventory.add_host(server["name"], group=self.get_option("group")) + hostvars = {} for key, value in server.items(): # Add hostvars prefix and suffix for variables coming from the Hetzner Cloud. if hostvars_prefix or hostvars_suffix: @@ -478,7 +490,18 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): if hostvars_suffix: key = key + hostvars_suffix - self.inventory.set_variable(server["name"], key, value) + hostvars[key] = value + + if hostname_template: + templar = self.templar + templar.available_variables = combine_vars(hostvars, self._vars) + hostname = templar.template(hostname_template) + else: + hostname = server["name"] + + self.inventory.add_host(hostname, group=self.get_option("group")) + for key, value in hostvars.items(): + self.inventory.set_variable(hostname, key, value) # Use constructed if applicable strict = self.get_option("strict") @@ -486,8 +509,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): # Composed variables self._set_composite_vars( self.get_option("compose"), - self.inventory.get_host(server["name"]).get_vars(), - server["name"], + self.inventory.get_host(hostname).get_vars(), + hostname, strict=strict, ) @@ -495,7 +518,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): self._add_host_to_composed_groups( self.get_option("groups"), {}, - server["name"], + hostname, strict=strict, ) @@ -503,7 +526,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): self._add_host_to_keyed_groups( self.get_option("keyed_groups"), {}, - server["name"], + hostname, strict=strict, ) diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py index eab0aef59..60391308a 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py @@ -10,6 +10,10 @@ from typing import Any, NoReturn from ansible.module_utils.basic import AnsibleModule as AnsibleModuleBase, env_fallback from ansible.module_utils.common.text.converters import to_native +from ansible.module_utils.common.validation import ( + check_missing_parameters, + check_required_one_of, +) from .client import ClientException, client_check_required_lib, client_get_by_name_or_id from .vendor.hcloud import APIException, Client, HCloudException @@ -94,6 +98,29 @@ class AnsibleHCloud: def _mark_as_changed(self) -> None: self.result["changed"] = True + def fail_on_invalid_params( + self, + *, + required: list[str] | None = None, + required_one_of: list[list[str]] | None = None, + ) -> None: + """ + Run additional validation that cannot be done in the argument spec validation. + + :param required_params: Check that terms exists in the module params. + :param required_one_of: Check each list of terms to ensure at least one exists in the module parameters. + """ + try: + if required: + check_missing_parameters(self.module.params, required) + + if required_one_of: + params_without_nones = {k: v for k, v in self.module.params.items() if v is not None} + check_required_one_of(required_one_of, params_without_nones) + + except TypeError as e: + self.module.fail_json(msg=to_native(e)) + @classmethod def base_module_arguments(cls): return { diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py index e03c1b434..d350d7138 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py @@ -1,3 +1,3 @@ from __future__ import annotations -VERSION = "1.33.2" # x-release-please-version +VERSION = "1.35.0" # x-release-please-version diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py index 692f7488b..bba954fe2 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py @@ -34,6 +34,24 @@ class DomainIdentityMixin: return self.name raise ValueError("id or name must be set") + def has_id_or_name(self, id_or_name: int | str) -> bool: + """ + Return whether this domain has the same id or same name as the other. + + The domain calling this method MUST be a bound domain or be populated, otherwise + the comparison will not work as expected (e.g. the domains are the same but + cannot be equal, if one provides an id and the other the name). + """ + values: list[int | str] = [] + if self.id is not None: + values.append(self.id) + if self.name is not None: + values.append(self.name) + if not values: + raise ValueError("id or name must be set") + + return id_or_name in values + class Pagination(BaseDomain): __slots__ = ( diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py index 5ce9281d9..d637231d6 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py @@ -7,7 +7,7 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction @@ -15,7 +15,7 @@ if TYPE_CHECKING: from .client import BoundFirewall -class Firewall(BaseDomain): +class Firewall(BaseDomain, DomainIdentityMixin): """Firewall Domain :param id: int diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py index e1f295bd6..abd2c13cc 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py @@ -7,7 +7,7 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction @@ -16,7 +16,7 @@ if TYPE_CHECKING: from .client import BoundFloatingIP -class FloatingIP(BaseDomain): +class FloatingIP(BaseDomain, DomainIdentityMixin): """Floating IP Domain :param id: int diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py index 65b7546a8..a7d41e01b 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import TYPE_CHECKING, Any, NamedTuple from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient @@ -305,18 +306,27 @@ class ImagesClient(ClientEntityBase): def get_by_name(self, name: str) -> BoundImage | None: """Get image by name - Deprecated: Use get_by_name_and_architecture instead. - :param name: str Used to get image by name. :return: :class:`BoundImage <hcloud.images.client.BoundImage>` + + .. deprecated:: 1.19 + Use :func:`hcloud.images.client.ImagesClient.get_by_name_and_architecture` instead. """ + warnings.warn( + "The 'hcloud.images.client.ImagesClient.get_by_name' method is deprecated, please use the " + "'hcloud.images.client.ImagesClient.get_by_name_and_architecture' method instead.", + DeprecationWarning, + stacklevel=2, + ) return self._get_first_by(name=name) def get_by_name_and_architecture( self, name: str, architecture: str, + *, + include_deprecated: bool | None = None, ) -> BoundImage | None: """Get image by name @@ -324,9 +334,15 @@ class ImagesClient(ClientEntityBase): Used to identify the image. :param architecture: str Used to identify the image. + :param include_deprecated: bool (optional) + Include deprecated images. Default: False :return: :class:`BoundImage <hcloud.images.client.BoundImage>` """ - return self._get_first_by(name=name, architecture=[architecture]) + return self._get_first_by( + name=name, + architecture=[architecture], + include_deprecated=include_deprecated, + ) def update( self, diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py index 6d6f0700a..76e8db3f7 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py @@ -7,7 +7,7 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction @@ -20,7 +20,7 @@ if TYPE_CHECKING: from .client import BoundLoadBalancer -class LoadBalancer(BaseDomain): +class LoadBalancer(BaseDomain, DomainIdentityMixin): """LoadBalancer Domain :param id: int @@ -79,7 +79,7 @@ class LoadBalancer(BaseDomain): id: int, name: str | None = None, public_net: PublicNetwork | None = None, - private_net: PrivateNet | None = None, + private_net: list[PrivateNet] | None = None, location: BoundLocation | None = None, algorithm: LoadBalancerAlgorithm | None = None, services: list[LoadBalancerService] | None = None, @@ -203,9 +203,9 @@ class LoadBalancerService(BaseDomain): if self.health_check.http.response is not None: health_check_http["response"] = self.health_check.http.response if self.health_check.http.status_codes is not None: - health_check_http[ - "status_codes" - ] = self.health_check.http.status_codes + health_check_http["status_codes"] = ( + self.health_check.http.status_codes + ) if self.health_check.http.tls is not None: health_check_http["tls"] = self.health_check.http.tls diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py index c307bf989..e04de2775 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py @@ -7,7 +7,7 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction @@ -15,7 +15,7 @@ if TYPE_CHECKING: from .client import BoundNetwork -class Network(BaseDomain): +class Network(BaseDomain, DomainIdentityMixin): """Network Domain :param id: int diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py index 16b2a390d..1c6fc04cd 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py @@ -7,14 +7,14 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction from .client import BoundPlacementGroup -class PlacementGroup(BaseDomain): +class PlacementGroup(BaseDomain, DomainIdentityMixin): """Placement Group Domain :param id: int diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py index aeb943f0a..2eebacef4 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py @@ -7,7 +7,7 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction @@ -15,7 +15,7 @@ if TYPE_CHECKING: from .client import BoundPrimaryIP -class PrimaryIP(BaseDomain): +class PrimaryIP(BaseDomain, DomainIdentityMixin): """Primary IP Domain :param id: int diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py index 0a0d34688..d5e769e5e 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py @@ -7,7 +7,7 @@ try: except ImportError: isoparse = None -from ..core import BaseDomain +from ..core import BaseDomain, DomainIdentityMixin if TYPE_CHECKING: from ..actions import BoundAction @@ -25,7 +25,7 @@ if TYPE_CHECKING: from .client import BoundServer -class Server(BaseDomain): +class Server(BaseDomain, DomainIdentityMixin): """Server Domain :param id: int diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py index e78c320a2..0bf903564 100644 --- a/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py +++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py @@ -1,3 +1,3 @@ from __future__ import annotations -version = "2.5.0" # x-release-please-version +version = "3.1.1" # x-release-please-version diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py b/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py index ea39be6ca..53466e48f 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py @@ -146,7 +146,6 @@ hcloud_certificate: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -160,14 +159,14 @@ class AnsibleHCloudCertificate(AnsibleHCloud): def _prepare_result(self): return { - "id": to_native(self.hcloud_certificate.id), - "name": to_native(self.hcloud_certificate.name), - "type": to_native(self.hcloud_certificate.type), - "fingerprint": to_native(self.hcloud_certificate.fingerprint), - "certificate": to_native(self.hcloud_certificate.certificate), - "not_valid_before": to_native(self.hcloud_certificate.not_valid_before), - "not_valid_after": to_native(self.hcloud_certificate.not_valid_after), - "domain_names": [to_native(domain) for domain in self.hcloud_certificate.domain_names], + "id": str(self.hcloud_certificate.id), + "name": self.hcloud_certificate.name, + "type": self.hcloud_certificate.type, + "fingerprint": self.hcloud_certificate.fingerprint, + "certificate": self.hcloud_certificate.certificate, + "not_valid_before": self.hcloud_certificate.not_valid_before.isoformat(), + "not_valid_after": self.hcloud_certificate.not_valid_after.isoformat(), + "domain_names": self.hcloud_certificate.domain_names, "labels": self.hcloud_certificate.labels, } @@ -203,7 +202,9 @@ class AnsibleHCloudCertificate(AnsibleHCloud): if not self.module.check_mode: try: resp = self.client.certificates.create_managed(**params) - resp.action.wait_until_finished(max_retries=1000) + # Action should take 60 to 90 seconds on average, wait for 5m to + # allow DNS or Let's Encrypt slowdowns. + resp.action.wait_until_finished(max_retries=300) except HCloudException as exception: self.fail_json_hcloud(exception) diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py index e074046fd..37b944341 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py @@ -87,7 +87,6 @@ hcloud_certificate_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -100,23 +99,25 @@ class AnsibleHCloudCertificateInfo(AnsibleHCloud): hcloud_certificate_info: list[BoundCertificate] | None = None def _prepare_result(self): - certificates = [] + tmp = [] for certificate in self.hcloud_certificate_info: - if certificate: - certificates.append( - { - "id": to_native(certificate.id), - "name": to_native(certificate.name), - "fingerprint": to_native(certificate.fingerprint), - "certificate": to_native(certificate.certificate), - "not_valid_before": to_native(certificate.not_valid_before), - "not_valid_after": to_native(certificate.not_valid_after), - "domain_names": [to_native(domain) for domain in certificate.domain_names], - "labels": certificate.labels, - } - ) - return certificates + if certificate is None: + continue + + tmp.append( + { + "id": str(certificate.id), + "name": certificate.name, + "fingerprint": certificate.fingerprint, + "certificate": certificate.certificate, + "not_valid_before": certificate.not_valid_before.isoformat(), + "not_valid_after": certificate.not_valid_after.isoformat(), + "domain_names": certificate.domain_names, + "labels": certificate.labels, + } + ) + return tmp def get_certificates(self): try: diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py index f6665a6fb..85475dd44 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py @@ -118,7 +118,6 @@ hcloud_datacenter_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -139,10 +138,10 @@ class AnsibleHCloudDatacenterInfo(AnsibleHCloud): tmp.append( { - "id": to_native(datacenter.id), - "name": to_native(datacenter.name), - "description": to_native(datacenter.description), - "location": to_native(datacenter.location.name), + "id": str(datacenter.id), + "name": datacenter.name, + "description": datacenter.description, + "location": datacenter.location.name, "server_types": { "available": [o.id for o in datacenter.server_types.available], "available_for_migration": [o.id for o in datacenter.server_types.available_for_migration], diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py index 3c51b5c0a..30f17eb9b 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py @@ -219,7 +219,6 @@ hcloud_firewall: import time from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import APIException, HCloudException @@ -237,8 +236,8 @@ class AnsibleHCloudFirewall(AnsibleHCloud): def _prepare_result(self): return { - "id": to_native(self.hcloud_firewall.id), - "name": to_native(self.hcloud_firewall.name), + "id": str(self.hcloud_firewall.id), + "name": self.hcloud_firewall.name, "rules": [self._prepare_result_rule(rule) for rule in self.hcloud_firewall.rules], "labels": self.hcloud_firewall.labels, "applied_to": [self._prepare_result_applied_to(resource) for resource in self.hcloud_firewall.applied_to], @@ -246,27 +245,25 @@ class AnsibleHCloudFirewall(AnsibleHCloud): def _prepare_result_rule(self, rule: FirewallRule): return { - "direction": to_native(rule.direction), - "protocol": to_native(rule.protocol), - "port": to_native(rule.port) if rule.port is not None else None, - "source_ips": [to_native(cidr) for cidr in rule.source_ips], - "destination_ips": [to_native(cidr) for cidr in rule.destination_ips], - "description": to_native(rule.description) if rule.description is not None else None, + "direction": rule.direction, + "protocol": rule.protocol, + "port": rule.port, + "source_ips": rule.source_ips, + "destination_ips": rule.destination_ips, + "description": rule.description, } def _prepare_result_applied_to(self, resource: FirewallResource): result = { - "type": to_native(resource.type), - "server": to_native(resource.server.id) if resource.server is not None else None, - "label_selector": ( - to_native(resource.label_selector.selector) if resource.label_selector is not None else None - ), + "type": resource.type, + "server": str(resource.server.id) if resource.server is not None else None, + "label_selector": resource.label_selector.selector if resource.label_selector is not None else None, } if resource.applied_to_resources is not None: result["applied_to_resources"] = [ { - "type": to_native(item.type), - "server": to_native(item.server.id) if item.server is not None else None, + "type": item.type, + "server": str(item.server.id) if item.server is not None else None, } for item in resource.applied_to_resources ] diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py index 7e7a623d0..a07d9ec54 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py @@ -142,7 +142,6 @@ hcloud_firewall_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -167,8 +166,8 @@ class AnsibleHCloudFirewallInfo(AnsibleHCloud): tmp.append( { - "id": to_native(firewall.id), - "name": to_native(firewall.name), + "id": str(firewall.id), + "name": firewall.name, "labels": firewall.labels, "rules": [self._prepare_result_rule(rule) for rule in firewall.rules], "applied_to": [self._prepare_result_applied_to(resource) for resource in firewall.applied_to], @@ -179,27 +178,25 @@ class AnsibleHCloudFirewallInfo(AnsibleHCloud): def _prepare_result_rule(self, rule: FirewallRule): return { - "description": to_native(rule.description) if rule.description is not None else None, - "direction": to_native(rule.direction), - "protocol": to_native(rule.protocol), - "port": to_native(rule.port) if rule.port is not None else None, - "source_ips": [to_native(cidr) for cidr in rule.source_ips], - "destination_ips": [to_native(cidr) for cidr in rule.destination_ips], + "description": rule.description, + "direction": rule.direction, + "protocol": rule.protocol, + "port": rule.port, + "source_ips": rule.source_ips, + "destination_ips": rule.destination_ips, } def _prepare_result_applied_to(self, resource: FirewallResource): result = { - "type": to_native(resource.type), - "server": to_native(resource.server.id) if resource.server is not None else None, - "label_selector": ( - to_native(resource.label_selector.selector) if resource.label_selector is not None else None - ), + "type": resource.type, + "server": str(resource.server.id) if resource.server is not None else None, + "label_selector": resource.label_selector.selector if resource.label_selector is not None else None, } if resource.applied_to_resources is not None: result["applied_to_resources"] = [ { - "type": to_native(item.type), - "server": to_native(item.server.id) if item.server is not None else None, + "type": item.type, + "server": str(item.server.id) if item.server is not None else None, } for item in resource.applied_to_resources ] diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py index 207f27092..7c0271ba3 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py @@ -103,7 +103,6 @@ hcloud_firewall_resource: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -125,12 +124,12 @@ class AnsibleHCloudFirewallResource(AnsibleHCloud): label_selectors = [] for resource in self.hcloud_firewall_resource.applied_to: if resource.type == FirewallResource.TYPE_SERVER: - servers.append(to_native(resource.server.name)) + servers.append(resource.server.name) elif resource.type == FirewallResource.TYPE_LABEL_SELECTOR: - label_selectors.append(to_native(resource.label_selector.selector)) + label_selectors.append(resource.label_selector.selector) return { - "firewall": to_native(self.hcloud_firewall_resource.name), + "firewall": self.hcloud_firewall_resource.name, "servers": servers, "label_selectors": label_selectors, } diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py index e037dd7a1..022036124 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py @@ -160,7 +160,6 @@ hcloud_floating_ip: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -173,19 +172,15 @@ class AnsibleHCloudFloatingIP(AnsibleHCloud): hcloud_floating_ip: BoundFloatingIP | None = None def _prepare_result(self): - server = None - - if self.hcloud_floating_ip.server is not None: - server = to_native(self.hcloud_floating_ip.server.name) return { - "id": to_native(self.hcloud_floating_ip.id), - "name": to_native(self.hcloud_floating_ip.name), - "description": to_native(self.hcloud_floating_ip.description), - "ip": to_native(self.hcloud_floating_ip.ip), - "type": to_native(self.hcloud_floating_ip.type), - "home_location": to_native(self.hcloud_floating_ip.home_location.name), + "id": str(self.hcloud_floating_ip.id), + "name": self.hcloud_floating_ip.name, + "description": self.hcloud_floating_ip.description, + "ip": self.hcloud_floating_ip.ip, + "type": self.hcloud_floating_ip.type, + "home_location": self.hcloud_floating_ip.home_location.name, "labels": self.hcloud_floating_ip.labels, - "server": server, + "server": self.hcloud_floating_ip.server.name if self.hcloud_floating_ip.server is not None else None, "delete_protection": self.hcloud_floating_ip.protection["delete"], } @@ -221,7 +216,8 @@ class AnsibleHCloudFloatingIP(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: - self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_floating_ip.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -266,7 +262,8 @@ class AnsibleHCloudFloatingIP(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_floating_ip.protection["delete"]: if not self.module.check_mode: - self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_floating_ip.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_floating_ip() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py index 663d29622..6595799ba 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py @@ -100,7 +100,6 @@ hcloud_floating_ip_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -116,23 +115,22 @@ class AnsibleHCloudFloatingIPInfo(AnsibleHCloud): tmp = [] for floating_ip in self.hcloud_floating_ip_info: - if floating_ip is not None: - server_name = None - if floating_ip.server is not None: - server_name = floating_ip.server.name - tmp.append( - { - "id": to_native(floating_ip.id), - "name": to_native(floating_ip.name), - "description": to_native(floating_ip.description), - "ip": to_native(floating_ip.ip), - "type": to_native(floating_ip.type), - "server": to_native(server_name), - "home_location": to_native(floating_ip.home_location.name), - "labels": floating_ip.labels, - "delete_protection": floating_ip.protection["delete"], - } - ) + if floating_ip is None: + continue + + tmp.append( + { + "id": str(floating_ip.id), + "name": floating_ip.name, + "description": floating_ip.description, + "ip": floating_ip.ip, + "type": floating_ip.type, + "server": floating_ip.server.name if floating_ip.server is not None else None, + "home_location": floating_ip.home_location.name, + "labels": floating_ip.labels, + "delete_protection": floating_ip.protection["delete"], + } + ) return tmp diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py index b0d7fc482..a3a1331c5 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py @@ -112,7 +112,6 @@ hcloud_image_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -128,20 +127,22 @@ class AnsibleHCloudImageInfo(AnsibleHCloud): tmp = [] for image in self.hcloud_image_info: - if image is not None: - tmp.append( - { - "id": to_native(image.id), - "status": to_native(image.status), - "type": to_native(image.type), - "name": to_native(image.name), - "description": to_native(image.description), - "os_flavor": to_native(image.os_flavor), - "os_version": to_native(image.os_version), - "architecture": to_native(image.architecture), - "labels": image.labels, - } - ) + if image is None: + continue + + tmp.append( + { + "id": str(image.id), + "status": image.status, + "type": image.type, + "name": image.name, + "description": image.description, + "os_flavor": image.os_flavor, + "os_version": image.os_version, + "architecture": image.architecture, + "labels": image.labels, + } + ) return tmp def get_images(self): diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py index e623d1714..aab33cab2 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py @@ -122,7 +122,6 @@ hcloud_iso_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -143,13 +142,13 @@ class AnsibleHCloudIsoInfo(AnsibleHCloud): tmp.append( { - "id": to_native(iso_info.id), - "name": to_native(iso_info.name), - "description": to_native(iso_info.description), + "id": str(iso_info.id), + "name": iso_info.name, + "description": iso_info.description, "type": iso_info.type, "architecture": iso_info.architecture, "deprecated": ( - iso_info.deprecation.unavailable_after if iso_info.deprecation is not None else None + iso_info.deprecation.unavailable_after.isoformat() if iso_info.deprecation is not None else None ), "deprecation": ( { diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py index 1a0d8712a..11dbf96fb 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py @@ -152,7 +152,6 @@ hcloud_load_balancer: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -168,23 +167,20 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud): hcloud_load_balancer: BoundLoadBalancer | None = None def _prepare_result(self): - private_ipv4_address = ( - None - if len(self.hcloud_load_balancer.private_net) == 0 - else to_native(self.hcloud_load_balancer.private_net[0].ip) - ) return { - "id": to_native(self.hcloud_load_balancer.id), - "name": to_native(self.hcloud_load_balancer.name), - "ipv4_address": to_native(self.hcloud_load_balancer.public_net.ipv4.ip), - "ipv6_address": to_native(self.hcloud_load_balancer.public_net.ipv6.ip), - "private_ipv4_address": private_ipv4_address, - "load_balancer_type": to_native(self.hcloud_load_balancer.load_balancer_type.name), - "algorithm": to_native(self.hcloud_load_balancer.algorithm.type), - "location": to_native(self.hcloud_load_balancer.location.name), + "id": str(self.hcloud_load_balancer.id), + "name": self.hcloud_load_balancer.name, + "ipv4_address": self.hcloud_load_balancer.public_net.ipv4.ip, + "ipv6_address": self.hcloud_load_balancer.public_net.ipv6.ip, + "private_ipv4_address": ( + self.hcloud_load_balancer.private_net[0].ip if len(self.hcloud_load_balancer.private_net) else None + ), + "load_balancer_type": self.hcloud_load_balancer.load_balancer_type.name, + "algorithm": self.hcloud_load_balancer.algorithm.type, + "location": self.hcloud_load_balancer.location.name, "labels": self.hcloud_load_balancer.labels, "delete_protection": self.hcloud_load_balancer.protection["delete"], - "disable_public_interface": False if self.hcloud_load_balancer.public_net.enabled else True, + "disable_public_interface": not self.hcloud_load_balancer.public_net.enabled, } def _get_load_balancer(self): @@ -217,12 +213,13 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud): if not self.module.check_mode: resp = self.client.load_balancers.create(**params) - resp.action.wait_until_finished(max_retries=1000) + resp.action.wait_until_finished() delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: self._get_load_balancer() - self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_load_balancer.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -239,7 +236,8 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_load_balancer.protection["delete"]: if not self.module.check_mode: - self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_load_balancer.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_load_balancer() @@ -249,9 +247,11 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud): ): if not self.module.check_mode: if disable_public_interface is True: - self.hcloud_load_balancer.disable_public_interface().wait_until_finished() + action = self.hcloud_load_balancer.disable_public_interface() + action.wait_until_finished() else: - self.hcloud_load_balancer.enable_public_interface().wait_until_finished() + action = self.hcloud_load_balancer.enable_public_interface() + action.wait_until_finished() self._mark_as_changed() load_balancer_type = self.module.params.get("load_balancer_type") @@ -263,17 +263,17 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud): if not new_load_balancer_type: self.module.fail_json(msg="unknown load balancer type") if not self.module.check_mode: - self.hcloud_load_balancer.change_type( + action = self.hcloud_load_balancer.change_type( load_balancer_type=new_load_balancer_type, - ).wait_until_finished(max_retries=1000) + ) + action.wait_until_finished() self._mark_as_changed() algorithm = self.module.params.get("algorithm") if algorithm is not None and self.hcloud_load_balancer.algorithm.type != algorithm: - self.hcloud_load_balancer.change_algorithm( - algorithm=LoadBalancerAlgorithm(type=algorithm) - ).wait_until_finished() + action = self.hcloud_load_balancer.change_algorithm(algorithm=LoadBalancerAlgorithm(type=algorithm)) + action.wait_until_finished() self._mark_as_changed() self._get_load_balancer() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py index 19ead98c2..4ed5f134b 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py @@ -277,11 +277,14 @@ hcloud_load_balancer_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException -from ..module_utils.vendor.hcloud.load_balancers import BoundLoadBalancer +from ..module_utils.vendor.hcloud.load_balancers import ( + BoundLoadBalancer, + LoadBalancerService, + LoadBalancerTarget, +) class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud): @@ -293,44 +296,40 @@ class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud): tmp = [] for load_balancer in self.hcloud_load_balancer_info: - if load_balancer is not None: - services = [self._prepare_service_result(service) for service in load_balancer.services] - targets = [self._prepare_target_result(target) for target in load_balancer.targets] - - private_ipv4_address = ( - None if len(load_balancer.private_net) == 0 else to_native(load_balancer.private_net[0].ip) - ) - tmp.append( - { - "id": to_native(load_balancer.id), - "name": to_native(load_balancer.name), - "ipv4_address": to_native(load_balancer.public_net.ipv4.ip), - "ipv6_address": to_native(load_balancer.public_net.ipv6.ip), - "private_ipv4_address": private_ipv4_address, - "load_balancer_type": to_native(load_balancer.load_balancer_type.name), - "location": to_native(load_balancer.location.name), - "labels": load_balancer.labels, - "delete_protection": load_balancer.protection["delete"], - "disable_public_interface": False if load_balancer.public_net.enabled else True, - "targets": targets, - "services": services, - } - ) + if load_balancer is None: + continue + + tmp.append( + { + "id": str(load_balancer.id), + "name": load_balancer.name, + "ipv4_address": load_balancer.public_net.ipv4.ip, + "ipv6_address": load_balancer.public_net.ipv6.ip, + "private_ipv4_address": load_balancer.private_net[0].ip if len(load_balancer.private_net) else None, + "load_balancer_type": load_balancer.load_balancer_type.name, + "location": load_balancer.location.name, + "labels": load_balancer.labels, + "delete_protection": load_balancer.protection["delete"], + "disable_public_interface": False if load_balancer.public_net.enabled else True, + "targets": [self._prepare_target_result(target) for target in load_balancer.targets], + "services": [self._prepare_service_result(service) for service in load_balancer.services], + } + ) return tmp @staticmethod - def _prepare_service_result(service): + def _prepare_service_result(service: LoadBalancerService): http = None if service.protocol != "tcp": http = { - "cookie_name": to_native(service.http.cookie_name), - "cookie_lifetime": service.http.cookie_name, + "cookie_name": service.http.cookie_name, + "cookie_lifetime": service.http.cookie_lifetime, "redirect_http": service.http.redirect_http, "sticky_sessions": service.http.sticky_sessions, - "certificates": [to_native(certificate.name) for certificate in service.http.certificates], + "certificates": [certificate.name for certificate in service.http.certificates], } health_check = { - "protocol": to_native(service.health_check.protocol), + "protocol": service.health_check.protocol, "port": service.health_check.port, "interval": service.health_check.interval, "timeout": service.health_check.timeout, @@ -338,14 +337,14 @@ class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud): } if service.health_check.protocol != "tcp": health_check["http"] = { - "domain": to_native(service.health_check.http.domain), - "path": to_native(service.health_check.http.path), - "response": to_native(service.health_check.http.response), - "certificates": [to_native(status_code) for status_code in service.health_check.http.status_codes], + "domain": service.health_check.http.domain, + "path": service.health_check.http.path, + "response": service.health_check.http.response, + "certificates": service.health_check.http.status_codes, "tls": service.health_check.http.tls, } return { - "protocol": to_native(service.protocol), + "protocol": service.protocol, "listen_port": service.listen_port, "destination_port": service.destination_port, "proxyprotocol": service.proxyprotocol, @@ -354,17 +353,17 @@ class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud): } @staticmethod - def _prepare_target_result(target): + def _prepare_target_result(target: LoadBalancerTarget): result = { - "type": to_native(target.type), + "type": target.type, "use_private_ip": target.use_private_ip, } if target.type == "server": - result["server"] = to_native(target.server.name) + result["server"] = target.server.name elif target.type == "label_selector": - result["label_selector"] = to_native(target.label_selector.selector) + result["label_selector"] = target.label_selector.selector elif target.type == "ip": - result["ip"] = to_native(target.ip.ip) + result["ip"] = target.ip.ip if target.health_status is not None: result["health_status"] = [ diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py index 4560f8735..b6ec486ed 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py @@ -90,7 +90,6 @@ hcloud_load_balancer_network: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -107,9 +106,9 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): def _prepare_result(self): return { - "network": to_native(self.hcloud_network.name), - "load_balancer": to_native(self.hcloud_load_balancer.name), - "ip": to_native(self.hcloud_load_balancer_network.ip), + "network": self.hcloud_network.name, + "load_balancer": self.hcloud_load_balancer.name, + "ip": self.hcloud_load_balancer_network.ip, } def _get_load_balancer_and_network(self): @@ -140,7 +139,8 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_load_balancer.attach_to_network(**params).wait_until_finished() + action = self.hcloud_load_balancer.attach_to_network(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -160,9 +160,8 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): if self.hcloud_load_balancer_network is not None and self.hcloud_load_balancer is not None: if not self.module.check_mode: try: - self.hcloud_load_balancer.detach_from_network( - self.hcloud_load_balancer_network.network - ).wait_until_finished() + action = self.hcloud_load_balancer.detach_from_network(self.hcloud_load_balancer_network.network) + action.wait_until_finished() self._mark_as_changed() except HCloudException as exception: self.fail_json_hcloud(exception) diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py index 1fc18deef..29e37083c 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py @@ -279,7 +279,6 @@ hcloud_load_balancer_service: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import APIException, HCloudException @@ -302,16 +301,16 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud): http = None if self.hcloud_load_balancer_service.protocol != "tcp": http = { - "cookie_name": to_native(self.hcloud_load_balancer_service.http.cookie_name), - "cookie_lifetime": self.hcloud_load_balancer_service.http.cookie_name, + "cookie_name": self.hcloud_load_balancer_service.http.cookie_name, + "cookie_lifetime": self.hcloud_load_balancer_service.http.cookie_lifetime, "redirect_http": self.hcloud_load_balancer_service.http.redirect_http, "sticky_sessions": self.hcloud_load_balancer_service.http.sticky_sessions, "certificates": [ - to_native(certificate.name) for certificate in self.hcloud_load_balancer_service.http.certificates + certificate.name for certificate in self.hcloud_load_balancer_service.http.certificates ], } health_check = { - "protocol": to_native(self.hcloud_load_balancer_service.health_check.protocol), + "protocol": self.hcloud_load_balancer_service.health_check.protocol, "port": self.hcloud_load_balancer_service.health_check.port, "interval": self.hcloud_load_balancer_service.health_check.interval, "timeout": self.hcloud_load_balancer_service.health_check.timeout, @@ -319,18 +318,15 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud): } if self.hcloud_load_balancer_service.health_check.protocol != "tcp": health_check["http"] = { - "domain": to_native(self.hcloud_load_balancer_service.health_check.http.domain), - "path": to_native(self.hcloud_load_balancer_service.health_check.http.path), - "response": to_native(self.hcloud_load_balancer_service.health_check.http.response), - "status_codes": [ - to_native(status_code) - for status_code in self.hcloud_load_balancer_service.health_check.http.status_codes - ], + "domain": self.hcloud_load_balancer_service.health_check.http.domain, + "path": self.hcloud_load_balancer_service.health_check.http.path, + "response": self.hcloud_load_balancer_service.health_check.http.response, + "status_codes": self.hcloud_load_balancer_service.health_check.http.status_codes, "tls": self.hcloud_load_balancer_service.health_check.http.tls, } return { - "load_balancer": to_native(self.hcloud_load_balancer.name), - "protocol": to_native(self.hcloud_load_balancer_service.protocol), + "load_balancer": self.hcloud_load_balancer.name, + "protocol": self.hcloud_load_balancer_service.protocol, "listen_port": self.hcloud_load_balancer_service.listen_port, "destination_port": self.hcloud_load_balancer_service.destination_port, "proxyprotocol": self.hcloud_load_balancer_service.proxyprotocol, @@ -372,9 +368,8 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_load_balancer.add_service(LoadBalancerService(**params)).wait_until_finished( - max_retries=1000 - ) + action = self.hcloud_load_balancer.add_service(LoadBalancerService(**params)) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -468,9 +463,8 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud): changed = True if not self.module.check_mode: - self.hcloud_load_balancer.update_service(LoadBalancerService(**params)).wait_until_finished( - max_retries=1000 - ) + action = self.hcloud_load_balancer.update_service(LoadBalancerService(**params)) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._get_load_balancer() @@ -496,9 +490,8 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud): if self.hcloud_load_balancer_service is not None: if not self.module.check_mode: try: - self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service).wait_until_finished( - max_retries=1000 - ) + action = self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py index 36e7f608f..c392ae712 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py @@ -134,7 +134,6 @@ hcloud_load_balancer_target: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import APIException, HCloudException @@ -156,17 +155,17 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud): def _prepare_result(self): result = { - "type": to_native(self.hcloud_load_balancer_target.type), - "load_balancer": to_native(self.hcloud_load_balancer.name), + "type": self.hcloud_load_balancer_target.type, + "load_balancer": self.hcloud_load_balancer.name, "use_private_ip": self.hcloud_load_balancer_target.use_private_ip, } if self.hcloud_load_balancer_target.type == "server": - result["server"] = to_native(self.hcloud_load_balancer_target.server.name) + result["server"] = self.hcloud_load_balancer_target.server.name elif self.hcloud_load_balancer_target.type == "label_selector": - result["label_selector"] = to_native(self.hcloud_load_balancer_target.label_selector.selector) + result["label_selector"] = self.hcloud_load_balancer_target.label_selector.selector elif self.hcloud_load_balancer_target.type == "ip": - result["ip"] = to_native(self.hcloud_load_balancer_target.ip.ip) + result["ip"] = self.hcloud_load_balancer_target.ip.ip return result def _get_load_balancer_and_target(self): @@ -225,7 +224,8 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_load_balancer.add_target(**params).wait_until_finished() + action = self.hcloud_load_balancer.add_target(**params) + action.wait_until_finished() except APIException as exception: if exception.code == "locked" or exception.code == "conflict": self._create_load_balancer_target() @@ -270,7 +270,8 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud): use_private_ip=False, ) try: - self.hcloud_load_balancer.remove_target(target).wait_until_finished() + action = self.hcloud_load_balancer.remove_target(target) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py index 67feafd59..90505651c 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py @@ -88,7 +88,6 @@ hcloud_load_balancer_type_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -104,18 +103,20 @@ class AnsibleHCloudLoadBalancerTypeInfo(AnsibleHCloud): tmp = [] for load_balancer_type in self.hcloud_load_balancer_type_info: - if load_balancer_type is not None: - tmp.append( - { - "id": to_native(load_balancer_type.id), - "name": to_native(load_balancer_type.name), - "description": to_native(load_balancer_type.description), - "max_connections": load_balancer_type.max_connections, - "max_services": load_balancer_type.max_services, - "max_targets": load_balancer_type.max_targets, - "max_assigned_certificates": load_balancer_type.max_assigned_certificates, - } - ) + if load_balancer_type is None: + continue + + tmp.append( + { + "id": str(load_balancer_type.id), + "name": load_balancer_type.name, + "description": load_balancer_type.description, + "max_connections": load_balancer_type.max_connections, + "max_services": load_balancer_type.max_services, + "max_targets": load_balancer_type.max_targets, + "max_assigned_certificates": load_balancer_type.max_assigned_certificates, + } + ) return tmp def get_load_balancer_types(self): diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py index ac495c6c8..676917bfc 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py @@ -78,7 +78,6 @@ hcloud_location_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -94,16 +93,18 @@ class AnsibleHCloudLocationInfo(AnsibleHCloud): tmp = [] for location in self.hcloud_location_info: - if location is not None: - tmp.append( - { - "id": to_native(location.id), - "name": to_native(location.name), - "description": to_native(location.description), - "city": to_native(location.city), - "country": to_native(location.country), - } - ) + if location is None: + continue + + tmp.append( + { + "id": str(location.id), + "name": location.name, + "description": location.description, + "city": location.city, + "country": location.country, + } + ) return tmp def get_locations(self): diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/network.py b/ansible_collections/hetzner/hcloud/plugins/modules/network.py index 24e45a48d..92fe9461e 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/network.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/network.py @@ -115,7 +115,6 @@ hcloud_network: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -129,9 +128,9 @@ class AnsibleHCloudNetwork(AnsibleHCloud): def _prepare_result(self): return { - "id": to_native(self.hcloud_network.id), - "name": to_native(self.hcloud_network.name), - "ip_range": to_native(self.hcloud_network.ip_range), + "id": str(self.hcloud_network.id), + "name": self.hcloud_network.name, + "ip_range": self.hcloud_network.ip_range, "expose_routes_to_vswitch": self.hcloud_network.expose_routes_to_vswitch, "delete_protection": self.hcloud_network.protection["delete"], "labels": self.hcloud_network.labels, @@ -165,7 +164,8 @@ class AnsibleHCloudNetwork(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: self._get_network() - self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_network.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -173,6 +173,13 @@ class AnsibleHCloudNetwork(AnsibleHCloud): def _update_network(self): try: + name = self.module.params.get("name") + if name is not None and self.hcloud_network.name != name: + self.module.fail_on_missing_params(required_params=["id"]) + if not self.module.check_mode: + self.hcloud_network.update(name=name) + self._mark_as_changed() + labels = self.module.params.get("labels") if labels is not None and labels != self.hcloud_network.labels: if not self.module.check_mode: @@ -182,7 +189,8 @@ class AnsibleHCloudNetwork(AnsibleHCloud): ip_range = self.module.params.get("ip_range") if ip_range is not None and ip_range != self.hcloud_network.ip_range: if not self.module.check_mode: - self.hcloud_network.change_ip_range(ip_range=ip_range).wait_until_finished() + action = self.hcloud_network.change_ip_range(ip_range=ip_range) + action.wait_until_finished() self._mark_as_changed() expose_routes_to_vswitch = self.module.params.get("expose_routes_to_vswitch") @@ -197,7 +205,8 @@ class AnsibleHCloudNetwork(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_network.protection["delete"]: if not self.module.check_mode: - self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_network.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() except HCloudException as exception: self.fail_json_hcloud(exception) diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py index 4008352b4..8f1e5fbf7 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py @@ -185,7 +185,6 @@ hcloud_network_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -201,55 +200,55 @@ class AnsibleHCloudNetworkInfo(AnsibleHCloud): tmp = [] for network in self.hcloud_network_info: - if network is not None: - subnets = [] - for subnet in network.subnets: - prepared_subnet = { - "type": subnet.type, - "ip_range": subnet.ip_range, - "network_zone": subnet.network_zone, - "gateway": subnet.gateway, - } - subnets.append(prepared_subnet) - routes = [] - for route in network.routes: - prepared_route = {"destination": route.destination, "gateway": route.gateway} - routes.append(prepared_route) - - servers = [] - for server in network.servers: - image = None if server.image is None else to_native(server.image.name) - ipv4_address = None if server.public_net.ipv4 is None else to_native(server.public_net.ipv4.ip) - ipv6 = None if server.public_net.ipv6 is None else to_native(server.public_net.ipv6.ip) - prepared_server = { - "id": to_native(server.id), - "name": to_native(server.name), - "ipv4_address": ipv4_address, - "ipv6": ipv6, - "image": image, - "server_type": to_native(server.server_type.name), - "datacenter": to_native(server.datacenter.name), - "location": to_native(server.datacenter.location.name), - "rescue_enabled": server.rescue_enabled, - "backup_window": to_native(server.backup_window), - "labels": server.labels, - "status": to_native(server.status), - } - servers.append(prepared_server) - - tmp.append( - { - "id": to_native(network.id), - "name": to_native(network.name), - "ip_range": to_native(network.ip_range), - "subnetworks": subnets, - "routes": routes, - "expose_routes_to_vswitch": network.expose_routes_to_vswitch, - "servers": servers, - "labels": network.labels, - "delete_protection": network.protection["delete"], - } - ) + if network is None: + continue + + subnets = [] + for subnet in network.subnets: + prepared_subnet = { + "type": subnet.type, + "ip_range": subnet.ip_range, + "network_zone": subnet.network_zone, + "gateway": subnet.gateway, + } + subnets.append(prepared_subnet) + + routes = [] + for route in network.routes: + prepared_route = {"destination": route.destination, "gateway": route.gateway} + routes.append(prepared_route) + + servers = [] + for server in network.servers: + prepared_server = { + "id": str(server.id), + "name": server.name, + "ipv4_address": server.public_net.ipv4.ip if server.public_net.ipv4 is not None else None, + "ipv6": server.public_net.ipv6.ip if server.public_net.ipv6 is not None else None, + "image": server.image.name if server.image is not None else None, + "server_type": server.server_type.name, + "datacenter": server.datacenter.name, + "location": server.datacenter.location.name, + "rescue_enabled": server.rescue_enabled, + "backup_window": server.backup_window, + "labels": server.labels, + "status": server.status, + } + servers.append(prepared_server) + + tmp.append( + { + "id": str(network.id), + "name": network.name, + "ip_range": network.ip_range, + "subnetworks": subnets, + "routes": routes, + "expose_routes_to_vswitch": network.expose_routes_to_vswitch, + "servers": servers, + "labels": network.labels, + "delete_protection": network.protection["delete"], + } + ) return tmp def get_networks(self): diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py b/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py index ba26fad22..45a0cd76b 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py @@ -107,7 +107,6 @@ hcloud_placement_group: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -121,10 +120,10 @@ class AnsibleHCloudPlacementGroup(AnsibleHCloud): def _prepare_result(self): return { - "id": to_native(self.hcloud_placement_group.id), - "name": to_native(self.hcloud_placement_group.name), + "id": str(self.hcloud_placement_group.id), + "name": self.hcloud_placement_group.name, "labels": self.hcloud_placement_group.labels, - "type": to_native(self.hcloud_placement_group.type), + "type": self.hcloud_placement_group.type, "servers": self.hcloud_placement_group.servers, } diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py index 607f6c7e1..08bcea493 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py @@ -35,6 +35,12 @@ options: - Home Location of the Hetzner Cloud Primary IP. - Required if no I(server) is given and Primary IP does not exist. type: str + server: + description: + - Name or ID of the Hetzner Cloud Server the Primary IP should be assigned to. + - The Primary IP cannot be assigned to a running server. + - Required if no O(datacenter) is given and the Primary IP does not exist. + type: str type: description: - Type of the Primary IP. @@ -43,9 +49,9 @@ options: type: str auto_delete: description: - - Delete this Primary IP when the resource it is assigned to is deleted + - Delete the Primary IP when the resource it is assigned to is deleted. type: bool - default: no + default: false delete_protection: description: - Protect the Primary IP for deletion. @@ -66,22 +72,39 @@ extends_documentation_fragment: """ EXAMPLES = """ -- name: Create a basic IPv4 Primary IP +- name: Create a IPv4 Primary IP hetzner.hcloud.primary_ip: name: my-primary-ip datacenter: fsn1-dc14 type: ipv4 state: present -- name: Create a basic IPv6 Primary IP + +- name: Create a IPv6 Primary IP hetzner.hcloud.primary_ip: name: my-primary-ip datacenter: fsn1-dc14 type: ipv6 state: present -- name: Primary IP should be absent + +- name: Delete a Primary IP hetzner.hcloud.primary_ip: name: my-primary-ip state: absent + +- name: Ensure the server is stopped + hetzner.hcloud.server: + name: my-server + state: stopped +- name: Create a Primary IP attached to a Server + hetzner.hcloud.primary_ip: + name: my-primary-ip + server: my-server + type: ipv4 + state: present +- name: Ensure the server is started + hetzner.hcloud.server: + name: my-server + state: started """ RETURN = """ @@ -127,10 +150,24 @@ hcloud_primary_ip: sample: key: value mylabel: 123 + assignee_id: + description: ID of the resource the Primary IP is assigned to, null if it is not assigned. + type: int + returned: always + sample: 1937415 + assignee_type: + description: Resource type the Primary IP can be assigned to. + type: str + returned: always + sample: server + auto_delete: + description: Delete the Primary IP when the resource it is assigned to is deleted. + type: bool + returned: always + sample: false """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -144,13 +181,18 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud): def _prepare_result(self): return { - "id": to_native(self.hcloud_primary_ip.id), - "name": to_native(self.hcloud_primary_ip.name), - "ip": to_native(self.hcloud_primary_ip.ip), - "type": to_native(self.hcloud_primary_ip.type), - "datacenter": to_native(self.hcloud_primary_ip.datacenter.name), + "id": str(self.hcloud_primary_ip.id), + "name": self.hcloud_primary_ip.name, + "ip": self.hcloud_primary_ip.ip, + "type": self.hcloud_primary_ip.type, + "datacenter": self.hcloud_primary_ip.datacenter.name, "labels": self.hcloud_primary_ip.labels, "delete_protection": self.hcloud_primary_ip.protection["delete"], + "assignee_id": ( + str(self.hcloud_primary_ip.assignee_id) if self.hcloud_primary_ip.assignee_id is not None else None + ), + "assignee_type": self.hcloud_primary_ip.assignee_type, + "auto_delete": self.hcloud_primary_ip.auto_delete, } def _get_primary_ip(self): @@ -163,23 +205,35 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud): self.fail_json_hcloud(exception) def _create_primary_ip(self): - self.module.fail_on_missing_params(required_params=["type", "datacenter"]) + self.fail_on_invalid_params( + required=["type", "name"], + required_one_of=[["server", "datacenter"]], + ) try: params = { "type": self.module.params.get("type"), "name": self.module.params.get("name"), - "datacenter": self.client.datacenters.get_by_name(self.module.params.get("datacenter")), + "auto_delete": self.module.params.get("auto_delete"), + "datacenter": None, # TODO: https://github.com/hetznercloud/hcloud-python/pull/363 } + if self.module.params.get("datacenter") is not None: + params["datacenter"] = self.client.datacenters.get_by_name(self.module.params.get("datacenter")) + elif self.module.params.get("server") is not None: + params["assignee_id"] = self._client_get_by_name_or_id("servers", self.module.params.get("server")).id + if self.module.params.get("labels") is not None: params["labels"] = self.module.params.get("labels") if not self.module.check_mode: resp = self.client.primary_ips.create(**params) + if resp.action is not None: + resp.action.wait_until_finished() self.hcloud_primary_ip = resp.primary_ip delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: - self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_primary_ip.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -187,16 +241,26 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud): def _update_primary_ip(self): try: + changes = {} + + auto_delete = self.module.params.get("auto_delete") + if auto_delete is not None and auto_delete != self.hcloud_primary_ip.auto_delete: + changes["auto_delete"] = auto_delete + labels = self.module.params.get("labels") if labels is not None and labels != self.hcloud_primary_ip.labels: + changes["labels"] = labels + + if changes: if not self.module.check_mode: - self.hcloud_primary_ip.update(labels=labels) + self.hcloud_primary_ip.update(**changes) self._mark_as_changed() delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_primary_ip.protection["delete"]: if not self.module.check_mode: - self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_primary_ip.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_primary_ip() @@ -228,6 +292,7 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud): id={"type": "int"}, name={"type": "str"}, datacenter={"type": "str"}, + server={"type": "str"}, auto_delete={"type": "bool", "default": False}, type={"choices": ["ipv4", "ipv6"]}, labels={"type": "dict"}, diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py index c0bfdbb35..72e359ae2 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py @@ -117,10 +117,14 @@ hcloud_primary_ip_info: description: True if the Primary IP is protected for deletion returned: always type: bool + auto_delete: + description: Delete the Primary IP when the resource it is assigned to is deleted. + type: bool + returned: always + sample: false """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -136,26 +140,24 @@ class AnsibleHCloudPrimaryIPInfo(AnsibleHCloud): tmp = [] for primary_ip in self.hcloud_primary_ip_info: - if primary_ip is not None: - dns_ptr = None - if len(primary_ip.dns_ptr) > 0: - dns_ptr = primary_ip.dns_ptr[0]["dns_ptr"] - tmp.append( - { - "id": to_native(primary_ip.id), - "name": to_native(primary_ip.name), - "ip": to_native(primary_ip.ip), - "type": to_native(primary_ip.type), - "assignee_id": ( - to_native(primary_ip.assignee_id) if primary_ip.assignee_id is not None else None - ), - "assignee_type": to_native(primary_ip.assignee_type), - "home_location": to_native(primary_ip.datacenter.name), - "dns_ptr": to_native(dns_ptr) if dns_ptr is not None else None, - "labels": primary_ip.labels, - "delete_protection": primary_ip.protection["delete"], - } - ) + if primary_ip is None: + continue + + tmp.append( + { + "id": str(primary_ip.id), + "name": primary_ip.name, + "ip": primary_ip.ip, + "type": primary_ip.type, + "assignee_id": str(primary_ip.assignee_id) if primary_ip.assignee_id is not None else None, + "assignee_type": primary_ip.assignee_type, + "auto_delete": primary_ip.auto_delete, + "home_location": primary_ip.datacenter.name, + "dns_ptr": primary_ip.dns_ptr[0]["dns_ptr"] if len(primary_ip.dns_ptr) else None, + "labels": primary_ip.labels, + "delete_protection": primary_ip.protection["delete"], + } + ) return tmp diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py b/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py index b2decdec8..4e21f3e92 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py @@ -136,7 +136,6 @@ import ipaddress from typing import Any from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -157,18 +156,18 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud): "server": None, "floating_ip": None, "load_balancer": None, - "ip_address": to_native(self.hcloud_rdns["ip_address"]), - "dns_ptr": to_native(self.hcloud_rdns["dns_ptr"]), + "ip_address": self.hcloud_rdns["ip_address"], + "dns_ptr": self.hcloud_rdns["dns_ptr"], } if self.module.params.get("server"): - result["server"] = to_native(self.hcloud_resource.name) + result["server"] = self.hcloud_resource.name elif self.module.params.get("floating_ip"): - result["floating_ip"] = to_native(self.hcloud_resource.name) + result["floating_ip"] = self.hcloud_resource.name elif self.module.params.get("load_balancer"): - result["load_balancer"] = to_native(self.hcloud_resource.name) + result["load_balancer"] = self.hcloud_resource.name elif self.module.params.get("primary_ip"): - result["primary_ip"] = to_native(self.hcloud_resource.name) + result["primary_ip"] = self.hcloud_resource.name return result def _get_resource(self): @@ -277,7 +276,8 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_resource.change_dns_ptr(**params).wait_until_finished() + action = self.hcloud_resource.change_dns_ptr(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -294,7 +294,8 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_resource.change_dns_ptr(**params).wait_until_finished() + action = self.hcloud_resource.change_dns_ptr(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/route.py b/ansible_collections/hetzner/hcloud/plugins/modules/route.py index 3c96a7382..37ff50b07 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/route.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/route.py @@ -86,7 +86,6 @@ hcloud_route: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -101,8 +100,8 @@ class AnsibleHCloudRoute(AnsibleHCloud): def _prepare_result(self): return { - "network": to_native(self.hcloud_network.name), - "destination": to_native(self.hcloud_route.destination), + "network": self.hcloud_network.name, + "destination": self.hcloud_route.destination, "gateway": self.hcloud_route.gateway, } @@ -130,7 +129,8 @@ class AnsibleHCloudRoute(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_network.add_route(route=route).wait_until_finished() + action = self.hcloud_network.add_route(route=route) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -150,7 +150,8 @@ class AnsibleHCloudRoute(AnsibleHCloud): if self.hcloud_route is not None and self.hcloud_network is not None: if not self.module.check_mode: try: - self.hcloud_network.delete_route(self.hcloud_route).wait_until_finished() + action = self.hcloud_network.delete_route(self.hcloud_route) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server.py b/ansible_collections/hetzner/hcloud/plugins/modules/server.py index f5cadb807..d7bae3fc1 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/server.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/server.py @@ -22,50 +22,58 @@ author: options: id: description: - - The ID of the Hetzner Cloud server to manage. - - Only required if no server I(name) is given + - ID of the Hetzner Cloud Server to manage. + - Only required if no server O(name) is given type: int name: description: - - The Name of the Hetzner Cloud server to manage. - - Only required if no server I(id) is given or a server does not exist. + - Name of the Hetzner Cloud Server to manage. + - Only required if no server O(id) is given or a server does not exist. type: str server_type: description: - - The Server Type of the Hetzner Cloud server to manage. + - Hetzner Cloud Server Type (name or ID) of the server. - Required if server does not exist. type: str ssh_keys: description: - - List of SSH key names - - The key names correspond to the SSH keys configured for your - Hetzner Cloud account access. + - List of Hetzner Cloud SSH Keys (name or ID) to create the server with. + - Only used during the server creation. type: list elements: str volumes: description: - - List of Volumes IDs that should be attached to the server on server creation. + - List of Hetzner Cloud Volumes (name or ID) that should be attached to the server. + - Only used during the server creation. type: list elements: str firewalls: description: - - List of Firewall IDs that should be attached to the server on server creation. + - List of Hetzner Cloud Firewalls (name or ID) that should be attached to the server. type: list elements: str image: description: - - Image the server should be created from. - - Required if server does not exist. + - Hetzner Cloud Image (name or ID) to create the server from. + - Required if server does not exist or when O(state=rebuild). type: str + image_allow_deprecated: + description: + - Allows the creation of servers with deprecated images. + type: bool + default: false + aliases: [allow_deprecated_image] location: description: - - Location of Server. - - Required if no I(datacenter) is given and server does not exist. + - Hetzner Cloud Location (name or ID) to create the server in. + - Required if no O(datacenter) is given and server does not exist. + - Only used during the server creation. type: str datacenter: description: - - Datacenter of Server. - - Required if no I(location) is given and server does not exist. + - Hetzner Cloud Datacenter (name or ID) to create the server in. + - Required if no O(location) is given and server does not exist. + - Only used during the server creation. type: str backups: description: @@ -79,50 +87,42 @@ options: default: false enable_ipv4: description: - - Enables the public ipv4 address + - Enables the public ipv4 address. type: bool default: true enable_ipv6: description: - - Enables the public ipv6 address + - Enables the public ipv6 address. type: bool default: true ipv4: description: - - ID of the ipv4 Primary IP to use. If omitted and enable_ipv4 is true, a new ipv4 Primary IP will automatically be created + - Hetzner Cloud Primary IPv4 (name or ID) to use. + - If omitted and O(enable_ipv4=true), a new ipv4 Primary IP will automatically be created. type: str ipv6: description: - - ID of the ipv6 Primary IP to use. If omitted and enable_ipv6 is true, a new ipv6 Primary IP will automatically be created. + - Hetzner Cloud Primary IPv6 (name or ID) to use. + - If omitted and O(enable_ipv6=true), a new ipv6 Primary IP will automatically be created. type: str private_networks: description: - - List of private networks the server is attached to (name or ID) + - List of Hetzner Cloud Networks (name or ID) the server should be attached to. - If None, private networks are left as they are (e.g. if previously added by hcloud_server_network), if it has any other value (including []), only those networks are attached to the server. type: list elements: str - force_upgrade: - description: - - Deprecated - - Force the upgrade of the server. - - Power off the server if it is running on upgrade. - type: bool force: description: - Force the update of the server. - - May power off the server if update. - type: bool - default: false - allow_deprecated_image: - description: - - Allows the creation of servers with deprecated images. + - May power off the server if update is applied. type: bool default: false + aliases: [force_upgrade] user_data: description: - User Data to be passed to the server on creation. - - Only used if server does not exist. + - Only used during the server creation. type: str rescue_mode: description: @@ -135,16 +135,16 @@ options: delete_protection: description: - Protect the Server for deletion. - - Needs to be the same as I(rebuild_protection). + - Needs to be the same as O(rebuild_protection). type: bool rebuild_protection: description: - Protect the Server for rebuild. - - Needs to be the same as I(delete_protection). + - Needs to be the same as O(delete_protection). type: bool placement_group: description: - - Placement Group of the server. + - Hetzner Cloud Placement Group (name or ID) to create the server in. type: str state: description: @@ -336,9 +336,9 @@ hcloud_server: """ from datetime import datetime, timedelta, timezone +from typing import TYPE_CHECKING, Literal from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -348,8 +348,14 @@ from ..module_utils.vendor.hcloud.servers import ( Server, ServerCreatePublicNetwork, ) -from ..module_utils.vendor.hcloud.ssh_keys import SSHKey -from ..module_utils.vendor.hcloud.volumes import Volume + +if TYPE_CHECKING: + from ..module_utils.vendor.hcloud.actions import BoundAction + from ..module_utils.vendor.hcloud.firewalls import BoundFirewall + from ..module_utils.vendor.hcloud.networks import BoundNetwork + from ..module_utils.vendor.hcloud.placement_groups import BoundPlacementGroup + from ..module_utils.vendor.hcloud.primary_ips import PrimaryIP + from ..module_utils.vendor.hcloud.server_types import ServerType class AnsibleHCloudServer(AnsibleHCloud): @@ -358,38 +364,31 @@ class AnsibleHCloudServer(AnsibleHCloud): hcloud_server: BoundServer | None = None def _prepare_result(self): - image = None if self.hcloud_server.image is None else to_native(self.hcloud_server.image.name) - placement_group = ( - None if self.hcloud_server.placement_group is None else to_native(self.hcloud_server.placement_group.name) - ) - ipv4_address = ( - None if self.hcloud_server.public_net.ipv4 is None else to_native(self.hcloud_server.public_net.ipv4.ip) - ) - ipv6 = None if self.hcloud_server.public_net.ipv6 is None else to_native(self.hcloud_server.public_net.ipv6.ip) - backup_window = ( - None if self.hcloud_server.backup_window is None else to_native(self.hcloud_server.backup_window) - ) return { - "id": to_native(self.hcloud_server.id), - "name": to_native(self.hcloud_server.name), - "created": to_native(self.hcloud_server.created.isoformat()), - "ipv4_address": ipv4_address, - "ipv6": ipv6, - "private_networks": [to_native(net.network.name) for net in self.hcloud_server.private_net], + "id": str(self.hcloud_server.id), + "name": self.hcloud_server.name, + "created": self.hcloud_server.created.isoformat(), + "ipv4_address": ( + self.hcloud_server.public_net.ipv4.ip if self.hcloud_server.public_net.ipv4 is not None else None + ), + "ipv6": self.hcloud_server.public_net.ipv6.ip if self.hcloud_server.public_net.ipv6 is not None else None, + "private_networks": [net.network.name for net in self.hcloud_server.private_net], "private_networks_info": [ - {"name": to_native(net.network.name), "ip": net.ip} for net in self.hcloud_server.private_net + {"name": net.network.name, "ip": net.ip} for net in self.hcloud_server.private_net ], - "image": image, - "server_type": to_native(self.hcloud_server.server_type.name), - "datacenter": to_native(self.hcloud_server.datacenter.name), - "location": to_native(self.hcloud_server.datacenter.location.name), - "placement_group": placement_group, + "image": self.hcloud_server.image.name if self.hcloud_server.image is not None else None, + "server_type": self.hcloud_server.server_type.name, + "datacenter": self.hcloud_server.datacenter.name, + "location": self.hcloud_server.datacenter.location.name, + "placement_group": ( + self.hcloud_server.placement_group.name if self.hcloud_server.placement_group is not None else None + ), "rescue_enabled": self.hcloud_server.rescue_enabled, - "backup_window": backup_window, + "backup_window": self.hcloud_server.backup_window, "labels": self.hcloud_server.labels, "delete_protection": self.hcloud_server.protection["delete"], "rebuild_protection": self.hcloud_server.protection["rebuild"], - "status": to_native(self.hcloud_server.status), + "status": self.hcloud_server.status, } def _get_server(self): @@ -405,73 +404,76 @@ class AnsibleHCloudServer(AnsibleHCloud): self.module.fail_on_missing_params(required_params=["name", "server_type", "image"]) server_type = self._get_server_type() + image = self._get_image(server_type) params = { "name": self.module.params.get("name"), + "labels": self.module.params.get("labels"), "server_type": server_type, + "image": image, "user_data": self.module.params.get("user_data"), - "labels": self.module.params.get("labels"), - "image": self._get_image(server_type), - "placement_group": self._get_placement_group(), "public_net": ServerCreatePublicNetwork( enable_ipv4=self.module.params.get("enable_ipv4"), enable_ipv6=self.module.params.get("enable_ipv6"), ), } + if self.module.params.get("placement_group") is not None: + params["placement_group"] = self._client_get_by_name_or_id( + "placement_groups", self.module.params.get("placement_group") + ) + if self.module.params.get("ipv4") is not None: - primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("ipv4")) - if not primary_ip: - primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("ipv4")) - params["public_net"].ipv4 = primary_ip + params["public_net"].ipv4 = self._client_get_by_name_or_id("primary_ips", self.module.params.get("ipv4")) if self.module.params.get("ipv6") is not None: - primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("ipv6")) - if not primary_ip: - primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("ipv6")) - params["public_net"].ipv6 = primary_ip + params["public_net"].ipv6 = self._client_get_by_name_or_id("primary_ips", self.module.params.get("ipv6")) if self.module.params.get("private_networks") is not None: - _networks = [] - for network_name_or_id in self.module.params.get("private_networks"): - _networks.append( - self.client.networks.get_by_name(network_name_or_id) - or self.client.networks.get_by_id(network_name_or_id) - ) - params["networks"] = _networks + params["networks"] = [ + self._client_get_by_name_or_id("networks", name_or_id) + for name_or_id in self.module.params.get("private_networks") + ] if self.module.params.get("ssh_keys") is not None: - params["ssh_keys"] = [SSHKey(name=ssh_key_name) for ssh_key_name in self.module.params.get("ssh_keys")] + params["ssh_keys"] = [ + self._client_get_by_name_or_id("ssh_keys", name_or_id) + for name_or_id in self.module.params.get("ssh_keys") + ] if self.module.params.get("volumes") is not None: - params["volumes"] = [Volume(id=volume_id) for volume_id in self.module.params.get("volumes")] + params["volumes"] = [ + self._client_get_by_name_or_id("volumes", name_or_id) + for name_or_id in self.module.params.get("volumes") + ] + if self.module.params.get("firewalls") is not None: - params["firewalls"] = [] - for firewall_param in self.module.params.get("firewalls"): - firewall = self.client.firewalls.get_by_name(firewall_param) - if firewall is not None: - # When firewall name is not available look for id instead - params["firewalls"].append(firewall) - else: - params["firewalls"].append(self.client.firewalls.get_by_id(firewall_param)) + params["firewalls"] = [ + self._client_get_by_name_or_id("firewalls", name_or_id) + for name_or_id in self.module.params.get("firewalls") + ] if self.module.params.get("location") is None and self.module.params.get("datacenter") is None: # When not given, the API will choose the location. params["location"] = None params["datacenter"] = None elif self.module.params.get("location") is not None and self.module.params.get("datacenter") is None: - params["location"] = self.client.locations.get_by_name(self.module.params.get("location")) + params["location"] = self._client_get_by_name_or_id("locations", self.module.params.get("location")) elif self.module.params.get("location") is None and self.module.params.get("datacenter") is not None: - params["datacenter"] = self.client.datacenters.get_by_name(self.module.params.get("datacenter")) + params["datacenter"] = self._client_get_by_name_or_id("datacenters", self.module.params.get("datacenter")) if self.module.params.get("state") == "stopped": params["start_after_create"] = False + if not self.module.check_mode: try: resp = self.client.servers.create(**params) self.result["root_password"] = resp.root_password - resp.action.wait_until_finished(max_retries=1000) - [action.wait_until_finished() for action in resp.next_actions] + # Action should take 60 to 90 seconds on average, but can be >10m when creating a + # server from a custom images + resp.action.wait_until_finished(max_retries=1800) + for action in resp.next_actions: + action.wait_until_finished() rescue_mode = self.module.params.get("rescue_mode") if rescue_mode: @@ -481,40 +483,35 @@ class AnsibleHCloudServer(AnsibleHCloud): backups = self.module.params.get("backups") if backups: self._get_server() - self.hcloud_server.enable_backup().wait_until_finished() + action = self.hcloud_server.enable_backup() + action.wait_until_finished() delete_protection = self.module.params.get("delete_protection") rebuild_protection = self.module.params.get("rebuild_protection") if delete_protection is not None and rebuild_protection is not None: self._get_server() - self.hcloud_server.change_protection( + action = self.hcloud_server.change_protection( delete=delete_protection, rebuild=rebuild_protection, - ).wait_until_finished() + ) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() self._get_server() - def _get_image(self, server_type): - image_resp = self.client.images.get_list( + def _get_image(self, server_type: ServerType): + image = self.client.images.get_by_name_and_architecture( name=self.module.params.get("image"), architecture=server_type.architecture, include_deprecated=True, ) - images = getattr(image_resp, "images") - image = None - if images is not None and len(images) > 0: - # If image name is not available look for id instead - image = images[0] - else: - try: - image = self.client.images.get_by_id(self.module.params.get("image")) - except HCloudException as exception: - self.fail_json_hcloud(exception, msg=f"Image {self.module.params.get('image')} was not found") + if image is None: + image = self.client.images.get_by_id(self.module.params.get("image")) + if image.deprecated is not None: available_until = image.deprecated + timedelta(days=90) - if self.module.params.get("allow_deprecated_image"): + if self.module.params.get("image_allow_deprecated"): self.module.warn( f"You try to use a deprecated image. The image {image.name} will " f"continue to be available until {available_until.strftime('%Y-%m-%d')}." @@ -524,27 +521,18 @@ class AnsibleHCloudServer(AnsibleHCloud): msg=( f"You try to use a deprecated image. The image {image.name} will " f"continue to be available until {available_until.strftime('%Y-%m-%d')}. " - "If you want to use this image use allow_deprecated_image=true." + "If you want to use this image use image_allow_deprecated=true." ) ) return image - def _get_server_type(self): - server_type = self.client.server_types.get_by_name(self.module.params.get("server_type")) - if server_type is None: - try: - server_type = self.client.server_types.get_by_id(self.module.params.get("server_type")) - except HCloudException as exception: - self.fail_json_hcloud( - exception, - msg=f"server_type {self.module.params.get('server_type')} was not found", - ) + def _get_server_type(self) -> ServerType: + server_type = self._client_get_by_name_or_id("server_types", self.module.params.get("server_type")) self._check_and_warn_deprecated_server(server_type) - return server_type - def _check_and_warn_deprecated_server(self, server_type): + def _check_and_warn_deprecated_server(self, server_type: ServerType) -> None: if server_type.deprecation is None: return @@ -567,42 +555,16 @@ class AnsibleHCloudServer(AnsibleHCloud): "the server_type parameter on the hetzner.hcloud.server module." ) - def _get_placement_group(self): - if self.module.params.get("placement_group") is None: - return None - - placement_group = self.client.placement_groups.get_by_name(self.module.params.get("placement_group")) - if placement_group is None: - try: - placement_group = self.client.placement_groups.get_by_id(self.module.params.get("placement_group")) - except HCloudException as exception: - self.fail_json_hcloud( - exception, - msg=f"placement_group {self.module.params.get('placement_group')} was not found", - ) - - return placement_group - - def _get_primary_ip(self, field): - if self.module.params.get(field) is None: - return None - - primary_ip = self.client.primary_ips.get_by_name(self.module.params.get(field)) - if primary_ip is None: - try: - primary_ip = self.client.primary_ips.get_by_id(self.module.params.get(field)) - except HCloudException as exception: - self.fail_json_hcloud(exception, msg=f"primary_ip {self.module.params.get(field)} was not found") - - return primary_ip - - def _update_server(self): - if "force_upgrade" in self.module.params and self.module.params.get("force_upgrade") is not None: - self.module.warn("force_upgrade is deprecated, use force instead") - + def _update_server(self) -> None: try: previous_server_status = self.hcloud_server.status + labels = self.module.params.get("labels") + if labels is not None and labels != self.hcloud_server.labels: + if not self.module.check_mode: + self.hcloud_server.update(labels=labels) + self._mark_as_changed() + rescue_mode = self.module.params.get("rescue_mode") if rescue_mode and self.hcloud_server.rescue_enabled is False: if not self.module.check_mode: @@ -610,167 +572,39 @@ class AnsibleHCloudServer(AnsibleHCloud): self._mark_as_changed() elif not rescue_mode and self.hcloud_server.rescue_enabled is True: if not self.module.check_mode: - self.hcloud_server.disable_rescue().wait_until_finished() + action = self.hcloud_server.disable_rescue() + action.wait_until_finished() self._mark_as_changed() backups = self.module.params.get("backups") if backups and self.hcloud_server.backup_window is None: if not self.module.check_mode: - self.hcloud_server.enable_backup().wait_until_finished() + action = self.hcloud_server.enable_backup() + action.wait_until_finished() self._mark_as_changed() elif backups is not None and not backups and self.hcloud_server.backup_window is not None: if not self.module.check_mode: - self.hcloud_server.disable_backup().wait_until_finished() + action = self.hcloud_server.disable_backup() + action.wait_until_finished() self._mark_as_changed() - labels = self.module.params.get("labels") - if labels is not None and labels != self.hcloud_server.labels: - if not self.module.check_mode: - self.hcloud_server.update(labels=labels) - self._mark_as_changed() + if self.module.params.get("firewalls") is not None: + self._update_server_firewalls() - wanted_firewalls = self.module.params.get("firewalls") - if wanted_firewalls is not None: - # Removing existing but not wanted firewalls - for current_firewall in self.hcloud_server.public_net.firewalls: - if current_firewall.firewall.name not in wanted_firewalls: - self._mark_as_changed() - if self.module.check_mode: - continue - - firewall_resource = FirewallResource(type="server", server=self.hcloud_server) - actions = self.client.firewalls.remove_from_resources( - current_firewall.firewall, - [firewall_resource], - ) - for action in actions: - action.wait_until_finished() - - # Adding wanted firewalls that doesn't exist yet - for firewall_name in wanted_firewalls: - found = False - for firewall in self.hcloud_server.public_net.firewalls: - if firewall.firewall.name == firewall_name: - found = True - break - - if not found: - self._mark_as_changed() - if not self.module.check_mode: - firewall = self.client.firewalls.get_by_name(firewall_name) - if firewall is None: - self.module.fail_json(msg=f"firewall {firewall_name} was not found") - firewall_resource = FirewallResource(type="server", server=self.hcloud_server) - actions = self.client.firewalls.apply_to_resources(firewall, [firewall_resource]) - for action in actions: - action.wait_until_finished() - - if "placement_group" in self.module.params: - if self.module.params["placement_group"] is None and self.hcloud_server.placement_group is not None: - if not self.module.check_mode: - self.hcloud_server.remove_from_placement_group().wait_until_finished() - self._mark_as_changed() - else: - placement_group = self._get_placement_group() - if placement_group is not None and ( - self.hcloud_server.placement_group is None - or self.hcloud_server.placement_group.id != placement_group.id - ): - self.stop_server_if_forced() - if not self.module.check_mode: - self.hcloud_server.add_to_placement_group(placement_group).wait_until_finished() - self._mark_as_changed() - - if "ipv4" in self.module.params: - if ( - self.module.params["ipv4"] is None - and self.hcloud_server.public_net.primary_ipv4 is not None - and not self.module.params.get("enable_ipv4") - ): - self.stop_server_if_forced() - if not self.module.check_mode: - self.hcloud_server.public_net.primary_ipv4.unassign().wait_until_finished() - self._mark_as_changed() - else: - primary_ip = self._get_primary_ip("ipv4") - if primary_ip is not None and ( - self.hcloud_server.public_net.primary_ipv4 is None - or self.hcloud_server.public_net.primary_ipv4.id != primary_ip.id - ): - self.stop_server_if_forced() - if not self.module.check_mode: - if self.hcloud_server.public_net.primary_ipv4: - self.hcloud_server.public_net.primary_ipv4.unassign().wait_until_finished() - primary_ip.assign(self.hcloud_server.id, "server").wait_until_finished() - self._mark_as_changed() - if "ipv6" in self.module.params: - if ( - (self.module.params["ipv6"] is None or self.module.params["ipv6"] == "") - and self.hcloud_server.public_net.primary_ipv6 is not None - and not self.module.params.get("enable_ipv6") - ): - self.stop_server_if_forced() - if not self.module.check_mode: - self.hcloud_server.public_net.primary_ipv6.unassign().wait_until_finished() - self._mark_as_changed() - else: - primary_ip = self._get_primary_ip("ipv6") - if primary_ip is not None and ( - self.hcloud_server.public_net.primary_ipv6 is None - or self.hcloud_server.public_net.primary_ipv6.id != primary_ip.id - ): - self.stop_server_if_forced() - if not self.module.check_mode: - if self.hcloud_server.public_net.primary_ipv6 is not None: - self.hcloud_server.public_net.primary_ipv6.unassign().wait_until_finished() - primary_ip.assign(self.hcloud_server.id, "server").wait_until_finished() - self._mark_as_changed() - if "private_networks" in self.module.params and self.module.params["private_networks"] is not None: - if not bool(self.module.params["private_networks"]): - # This handles None, "" and [] - networks_target = {} - else: - _networks = {} - for network_name_or_id in self.module.params.get("private_networks"): - _found_network = self.client.networks.get_by_name( - network_name_or_id - ) or self.client.networks.get_by_id(network_name_or_id) - _networks.update({_found_network.id: _found_network}) - networks_target = _networks - networks_is = dict() - for p_network in self.hcloud_server.private_net: - networks_is.update({p_network.network.id: p_network.network}) - for network_id in set(list(networks_is) + list(networks_target)): - if network_id in networks_is and network_id not in networks_target: - self.stop_server_if_forced() - if not self.module.check_mode: - self.hcloud_server.detach_from_network(networks_is[network_id]).wait_until_finished() - self._mark_as_changed() - elif network_id in networks_target and network_id not in networks_is: - self.stop_server_if_forced() - if not self.module.check_mode: - self.hcloud_server.attach_to_network(networks_target[network_id]).wait_until_finished() - self._mark_as_changed() - - server_type = self.module.params.get("server_type") - if server_type is not None: - if self.hcloud_server.server_type.name == server_type: - # Check if we should warn for using an deprecated server type - self._check_and_warn_deprecated_server(self.hcloud_server.server_type) - - else: - # Server type should be changed - self.stop_server_if_forced() - - timeout = 100 - if self.module.params.get("upgrade_disk"): - timeout = 1000 # When we upgrade the disk to the resize progress takes some more time. - if not self.module.check_mode: - self.hcloud_server.change_type( - server_type=self._get_server_type(), - upgrade_disk=self.module.params.get("upgrade_disk"), - ).wait_until_finished(timeout) - self._mark_as_changed() + if self.module.params.get("placement_group") is not None: + self._update_server_placement_group() + + if self.module.params.get("ipv4") is not None: + self._update_server_ip("ipv4") + + if self.module.params.get("ipv6") is not None: + self._update_server_ip("ipv6") + + if self.module.params.get("private_networks") is not None: + self._update_server_networks() + + if self.module.params.get("server_type") is not None: + self._update_server_server_type() if not self.module.check_mode and ( (self.module.params.get("state") == "present" and previous_server_status == Server.STATUS_RUNNING) @@ -785,15 +619,197 @@ class AnsibleHCloudServer(AnsibleHCloud): or rebuild_protection != self.hcloud_server.protection["rebuild"] ): if not self.module.check_mode: - self.hcloud_server.change_protection( + action = self.hcloud_server.change_protection( delete=delete_protection, rebuild=rebuild_protection, - ).wait_until_finished() + ) + action.wait_until_finished() self._mark_as_changed() self._get_server() except HCloudException as exception: self.fail_json_hcloud(exception) + def _update_server_placement_group(self) -> None: + current: BoundPlacementGroup | None = self.hcloud_server.placement_group + wanted = self.module.params.get("placement_group") + + # Return if nothing changed + if current is not None and current.has_id_or_name(wanted): + return + + # Fetch resource if parameter is truthy + if wanted: + placement_group = self._client_get_by_name_or_id("placement_groups", wanted) + + # Remove if current is defined + if current is not None: + if not self.module.check_mode: + action = self.hcloud_server.remove_from_placement_group() + action.wait_until_finished() + self._mark_as_changed() + + # Return if parameter is falsy + if not wanted: + return + + # Assign new + self.stop_server_if_forced() + if not self.module.check_mode: + action = self.hcloud_server.add_to_placement_group(placement_group) + action.wait_until_finished() + self._mark_as_changed() + + def _update_server_server_type(self) -> None: + current: ServerType = self.hcloud_server.server_type + wanted = self.module.params.get("server_type") + + # Return if nothing changed + if current.has_id_or_name(wanted): + # Check if we should warn for using an deprecated server type + self._check_and_warn_deprecated_server(self.hcloud_server.server_type) + return + + self.stop_server_if_forced() + + upgrade_disk = self.module.params.get("upgrade_disk") + # Upgrading a server takes 160 seconds on average, upgrading the disk should + # take more time + upgrade_timeout = 600 if upgrade_disk else 180 + + if not self.module.check_mode: + action = self.hcloud_server.change_type( + server_type=self._get_server_type(), + upgrade_disk=upgrade_disk, + ) + action.wait_until_finished(max_retries=upgrade_timeout) + self._mark_as_changed() + + def _update_server_ip(self, kind: Literal["ipv4", "ipv6"]) -> None: + current: PrimaryIP | None = getattr(self.hcloud_server.public_net, f"primary_{kind}") + wanted = self.module.params.get(kind) + enable = self.module.params.get(f"enable_{kind}") + + # Return if nothing changed + if current is not None and current.has_id_or_name(wanted) and enable: + return + + # Fetch resource if parameter is truthy + if wanted: + primary_ip = self._client_get_by_name_or_id("primary_ips", wanted) + + # Remove if current is defined + if current is not None: + self.stop_server_if_forced() + if not self.module.check_mode: + action = self.client.primary_ips.unassign(current) + action.wait_until_finished() + self._mark_as_changed() + + # Return if parameter is falsy or resource is disabled + if not wanted or not enable: + return + + # Assign new + self.stop_server_if_forced() + if not self.module.check_mode: + action = self.client.primary_ips.assign( + primary_ip, + assignee_id=self.hcloud_server.id, + assignee_type="server", + ) + action.wait_until_finished() + self._mark_as_changed() + + def _update_server_networks(self) -> None: + current: list[BoundNetwork] = [item.network for item in self.hcloud_server.private_net] + wanted: list[BoundNetwork] = [ + self._client_get_by_name_or_id("networks", name_or_id) + for name_or_id in self.module.params.get("private_networks") + ] + + current_ids = {item.id for item in current} + wanted_ids = {item.id for item in wanted} + + # Removing existing but not wanted networks + actions: list[BoundAction] = [] + for current_network in current: + if current_network.id in wanted_ids: + continue + + self._mark_as_changed() + if self.module.check_mode: + continue + + actions.append(self.hcloud_server.detach_from_network(current_network)) + + for action in actions: + action.wait_until_finished() + + # Adding wanted networks that doesn't exist yet + actions: list[BoundAction] = [] + for wanted_network in wanted: + if wanted_network.id in current_ids: + continue + + self._mark_as_changed() + if self.module.check_mode: + continue + + actions.append(self.hcloud_server.attach_to_network(wanted_network)) + + for action in actions: + action.wait_until_finished() + + def _update_server_firewalls(self) -> None: + current: list[BoundFirewall] = [item.firewall for item in self.hcloud_server.public_net.firewalls] + wanted: list[BoundFirewall] = [ + self._client_get_by_name_or_id("firewalls", name_or_id) + for name_or_id in self.module.params.get("firewalls") + ] + + current_ids = {item.id for item in current} + wanted_ids = {item.id for item in wanted} + + # Removing existing but not wanted firewalls + actions: list[BoundAction] = [] + for current_firewall in current: + if current_firewall.id in wanted_ids: + continue + + self._mark_as_changed() + if self.module.check_mode: + continue + + actions.extend( + self.client.firewalls.remove_from_resources( + current_firewall, + [FirewallResource(type="server", server=self.hcloud_server)], + ) + ) + + for action in actions: + action.wait_until_finished() + + # Adding wanted firewalls that doesn't exist yet + actions: list[BoundAction] = [] + for wanted_firewall in wanted: + if wanted_firewall.id in current_ids: + continue + + self._mark_as_changed() + if self.module.check_mode: + continue + + actions.extend( + self.client.firewalls.apply_to_resources( + wanted_firewall, + [FirewallResource(type="server", server=self.hcloud_server)], + ) + ) + + for action in actions: + action.wait_until_finished() + def _set_rescue_mode(self, rescue_mode): if self.module.params.get("ssh_keys"): resp = self.hcloud_server.enable_rescue( @@ -813,7 +829,8 @@ class AnsibleHCloudServer(AnsibleHCloud): if self.hcloud_server: if self.hcloud_server.status != Server.STATUS_RUNNING: if not self.module.check_mode: - self.client.servers.power_on(self.hcloud_server).wait_until_finished() + action = self.client.servers.power_on(self.hcloud_server) + action.wait_until_finished() self._mark_as_changed() self._get_server() except HCloudException as exception: @@ -824,7 +841,8 @@ class AnsibleHCloudServer(AnsibleHCloud): if self.hcloud_server: if self.hcloud_server.status != Server.STATUS_OFF: if not self.module.check_mode: - self.client.servers.power_off(self.hcloud_server).wait_until_finished() + action = self.client.servers.power_off(self.hcloud_server) + action.wait_until_finished() self._mark_as_changed() self._get_server() except HCloudException as exception: @@ -833,18 +851,14 @@ class AnsibleHCloudServer(AnsibleHCloud): def stop_server_if_forced(self): previous_server_status = self.hcloud_server.status if previous_server_status == Server.STATUS_RUNNING and not self.module.check_mode: - if ( - self.module.params.get("force_upgrade") - or self.module.params.get("force") - or self.module.params.get("state") == "stopped" - ): + if self.module.params.get("force") or self.module.params.get("state") == "stopped": self.stop_server() # Only stopped server can be upgraded return previous_server_status - else: - self.module.warn( - f"You can not upgrade a running instance {self.hcloud_server.name}. " - "You need to stop the instance or use force=true." - ) + + self.module.warn( + f"You can not upgrade a running instance {self.hcloud_server.name}. " + "You need to stop the instance or use force=true." + ) return None @@ -874,7 +888,8 @@ class AnsibleHCloudServer(AnsibleHCloud): self._get_server() if self.hcloud_server is not None: if not self.module.check_mode: - self.client.servers.delete(self.hcloud_server).wait_until_finished() + action = self.client.servers.delete(self.hcloud_server) + action.wait_until_finished() self._mark_as_changed() self.hcloud_server = None except HCloudException as exception: @@ -887,6 +902,7 @@ class AnsibleHCloudServer(AnsibleHCloud): id={"type": "int"}, name={"type": "str"}, image={"type": "str"}, + image_allow_deprecated={"type": "bool", "default": False, "aliases": ["allow_deprecated_image"]}, server_type={"type": "str"}, location={"type": "str"}, datacenter={"type": "str"}, @@ -902,9 +918,14 @@ class AnsibleHCloudServer(AnsibleHCloud): ipv4={"type": "str"}, ipv6={"type": "str"}, private_networks={"type": "list", "elements": "str", "default": None}, - force={"type": "bool", "default": False}, - force_upgrade={"type": "bool"}, - allow_deprecated_image={"type": "bool", "default": False}, + force={ + "type": "bool", + "default": False, + "aliases": ["force_upgrade"], + "deprecated_aliases": [ + {"collection_name": "hetzner.hcloud", "name": "force_upgrade", "version": "4.0.0"} + ], + }, rescue_mode={"type": "str"}, delete_protection={"type": "bool"}, rebuild_protection={"type": "bool"}, diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py index cee1634cb..3417e58af 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py @@ -146,7 +146,6 @@ hcloud_server_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -162,36 +161,31 @@ class AnsibleHCloudServerInfo(AnsibleHCloud): tmp = [] for server in self.hcloud_server_info: - if server is not None: - image = None if server.image is None else to_native(server.image.name) - placement_group = None if server.placement_group is None else to_native(server.placement_group.name) - ipv4_address = None if server.public_net.ipv4 is None else to_native(server.public_net.ipv4.ip) - ipv6 = None if server.public_net.ipv6 is None else to_native(server.public_net.ipv6.ip) - backup_window = None if server.backup_window is None else to_native(server.backup_window) - tmp.append( - { - "id": to_native(server.id), - "name": to_native(server.name), - "created": to_native(server.created.isoformat()), - "ipv4_address": ipv4_address, - "ipv6": ipv6, - "private_networks": [to_native(net.network.name) for net in server.private_net], - "private_networks_info": [ - {"name": to_native(net.network.name), "ip": net.ip} for net in server.private_net - ], - "image": image, - "server_type": to_native(server.server_type.name), - "datacenter": to_native(server.datacenter.name), - "location": to_native(server.datacenter.location.name), - "placement_group": placement_group, - "rescue_enabled": server.rescue_enabled, - "backup_window": backup_window, - "labels": server.labels, - "status": to_native(server.status), - "delete_protection": server.protection["delete"], - "rebuild_protection": server.protection["rebuild"], - } - ) + if server is None: + continue + + tmp.append( + { + "id": str(server.id), + "name": server.name, + "created": server.created.isoformat(), + "ipv4_address": server.public_net.ipv4.ip if server.public_net.ipv4 is not None else None, + "ipv6": server.public_net.ipv6.ip if server.public_net.ipv6 is not None else None, + "private_networks": [net.network.name for net in server.private_net], + "private_networks_info": [{"name": net.network.name, "ip": net.ip} for net in server.private_net], + "image": server.image.name if server.image is not None else None, + "server_type": server.server_type.name, + "datacenter": server.datacenter.name, + "location": server.datacenter.location.name, + "placement_group": server.placement_group.name if server.placement_group is not None else None, + "rescue_enabled": server.rescue_enabled, + "backup_window": server.backup_window, + "labels": server.labels, + "status": server.status, + "delete_protection": server.protection["delete"], + "rebuild_protection": server.protection["rebuild"], + } + ) return tmp def get_servers(self): diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py index ca80a8a76..bc6dec428 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py @@ -111,7 +111,6 @@ hcloud_server_network: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import APIException, HCloudException @@ -128,10 +127,10 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): def _prepare_result(self): return { - "network": to_native(self.hcloud_network.name), - "server": to_native(self.hcloud_server.name), - "ip": to_native(self.hcloud_server_network.ip), - "alias_ips": self.hcloud_server_network.alias_ips, + "network": self.hcloud_network.name, + "server": self.hcloud_server.name, + "ip": self.hcloud_server_network.ip, + "alias_ips": list(sorted(self.hcloud_server_network.alias_ips)), } def _get_server_and_network(self): @@ -165,7 +164,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_server.attach_to_network(**params).wait_until_finished() + action = self.hcloud_server.attach_to_network(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -183,7 +183,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_server.change_alias_ips(**params).wait_until_finished() + action = self.hcloud_server.change_alias_ips(**params) + action.wait_until_finished() except APIException as exception: self.fail_json_hcloud(exception) @@ -205,7 +206,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): if self.hcloud_server_network is not None and self.hcloud_server is not None: if not self.module.check_mode: try: - self.hcloud_server.detach_from_network(self.hcloud_server_network.network).wait_until_finished() + action = self.hcloud_server.detach_from_network(self.hcloud_server_network.network) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py index 61f1f5011..4f16b52fe 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py @@ -124,7 +124,6 @@ hcloud_server_type_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -140,29 +139,31 @@ class AnsibleHCloudServerTypeInfo(AnsibleHCloud): tmp = [] for server_type in self.hcloud_server_type_info: - if server_type is not None: - tmp.append( - { - "id": to_native(server_type.id), - "name": to_native(server_type.name), - "description": to_native(server_type.description), - "cores": server_type.cores, - "memory": server_type.memory, - "disk": server_type.disk, - "storage_type": to_native(server_type.storage_type), - "cpu_type": to_native(server_type.cpu_type), - "architecture": to_native(server_type.architecture), - "included_traffic": server_type.included_traffic, - "deprecation": ( - { - "announced": server_type.deprecation.announced.isoformat(), - "unavailable_after": server_type.deprecation.unavailable_after.isoformat(), - } - if server_type.deprecation is not None - else None - ), - } - ) + if server_type is None: + continue + + tmp.append( + { + "id": str(server_type.id), + "name": server_type.name, + "description": server_type.description, + "cores": server_type.cores, + "memory": server_type.memory, + "disk": server_type.disk, + "storage_type": server_type.storage_type, + "cpu_type": server_type.cpu_type, + "architecture": server_type.architecture, + "included_traffic": server_type.included_traffic, + "deprecation": ( + { + "announced": server_type.deprecation.announced.isoformat(), + "unavailable_after": server_type.deprecation.unavailable_after.isoformat(), + } + if server_type.deprecation is not None + else None + ), + } + ) return tmp def get_server_types(self): diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py index 349c52c68..e33987c44 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py @@ -113,7 +113,6 @@ hcloud_ssh_key: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -127,10 +126,10 @@ class AnsibleHCloudSSHKey(AnsibleHCloud): def _prepare_result(self): return { - "id": to_native(self.hcloud_ssh_key.id), - "name": to_native(self.hcloud_ssh_key.name), - "fingerprint": to_native(self.hcloud_ssh_key.fingerprint), - "public_key": to_native(self.hcloud_ssh_key.public_key), + "id": str(self.hcloud_ssh_key.id), + "name": self.hcloud_ssh_key.name, + "fingerprint": self.hcloud_ssh_key.fingerprint, + "public_key": self.hcloud_ssh_key.public_key, "labels": self.hcloud_ssh_key.labels, } diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py index 7a4ab5928..b6b22ff35 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py @@ -79,7 +79,6 @@ hcloud_ssh_key_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -92,20 +91,22 @@ class AnsibleHCloudSSHKeyInfo(AnsibleHCloud): hcloud_ssh_key_info: list[BoundSSHKey] | None = None def _prepare_result(self): - ssh_keys = [] + tmp = [] for ssh_key in self.hcloud_ssh_key_info: - if ssh_key: - ssh_keys.append( - { - "id": to_native(ssh_key.id), - "name": to_native(ssh_key.name), - "fingerprint": to_native(ssh_key.fingerprint), - "public_key": to_native(ssh_key.public_key), - "labels": ssh_key.labels, - } - ) - return ssh_keys + if ssh_key is None: + continue + + tmp.append( + { + "id": str(ssh_key.id), + "name": ssh_key.name, + "fingerprint": ssh_key.fingerprint, + "public_key": ssh_key.public_key, + "labels": ssh_key.labels, + } + ) + return tmp def get_ssh_keys(self): try: diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py b/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py index aea40bb13..6f7feeaad 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py @@ -123,7 +123,6 @@ hcloud_subnetwork: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -138,10 +137,10 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud): def _prepare_result(self): return { - "network": to_native(self.hcloud_network.name), - "ip_range": to_native(self.hcloud_subnetwork.ip_range), - "type": to_native(self.hcloud_subnetwork.type), - "network_zone": to_native(self.hcloud_subnetwork.network_zone), + "network": self.hcloud_network.name, + "ip_range": self.hcloud_subnetwork.ip_range, + "type": self.hcloud_subnetwork.type, + "network_zone": self.hcloud_subnetwork.network_zone, "gateway": self.hcloud_subnetwork.gateway, "vswitch_id": self.hcloud_subnetwork.vswitch_id, } @@ -174,7 +173,8 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud): if not self.module.check_mode: try: - self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)).wait_until_finished() + action = self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -194,7 +194,8 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud): if self.hcloud_subnetwork is not None and self.hcloud_network is not None: if not self.module.check_mode: try: - self.hcloud_network.delete_subnet(self.hcloud_subnetwork).wait_until_finished() + action = self.hcloud_network.delete_subnet(self.hcloud_subnetwork) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/volume.py b/ansible_collections/hetzner/hcloud/plugins/modules/volume.py index 8442ed90b..1bcb44253 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/volume.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/volume.py @@ -160,7 +160,6 @@ hcloud_volume: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -173,18 +172,14 @@ class AnsibleHCloudVolume(AnsibleHCloud): hcloud_volume: BoundVolume | None = None def _prepare_result(self): - server_name = None - if self.hcloud_volume.server is not None: - server_name = to_native(self.hcloud_volume.server.name) - return { - "id": to_native(self.hcloud_volume.id), - "name": to_native(self.hcloud_volume.name), + "id": str(self.hcloud_volume.id), + "name": self.hcloud_volume.name, "size": self.hcloud_volume.size, - "location": to_native(self.hcloud_volume.location.name), + "location": self.hcloud_volume.location.name, "labels": self.hcloud_volume.labels, - "server": server_name, - "linux_device": to_native(self.hcloud_volume.linux_device), + "server": self.hcloud_volume.server.name if self.hcloud_volume.server is not None else None, + "linux_device": self.hcloud_volume.linux_device, "delete_protection": self.hcloud_volume.protection["delete"], } @@ -221,7 +216,8 @@ class AnsibleHCloudVolume(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: self._get_volume() - self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_volume.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -233,7 +229,8 @@ class AnsibleHCloudVolume(AnsibleHCloud): if size: if self.hcloud_volume.size < size: if not self.module.check_mode: - self.hcloud_volume.resize(size).wait_until_finished() + action = self.hcloud_volume.resize(size) + action.wait_until_finished() self._mark_as_changed() elif self.hcloud_volume.size > size: self.module.warn("Shrinking of volumes is not supported") @@ -244,12 +241,14 @@ class AnsibleHCloudVolume(AnsibleHCloud): if self.hcloud_volume.server is None or self.hcloud_volume.server.name != server.name: if not self.module.check_mode: automount = self.module.params.get("automount", False) - self.hcloud_volume.attach(server, automount=automount).wait_until_finished() + action = self.hcloud_volume.attach(server, automount=automount) + action.wait_until_finished() self._mark_as_changed() else: if self.hcloud_volume.server is not None: if not self.module.check_mode: - self.hcloud_volume.detach().wait_until_finished() + action = self.hcloud_volume.detach() + action.wait_until_finished() self._mark_as_changed() labels = self.module.params.get("labels") @@ -261,7 +260,8 @@ class AnsibleHCloudVolume(AnsibleHCloud): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_volume.protection["delete"]: if not self.module.check_mode: - self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_volume.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_volume() @@ -281,7 +281,8 @@ class AnsibleHCloudVolume(AnsibleHCloud): if self.hcloud_volume is not None: if not self.module.check_mode: if self.hcloud_volume.server is not None: - self.hcloud_volume.detach().wait_until_finished() + action = self.hcloud_volume.detach() + action.wait_until_finished() self.client.volumes.delete(self.hcloud_volume) self._mark_as_changed() self.hcloud_volume = None diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py index 1e507690e..b30956d74 100644 --- a/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py +++ b/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py @@ -95,7 +95,6 @@ hcloud_volume_info: """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native from ..module_utils.hcloud import AnsibleHCloud from ..module_utils.vendor.hcloud import HCloudException @@ -111,22 +110,21 @@ class AnsibleHCloudVolumeInfo(AnsibleHCloud): tmp = [] for volume in self.hcloud_volume_info: - if volume is not None: - server_name = None - if volume.server is not None: - server_name = to_native(volume.server.name) - tmp.append( - { - "id": to_native(volume.id), - "name": to_native(volume.name), - "size": volume.size, - "location": to_native(volume.location.name), - "labels": volume.labels, - "server": server_name, - "linux_device": to_native(volume.linux_device), - "delete_protection": volume.protection["delete"], - } - ) + if volume is None: + continue + + tmp.append( + { + "id": str(volume.id), + "name": volume.name, + "size": volume.size, + "location": volume.location.name, + "labels": volume.labels, + "server": volume.server.name if volume.server is not None else None, + "linux_device": volume.linux_device, + "delete_protection": volume.protection["delete"], + } + ) return tmp diff --git a/ansible_collections/hetzner/hcloud/pyproject.toml b/ansible_collections/hetzner/hcloud/pyproject.toml index 5263580cb..8047f107f 100644 --- a/ansible_collections/hetzner/hcloud/pyproject.toml +++ b/ansible_collections/hetzner/hcloud/pyproject.toml @@ -25,4 +25,9 @@ good-names = ["i", "j", "k", "ex", "_", "ip", "id"] [tool.pylint.messages_control] disable = [ "wrong-import-position", + "missing-module-docstring", + "missing-class-docstring", + "missing-function-docstring", + "duplicate-code", + "use-dict-literal", ] diff --git a/ansible_collections/hetzner/hcloud/requirements.txt b/ansible_collections/hetzner/hcloud/requirements.txt index 0e9148f96..510a5ef1e 100644 --- a/ansible_collections/hetzner/hcloud/requirements.txt +++ b/ansible_collections/hetzner/hcloud/requirements.txt @@ -1,4 +1,4 @@ -ansible-core>=2.13 +ansible-core>=2.14 # Collections requirements netaddr @@ -9,4 +9,4 @@ requests # Development requirements pylint -antsibull-docs>=2.7,<2.8 +antsibull-docs>=2.10,<2.11 diff --git a/ansible_collections/hetzner/hcloud/scripts/vendor.py b/ansible_collections/hetzner/hcloud/scripts/vendor.py index b55a66577..4fa881d1d 100755 --- a/ansible_collections/hetzner/hcloud/scripts/vendor.py +++ b/ansible_collections/hetzner/hcloud/scripts/vendor.py @@ -22,7 +22,7 @@ from textwrap import dedent logger = logging.getLogger("vendor") HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python" -HCLOUD_VERSION = "v1.33.2" +HCLOUD_VERSION = "v1.35.0" HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/cloud-config-hcloud.ini.in b/ansible_collections/hetzner/hcloud/tests/integration/cloud-config-hcloud.ini.in new file mode 100644 index 000000000..06cd2c4b8 --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/integration/cloud-config-hcloud.ini.in @@ -0,0 +1,2 @@ +[default] +hcloud_api_token=$HCLOUD_TOKEN diff --git a/ansible_collections/hetzner/hcloud/tests/integration/common/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/common/defaults/main/common.yml index e45380565..2b6549ec6 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/common/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/common/defaults/main/common.yml @@ -5,5 +5,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/certificate_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/datacenter_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/cleanup.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/cleanup.yml index 37fbd3413..fd69ed570 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/cleanup.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/cleanup.yml @@ -1,10 +1,11 @@ --- -- name: Cleanup test_server - hetzner.hcloud.server: - name: "{{ hcloud_server_name }}" - state: absent - - name: Cleanup test_firewall hetzner.hcloud.firewall: name: "{{ hcloud_firewall_name }}" state: absent + force: true + +- name: Cleanup test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + state: absent diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/test.yml index 57059848f..8179bc61a 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall/tasks/test.yml @@ -183,7 +183,7 @@ ansible.builtin.assert: that: - result is failed - - '"is still in use" in result.msg' + - result.failure.code == "resource_in_use" - name: Test delete with force hetzner.hcloud.firewall: diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/aliases index 55ec821a4..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud -shippable/hcloud/group2 +gather_facts/no +azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/tasks/cleanup.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/tasks/cleanup.yml index 37fbd3413..fd69ed570 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/tasks/cleanup.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_info/tasks/cleanup.yml @@ -1,10 +1,11 @@ --- -- name: Cleanup test_server - hetzner.hcloud.server: - name: "{{ hcloud_server_name }}" - state: absent - - name: Cleanup test_firewall hetzner.hcloud.firewall: name: "{{ hcloud_firewall_name }}" state: absent + force: true + +- name: Cleanup test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + state: absent diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/aliases index 0e887600e..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/aliases @@ -1,2 +1,3 @@ cloud/hcloud -azp/group2 +gather_facts/no +azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/tasks/cleanup.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/tasks/cleanup.yml index 37fbd3413..fd69ed570 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/tasks/cleanup.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/firewall_resource/tasks/cleanup.yml @@ -1,10 +1,11 @@ --- -- name: Cleanup test_server - hetzner.hcloud.server: - name: "{{ hcloud_server_name }}" - state: absent - - name: Cleanup test_firewall hetzner.hcloud.firewall: name: "{{ hcloud_firewall_name }}" state: absent + force: true + +- name: Cleanup test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + state: absent diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/tasks/test.yml index fba06e308..23f29b229 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip/tasks/test.yml @@ -21,7 +21,7 @@ name: "{{ hcloud_server_name }}" server_type: cx11 image: ubuntu-22.04 - state: started + state: stopped location: "fsn1" register: main_server - name: verify setup server @@ -34,7 +34,7 @@ name: "{{ hcloud_server_name }}2" server_type: cx11 image: ubuntu-22.04 - state: started + state: stopped register: main_server2 - name: verify setup another server assert: @@ -101,6 +101,7 @@ assert: that: - result is failed + - result.failure.code == "invalid_input" - result.msg == "invalid input in fields 'server', 'home_location'" - name: test create Floating IP with check mode @@ -371,7 +372,8 @@ assert: that: - result is failed - - 'result.msg == "Floating IP deletion is protected"' + - result.failure.code == "protected" + - result.msg == "Floating IP deletion is protected" - name: test update Floating IP delete protection hetzner.hcloud.floating_ip: @@ -459,7 +461,8 @@ assert: that: - result is failed - - 'result.msg == "Floating IP deletion is protected"' + - result.failure.code == "protected" + - result.msg == "Floating IP deletion is protected" - name: test update Floating IP delete protection hetzner.hcloud.floating_ip: diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/floating_ip_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/image_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/iso_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/tasks/test.yml index 343f15672..3b7de5b11 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer/tasks/test.yml @@ -120,7 +120,8 @@ ansible.builtin.assert: that: - result is failed - - 'result.msg == "load balancer deletion is protected"' + - result.failure.code == "protected" + - result.msg == "load balancer deletion is protected" - name: Test update delete_protection hetzner.hcloud.load_balancer: diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/tasks/prepare.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/tasks/prepare.yml index bfad755df..653417e18 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/tasks/prepare.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_info/tasks/prepare.yml @@ -4,7 +4,7 @@ name: "{{ hcloud_server_name }}" server_type: cx11 image: ubuntu-22.04 - state: started + state: stopped register: test_server - name: Create test_load_balancer diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_network/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_service/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/tasks/test.yml index 19fd0e9af..a392f4f3d 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_target/tasks/test.yml @@ -6,7 +6,7 @@ name: "{{hcloud_server_name}}" server_type: cx11 image: ubuntu-22.04 - state: started + state: stopped location: "fsn1" register: server - name: verify setup server diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/load_balancer_type_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/location_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/aliases index f150235ee..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/aliases @@ -1,3 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 -disabled diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/main.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/main.yml index a8320602c..a01c6d60c 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/main.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/defaults/main/main.yml @@ -2,4 +2,3 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) --- hcloud_network_name: "{{ hcloud_ns }}" -hcloud_network_name_with_vswitch: "{{ hcloud_ns }}-vswitch" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/cleanup.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/cleanup.yml new file mode 100644 index 000000000..989d01b80 --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/cleanup.yml @@ -0,0 +1,5 @@ +--- +- name: Cleanup test_network + hetzner.hcloud.network: + name: "{{ hcloud_network_name }}" + state: absent diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/test.yml index b4f3de284..b814ceb15 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network/tasks/test.yml @@ -1,268 +1,186 @@ # Copyright: (c) 2019, Hetzner Cloud GmbH <info@hetzner-cloud.de> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) --- -- name: setup ensure network is absent +- name: Test missing required parameters hetzner.hcloud.network: - name: "{{ item }}" - state: absent - with_items: - - "{{ hcloud_network_name }}" - - "{{ hcloud_network_name_with_vswitch }}" - -- name: test missing ip_range parameter on create Network - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - register: result + name: "{{ hcloud_network_name }}" + state: present ignore_errors: true -- name: verify fail missing ip_range parameter on create Network result - assert: + register: result +- name: Verify missing required parameters + ansible.builtin.assert: that: - result is failed - 'result.msg == "missing required arguments: ip_range"' -- name: test create Network with check mode +- name: Test create with check mode hetzner.hcloud.network: - name: "{{hcloud_network_name}}" + name: "{{ hcloud_network_name }}" ip_range: "10.0.0.0/16" - register: result + labels: + key: value check_mode: true -- name: verify create Network with check mode result - assert: + register: result +- name: Verify create with check mode + ansible.builtin.assert: that: - result is changed -- name: test create Network - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/16" - register: network -- name: verify test create Network result - assert: - that: - - network is changed - - network.hcloud_network.name == hcloud_network_name - - network.hcloud_network.ip_range == "10.0.0.0/16" - -- name: test create Network idempotence - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/16" - register: network -- name: verify test create network - assert: - that: - - network is not changed - -- name: test create Network with expose_routes_to_vswitch +- name: Test create hetzner.hcloud.network: - name: "{{hcloud_network_name_with_vswitch}}" + name: "{{ hcloud_network_name }}" ip_range: "10.0.0.0/16" - expose_routes_to_vswitch: true - register: network -- name: verify test create Network with vSwitch result - assert: - that: - - network is changed - - network.hcloud_network.name == hcloud_network_name_with_vswitch - - network.hcloud_network.ip_range == "10.0.0.0/16" - - network.hcloud_network.expose_routes_to_vswitch is true - -- name: test create Network with expose_routes_to_vswitch idempotence - hetzner.hcloud.network: - name: "{{hcloud_network_name_with_vswitch}}" - ip_range: "10.0.0.0/16" - expose_routes_to_vswitch: true - register: network -- name: verify test create network idempotency - assert: - that: - - network is not changed - -- name: test update Network label - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" labels: key: value - register: network -- name: verify test update Network label - assert: + register: result +- name: Verify create + ansible.builtin.assert: that: - - network is changed - - network.hcloud_network.labels.key == "value" + - result is changed + - result.hcloud_network.name == hcloud_network_name + - result.hcloud_network.ip_range == "10.0.0.0/16" + - result.hcloud_network.labels.key == "value" + - result.hcloud_network.expose_routes_to_vswitch == false + - result.hcloud_network.delete_protection == false -- name: test update Network label idempotency +- name: Test create idempotency hetzner.hcloud.network: - name: "{{hcloud_network_name}}" + name: "{{ hcloud_network_name }}" + ip_range: "10.0.0.0/16" labels: key: value - register: network -- name: verify test update Network label idempotency - assert: - that: - - network is not changed - -- name: test update Network ip range - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/8" - register: network -- name: verify test update Network ip range - assert: - that: - - network is changed - - network.hcloud_network.ip_range == "10.0.0.0/8" - -- name: test update Network ip range idempotency - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/8" - register: network -- name: verify test update Network ip range idempotency - assert: - that: - - network is not changed - -- name: test update Network expose_routes_to_vswitch - hetzner.hcloud.network: - name: "{{hcloud_network_name_with_vswitch}}" - expose_routes_to_vswitch: false - register: network -- name: verify test update Network expose_routes_to_vswitch - assert: - that: - - network is changed - - network.hcloud_network.expose_routes_to_vswitch is false - -- name: test update Network expose_routes_to_vswitch idempotency - hetzner.hcloud.network: - name: "{{hcloud_network_name_with_vswitch}}" - expose_routes_to_vswitch: false - register: network -- name: verify test update Network expose_routes_to_vswitch idempotency - assert: + register: result +- name: Verify create idempotency + ansible.builtin.assert: that: - - network is not changed + - result is not changed -- name: test update Network delete protection +- name: Test update hetzner.hcloud.network: - name: "{{hcloud_network_name}}" + name: "{{ hcloud_network_name }}" ip_range: "10.0.0.0/8" + labels: + key: changed + foo: bar + expose_routes_to_vswitch: true delete_protection: true - register: network -- name: verify test update Network delete protection - assert: + register: result +- name: Verify update + ansible.builtin.assert: that: - - network is changed - - network.hcloud_network.delete_protection is sameas true + - result is changed + - result.hcloud_network.ip_range == "10.0.0.0/8" + - result.hcloud_network.labels.key == "changed" + - result.hcloud_network.labels.foo == "bar" + - result.hcloud_network.expose_routes_to_vswitch == true + - result.hcloud_network.delete_protection == true -- name: test update Network delete protection idempotency +- name: Test update idempotency hetzner.hcloud.network: - name: "{{hcloud_network_name}}" + name: "{{ hcloud_network_name }}" ip_range: "10.0.0.0/8" + labels: + key: changed + foo: bar delete_protection: true - register: network -- name: verify test update Network delete protection idempotency - assert: - that: - - network is not changed - - network.hcloud_network.delete_protection is sameas true - -- name: test Network without delete protection set to be idempotent - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/8" - register: network -- name: verify test Network without delete protection set to be idempotent - assert: + register: result +- name: Verify update idempotency + ansible.builtin.assert: that: - - network is not changed - - network.hcloud_network.delete_protection is sameas true + - result is not changed -- name: test delete Network fails if it is protected +- name: Test delete with delete protection hetzner.hcloud.network: - name: "{{hcloud_network_name}}" + name: "{{ hcloud_network_name }}" state: absent ignore_errors: true register: result -- name: verify delete Network - assert: +- name: Verify delete with delete protection + ansible.builtin.assert: that: - result is failed - - 'result.msg == "network deletion is protected"' + - result.failure.code == "protected" + - result.msg == "network deletion is protected" -- name: test update Network delete protection +- name: Test update delete protection hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/8" + name: "{{ hcloud_network_name }}" delete_protection: false - register: network -- name: verify test update Network delete protection - assert: + register: result +- name: Verify update delete protection + ansible.builtin.assert: that: - - network is changed - - network.hcloud_network.delete_protection is sameas false + - result is changed + - result.hcloud_network.delete_protection == false -- name: test delete Network +- name: Test update name hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - state: absent + id: "{{ result.hcloud_network.id }}" + name: "changed-{{ hcloud_network_name }}" register: result -- name: verify delete Network - assert: +- name: Verify update name + ansible.builtin.assert: that: - - result is success + - result is changed + - result.hcloud_network.name == "changed-" + hcloud_network_name -- name: test create Network with delete protection +- name: Test update name and labels hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - ip_range: "10.0.0.0/8" - delete_protection: true - register: network -- name: verify create Network with delete protection - assert: + id: "{{ result.hcloud_network.id }}" + name: "{{ hcloud_network_name }}" + labels: + key: value + register: result +- name: Verify update name and labels + ansible.builtin.assert: that: - - network is changed - - network.hcloud_network.delete_protection is sameas true + - result is changed + - result.hcloud_network.name == hcloud_network_name + - result.hcloud_network.labels.key == "value" + - result.hcloud_network.labels.foo is not defined -- name: test delete Network fails if it is protected +- name: Test delete hetzner.hcloud.network: - name: "{{hcloud_network_name}}" + name: "{{ hcloud_network_name }}" state: absent - ignore_errors: true register: result -- name: verify delete Network - assert: +- name: Verify delete + ansible.builtin.assert: that: - - result is failed - - 'result.msg == "network deletion is protected"' + - result is changed -- name: test update Network delete protection +- name: Test create with vSwitch hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - delete_protection: false - register: network -- name: verify test update Network delete protection - assert: + name: "{{ hcloud_network_name }}" + ip_range: "10.0.0.0/16" + expose_routes_to_vswitch: true + register: result +- name: Verify create with vSwitch + ansible.builtin.assert: that: - - network is changed - - network.hcloud_network.delete_protection is sameas false + - result is changed + - result.hcloud_network.name == hcloud_network_name + - result.hcloud_network.ip_range == "10.0.0.0/16" + - result.hcloud_network.expose_routes_to_vswitch == true + - result.hcloud_network.delete_protection == false -- name: test delete Network +- name: Test create with vSwitch idempotency hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - state: absent + name: "{{ hcloud_network_name }}" + ip_range: "10.0.0.0/16" + expose_routes_to_vswitch: true register: result -- name: verify delete Network - assert: +- name: Verify create + ansible.builtin.assert: that: - - result is success + - result is not changed -- name: test delete Network with expose_routes_to_vswitch +- name: Test delete with vSwitch hetzner.hcloud.network: - name: "{{hcloud_network_name_with_vswitch}}" + name: "{{ hcloud_network_name }}" state: absent register: result -- name: verify delete Network with expose_routes_to_vswitch - assert: +- name: Verify delete with vSwitch + ansible.builtin.assert: that: - - result is success + - result is changed diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/network_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/tasks/test.yml index 3694c846f..d988275d6 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/placement_group/tasks/test.yml @@ -80,7 +80,7 @@ - name: test remove server from placement group hetzner.hcloud.server: name: "{{ hcloud_server_name }}" - placement_group: null + placement_group: "" state: present register: result - name: verify remove server from placement group diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/cleanup.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/cleanup.yml new file mode 100644 index 000000000..d8c44b945 --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/cleanup.yml @@ -0,0 +1,10 @@ +--- +- name: Cleanup test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + state: absent + +- name: Cleanup test_primary_ip + hetzner.hcloud.primary_ip: + name: "{{ hcloud_primary_ip_name }}" + state: absent diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/prepare.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/prepare.yml new file mode 100644 index 000000000..8200e97a1 --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/prepare.yml @@ -0,0 +1,10 @@ +--- +- name: Create test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + server_type: cx11 + image: ubuntu-22.04 + state: stopped + enable_ipv4: false + enable_ipv6: false + register: test_server diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/test.yml index 4c0fd2e5f..84fd6a31f 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip/tasks/test.yml @@ -1,248 +1,181 @@ # Copyright: (c) 2019, Hetzner Cloud GmbH <info@hetzner-cloud.de> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) --- -- name: setup ensure primary ip is absent +- name: Test missing required parameters hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - state: absent - -- name: test create Primary IP with check mode - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" - register: primaryIP - check_mode: true -- name: verify test create Primary IP with check mode - assert: - that: - - primaryIP is changed - -- name: test create Primary IP - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" - register: primaryIP -- name: verify test create Primary IP - assert: - that: - - primaryIP is changed - - primaryIP.hcloud_primary_ip.name ==hcloud_primary_ip_name - - primaryIP.hcloud_primary_ip.datacenter == "fsn1-dc14" - -- name: test create Primary IP idempotency - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" - register: primaryIP -- name: verify test create Primary IP idempotency - assert: + state: present + ignore_errors: true + register: result +- name: Verify missing required parameters + ansible.builtin.assert: that: - - primaryIP is not changed + - result is failed + - 'result.msg == "one of the following is required: id, name"' -- name: test update Primary IP +- name: Test create with check mode hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" + type: ipv6 + datacenter: fsn1-dc14 labels: key: value - register: primaryIP -- name: verify test update Primary IP - assert: + check_mode: true + register: result +- name: Verify create with check mode + ansible.builtin.assert: that: - - primaryIP is changed + - result is changed -- name: test update Primary IP idempotency +- name: Test create hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" + type: ipv6 + datacenter: fsn1-dc14 labels: key: value - register: primaryIP -- name: verify test update Primary IP idempotency - assert: + register: result +- name: Verify create + ansible.builtin.assert: that: - - primaryIP is not changed + - result is changed + - result.hcloud_primary_ip.name == hcloud_primary_ip_name + - result.hcloud_primary_ip.type == "ipv6" + - result.hcloud_primary_ip.datacenter == "fsn1-dc14" + - result.hcloud_primary_ip.assignee_type == "server" + - result.hcloud_primary_ip.assignee_id is none + - result.hcloud_primary_ip.labels.key == "value" + - result.hcloud_primary_ip.auto_delete is false + - result.hcloud_primary_ip.delete_protection is false -- name: test update Primary IP with same labels +- name: Test create idempotency hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" + type: ipv6 + datacenter: fsn1-dc14 labels: key: value - register: primaryIP -- name: verify test update Primary IP with same labels - assert: + register: result +- name: Verify create idempotency + ansible.builtin.assert: that: - - primaryIP is not changed + - result is not changed -- name: test update Primary IP with other labels +- name: Test update hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" + type: ipv6 + datacenter: fsn1-dc14 labels: key: value - other: label - register: primaryIP -- name: verify test update Primary IP with other labels - assert: + foo: bar + auto_delete: true + register: result +- name: Verify update + ansible.builtin.assert: that: - - primaryIP is changed + - result is changed + - result.hcloud_primary_ip.name == hcloud_primary_ip_name + - result.hcloud_primary_ip.type == "ipv6" + - result.hcloud_primary_ip.datacenter == "fsn1-dc14" + - result.hcloud_primary_ip.assignee_type == "server" + - result.hcloud_primary_ip.assignee_id is none + - result.hcloud_primary_ip.labels.key == "value" + - result.hcloud_primary_ip.labels.foo == "bar" + - result.hcloud_primary_ip.delete_protection is false + - result.hcloud_primary_ip.auto_delete is true -- name: test update Primary IP with other labels in different order +- name: Test update idempotency hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: "fsn1-dc14" + type: ipv6 + datacenter: fsn1-dc14 labels: - other: label key: value - register: primaryIP -- name: verify test update Primary IP with other labels in different order - assert: - that: - - primaryIP is not changed - -- name: test update Primary IP delete protection - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - delete_protection: true - register: primaryIP -- name: verify update Primary IP delete protection - assert: + foo: bar + auto_delete: true + register: result +- name: Verify update idempotency + ansible.builtin.assert: that: - - primaryIP is changed - - primaryIP.hcloud_primary_ip.delete_protection is sameas true + - result is not changed -- name: test update Primary IP delete protection idempotency +- name: Test update delete protection hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 delete_protection: true - register: primaryIP -- name: verify update Primary IP delete protection idempotency - assert: - that: - - primaryIP is not changed - - primaryIP.hcloud_primary_ip.delete_protection is sameas true - -- name: test Primary IP without delete protection set to be idempotent - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - register: primaryIP -- name: verify Primary IP without delete protection set to be idempotent - assert: + register: result +- name: Verify update delete protection + ansible.builtin.assert: that: - - primaryIP is not changed - - primaryIP.hcloud_primary_ip.delete_protection is sameas true + - result is changed + - result.hcloud_primary_ip.delete_protection is true -- name: test delete Primary IP fails if it is protected +- name: Test delete with delete protection hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - state: "absent" - register: result + state: absent ignore_errors: true -- name: verify test delete primary ip - assert: + register: result +- name: Verify delete with delete protection + ansible.builtin.assert: that: - result is failed - - 'result.msg == "Primary IP deletion is protected"' + - result.failure.code == "protected" + - result.msg == "Primary IP deletion is protected" -- name: test update Primary IP delete protection +- name: Test update delete protection hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 delete_protection: false - register: primaryIP -- name: verify update Primary IP delete protection - assert: - that: - - primaryIP is changed - - primaryIP.hcloud_primary_ip.delete_protection is sameas false - -- name: test delete primary ip - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - state: "absent" register: result -- name: verify test delete primary ip - assert: +- name: Verify update delete protection + ansible.builtin.assert: that: - result is changed + - result.hcloud_primary_ip.delete_protection is false -- name: test create ipv6 primary ip +- name: Test delete hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv6 - datacenter: "fsn1-dc14" - state: "present" + state: absent register: result -- name: verify test create ipv6 primary ip - assert: +- name: Verify delete + ansible.builtin.assert: that: - result is changed -- name: test delete ipv6 primary ip +- name: Test create with server hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - state: "absent" + type: ipv6 + server: "{{ hcloud_server_name }}" register: result -- name: verify test delete ipv6 primary ip - assert: +- name: Verify create with server + ansible.builtin.assert: that: - result is changed + - result.hcloud_primary_ip.name == hcloud_primary_ip_name + - result.hcloud_primary_ip.type == "ipv6" + - result.hcloud_primary_ip.assignee_id == test_server.hcloud_server.id | string + - result.hcloud_primary_ip.assignee_type == "server" -- name: test create Primary IP with delete protection - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - datacenter: fsn1-dc14 - delete_protection: true - register: primaryIP -- name: verify create Primary IP with delete protection - assert: - that: - - primaryIP is changed - - primaryIP.hcloud_primary_ip.delete_protection is sameas true - -- name: test delete Primary IP fails if it is protected +- name: Test create with server idempotency hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - state: "absent" + type: ipv6 + server: "{{ hcloud_server_name }}" register: result - ignore_errors: true -- name: verify test delete primary ip - assert: +- name: Verify create with server idempotency + ansible.builtin.assert: that: - - result is failed - - 'result.msg == "Primary IP deletion is protected"' + - result is not changed -- name: test update Primary IP delete protection +- name: Test delete with server hetzner.hcloud.primary_ip: name: "{{ hcloud_primary_ip_name }}" - type: ipv4 - delete_protection: false - register: primaryIP -- name: verify update Primary IP delete protection - assert: - that: - - primaryIP is changed - - primaryIP.hcloud_primary_ip.delete_protection is sameas false - -- name: test delete primary ip - hetzner.hcloud.primary_ip: - name: "{{ hcloud_primary_ip_name }}" - state: "absent" + state: absent register: result -- name: verify test delete primary ip - assert: +- name: Verify delete with server + ansible.builtin.assert: that: - result is changed diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/primary_ip_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/rdns/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/route/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/route/aliases index 62828d1e9..d9a549fdd 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/route/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/route/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group1 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/route/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/route/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/route/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/route/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_basic.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_basic.yml index 1e94d67af..879e2d678 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_basic.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_basic.yml @@ -315,7 +315,8 @@ assert: that: - result is failed - - 'result.msg == "server deletion is protected"' + - result.failure.code == "protected" + - result.msg == "server deletion is protected" - name: test rebuild server fails if it is protected hetzner.hcloud.server: @@ -328,7 +329,8 @@ assert: that: - result is failed - - 'result.msg == "server rebuild is protected"' + - result.failure.code == "protected" + - result.msg == "server rebuild is protected" - name: test remove server protection hetzner.hcloud.server: @@ -585,7 +587,8 @@ assert: that: - result is failed - - 'result.msg == "server deletion is protected"' + - result.failure.code == "protected" + - result.msg == "server deletion is protected" - name: remove protection from server hetzner.hcloud.server: diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_firewalls.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_firewalls.yml index 896a6c5cf..230df46de 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_firewalls.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_firewalls.yml @@ -13,7 +13,9 @@ assert: that: - result is failed - - 'result.msg == "firewall not-existing was not found"' + - result.failure.code == "not_found" + - result.msg == "firewall not-existing was not found" + - name: setup create firewalls hetzner.hcloud.firewall: name: "{{ item }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_validation.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_validation.yml index d4e0ef8b4..e051816f9 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_validation.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server/tasks/test_validation.yml @@ -34,7 +34,8 @@ assert: that: - result is failed - - 'result.msg == "server_type not-existing-server-type was not found"' + - result.failure.code == "not_found" + - result.msg == "server_type not-existing-server-type was not found" - name: test create server with not existing image hetzner.hcloud.server: @@ -48,4 +49,5 @@ assert: that: - result is failed - - 'result.msg == "Image my-not-existing-image-20.04 was not found"' + - result.failure.code == "not_found" + - result.msg == "Image my-not-existing-image-20.04 was not found" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/tasks/prepare.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/tasks/prepare.yml index 9e8aa2c9f..8a7a09605 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/tasks/prepare.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_info/tasks/prepare.yml @@ -4,7 +4,7 @@ name: "{{ hcloud_server_name }}" server_type: cx11 image: ubuntu-22.04 - state: started + state: stopped labels: key: value register: test_server diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/aliases index 6e9b68657..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/aliases @@ -1,3 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 -disabled diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/cleanup.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/cleanup.yml new file mode 100644 index 000000000..af15c63bb --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/cleanup.yml @@ -0,0 +1,10 @@ +--- +- name: Cleanup test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + state: absent + +- name: Cleanup test_network + hetzner.hcloud.network: + name: "{{ hcloud_network_name }}" + state: absent diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/prepare.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/prepare.yml new file mode 100644 index 000000000..b74f43f06 --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/prepare.yml @@ -0,0 +1,24 @@ +--- +- name: Create test_network + hetzner.hcloud.network: + name: "{{ hcloud_network_name }}" + ip_range: 10.0.0.0/16 + labels: + key: value + register: test_network + +- name: Create test_subnetwork + hetzner.hcloud.subnetwork: + network: "{{ hcloud_network_name }}" + type: server + network_zone: eu-central + ip_range: 10.0.1.0/24 + register: test_subnetwork + +- name: Create test_server + hetzner.hcloud.server: + name: "{{ hcloud_server_name }}" + server_type: cx11 + image: ubuntu-22.04 + state: stopped + register: test_server diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/test.yml index a77f2e30a..a232ae5d5 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_network/tasks/test.yml @@ -1,222 +1,152 @@ # Copyright: (c) 2019, Hetzner Cloud GmbH <info@hetzner-cloud.de> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) --- -- name: setup network - hetzner.hcloud.network: - name: "{{ hcloud_network_name }}" - ip_range: "10.0.0.0/8" - state: present - register: network -- name: verify setup network - assert: - that: - - network is success - -- name: setup subnetwork - hetzner.hcloud.subnetwork: - network: "{{ hcloud_network_name }}" - ip_range: "10.0.0.0/16" - type: "server" - network_zone: "eu-central" - state: present - register: subnetwork -- name: verify subnetwork - assert: - that: - - subnetwork is success - -- name: setup server - hetzner.hcloud.server: - name: "{{hcloud_server_name}}" - server_type: cx11 - image: ubuntu-22.04 - state: started - location: "fsn1" - register: server -- name: verify setup server - assert: - that: - - server is success - -- name: test missing required parameters on create server network +- name: Test missing required parameters hetzner.hcloud.server_network: state: present - register: result ignore_errors: true -- name: verify fail test missing required parameters on create server network - assert: + register: result +- name: Verify missing required parameters + ansible.builtin.assert: that: - result is failed - 'result.msg == "missing required arguments: network, server"' -- name: test create server network with checkmode +- name: Test create with checkmode hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" + server: "{{ hcloud_server_name }}" state: present - register: result check_mode: true -- name: verify test create server network with checkmode - assert: + register: result +- name: Verify create with checkmode + ansible.builtin.assert: that: - result is changed -- name: test create server network +- name: Test create hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" + server: "{{ hcloud_server_name }}" state: present - register: serverNetwork -- name: verify create server network - assert: + register: result +- name: Verify create + ansible.builtin.assert: that: - - serverNetwork is changed - - serverNetwork.hcloud_server_network.network == hcloud_network_name - - serverNetwork.hcloud_server_network.server == hcloud_server_name + - result is changed + - result.hcloud_server_network.network == hcloud_network_name + - result.hcloud_server_network.server == hcloud_server_name -- name: test create server network idempotency +- name: Test create idempotency hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" + server: "{{ hcloud_server_name }}" state: present - register: serverNetwork -- name: verify create server network idempotency - assert: + register: result +- name: Verify create idempotency + ansible.builtin.assert: that: - - serverNetwork is not changed + - result is not changed -- name: test absent server network +- name: Test delete hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" + server: "{{ hcloud_server_name }}" state: absent register: result -- name: verify test absent server network - assert: +- name: Verify delete + ansible.builtin.assert: that: - result is changed -- name: test create server network with specified ip +- name: Test create with ip hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" - ip: "10.0.0.2" + server: "{{ hcloud_server_name }}" + ip: "10.0.1.2" state: present - register: serverNetwork -- name: verify create server network with specified ip - assert: + register: result +- name: Verify create with ip + ansible.builtin.assert: that: - - serverNetwork is changed - - serverNetwork.hcloud_server_network.network == hcloud_network_name - - serverNetwork.hcloud_server_network.server == hcloud_server_name - - serverNetwork.hcloud_server_network.ip == "10.0.0.2" + - result is changed + - result.hcloud_server_network.network == hcloud_network_name + - result.hcloud_server_network.server == hcloud_server_name + - result.hcloud_server_network.ip == "10.0.1.2" -- name: cleanup create server network with specified ip +- name: Test delete with ip hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" + server: "{{ hcloud_server_name }}" state: absent register: result -- name: verify cleanup create server network with specified ip - assert: +- name: Verify delete with ip + ansible.builtin.assert: that: - result is changed -- name: test create server network with alias ips +- name: Test create with alias ips hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" - ip: "10.0.0.2" + server: "{{ hcloud_server_name }}" + ip: "10.0.1.2" alias_ips: - - "10.0.1.2" - - "10.0.2.3" + - "10.0.1.10" + - "10.0.1.11" state: present - register: serverNetwork -- name: verify create server network with alias ips - assert: + register: result +- name: Verify create with alias ips + ansible.builtin.assert: that: - - serverNetwork is changed - - serverNetwork.hcloud_server_network.network == hcloud_network_name - - serverNetwork.hcloud_server_network.server == hcloud_server_name - - serverNetwork.hcloud_server_network.ip == "10.0.0.2" - - 'serverNetwork.hcloud_server_network.alias_ips[0] == "10.0.2.3"' - - 'serverNetwork.hcloud_server_network.alias_ips[1] == "10.0.1.2"' + - result is changed + - result.hcloud_server_network.network == hcloud_network_name + - result.hcloud_server_network.server == hcloud_server_name + - result.hcloud_server_network.ip == "10.0.1.2" + - result.hcloud_server_network.alias_ips[0] == "10.0.1.10" + - result.hcloud_server_network.alias_ips[1] == "10.0.1.11" -- name: test update server network with alias ips +- name: Test update with alias ips hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" - ip: "10.0.0.2" + server: "{{ hcloud_server_name }}" + ip: "10.0.1.2" alias_ips: - - "10.0.2.3" - - "10.0.3.1" + - "10.0.1.10" + - "10.0.1.20" state: present - register: serverNetwork -- name: verify create server network with alias ips - assert: + register: result +- name: Verify update with alias ips + ansible.builtin.assert: that: - - serverNetwork is changed - - serverNetwork.hcloud_server_network.network == hcloud_network_name - - serverNetwork.hcloud_server_network.server == hcloud_server_name - - serverNetwork.hcloud_server_network.ip == "10.0.0.2" - - 'serverNetwork.hcloud_server_network.alias_ips[0] == "10.0.2.3"' - - 'serverNetwork.hcloud_server_network.alias_ips[1] == "10.0.3.1"' + - result is changed + - result.hcloud_server_network.network == hcloud_network_name + - result.hcloud_server_network.server == hcloud_server_name + - result.hcloud_server_network.ip == "10.0.1.2" + - result.hcloud_server_network.alias_ips[0] == "10.0.1.10" + - result.hcloud_server_network.alias_ips[1] == "10.0.1.20" -- name: test update server network with alias ips idempotency +- name: Test update with alias ips idempotency hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" - ip: "10.0.0.2" + server: "{{ hcloud_server_name }}" + ip: "10.0.1.2" alias_ips: - - "10.0.2.3" - - "10.0.3.1" + - "10.0.1.10" + - "10.0.1.20" state: present - register: serverNetwork -- name: verify create server network with alias ips idempotency - assert: - that: - - serverNetwork is not changed - -- name: cleanup create server network with alias ips - hetzner.hcloud.server_network: - network: "{{ hcloud_network_name }}" - server: "{{hcloud_server_name}}" - state: absent - register: result -- name: verify cleanup create server network with alias ips - assert: - that: - - result is changed - -- name: cleanup server - hetzner.hcloud.server: - name: "{{ hcloud_server_name }}" - state: absent register: result -- name: verify cleanup server - assert: +- name: Verify update with alias ips idempotency + ansible.builtin.assert: that: - - result is success + - result is not changed -- name: cleanup subnetwork - hetzner.hcloud.subnetwork: +- name: Test delete with alias ips + hetzner.hcloud.server_network: network: "{{ hcloud_network_name }}" - ip_range: "10.0.0.0/16" - type: "server" - network_zone: "eu-central" + server: "{{ hcloud_server_name }}" state: absent register: result -- name: verify cleanup subnetwork - assert: +- name: Verify delete with alias ips + ansible.builtin.assert: that: - result is changed - -- name: cleanup - hetzner.hcloud.network: - name: "{{hcloud_network_name}}" - state: absent - register: result -- name: verify cleanup - assert: - that: - - result is success diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/server_type_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/tasks/test.yml index 41b9c351d..e314266a4 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key/tasks/test.yml @@ -133,7 +133,8 @@ assert: that: - result is failed - - 'result.msg == "SSH key with the same fingerprint already exists"' + - result.failure.code == "uniqueness_error" + - result.msg == "SSH key with the same fingerprint already exists" - name: test delete ssh key hetzner.hcloud.ssh_key: diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/ssh_key_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/aliases index a6a90a6bf..c96df02ff 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group3 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/subnetwork/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/tasks/test.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/tasks/test.yml index fd47d5343..9b586e051 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/tasks/test.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume/tasks/test.yml @@ -6,7 +6,7 @@ name: "{{hcloud_server_name}}" server_type: cx11 image: ubuntu-22.04 - state: started + state: stopped location: "fsn1" register: vol_server - name: verify setup server @@ -208,7 +208,8 @@ assert: that: - result is failed - - 'result.msg == "volume deletion is protected"' + - result.failure.code == "protected" + - result.msg == "volume deletion is protected" - name: test update Volume delete protection hetzner.hcloud.volume: @@ -254,7 +255,8 @@ assert: that: - result is failed - - 'result.msg == "volume deletion is protected"' + - result.failure.code == "protected" + - result.msg == "volume deletion is protected" - name: test update Volume delete protection hetzner.hcloud.volume: diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/aliases b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/aliases index 0e887600e..18b11115e 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/aliases +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/aliases @@ -1,2 +1,3 @@ cloud/hcloud +gather_facts/no azp/group2 diff --git a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/defaults/main/common.yml b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/defaults/main/common.yml index e316b233c..159bb2088 100644 --- a/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/defaults/main/common.yml +++ b/ansible_collections/hetzner/hcloud/tests/integration/targets/volume_info/defaults/main/common.yml @@ -8,5 +8,5 @@ hcloud_prefix: "tests" # Used to namespace resources created by concurrent test pipelines/targets hcloud_run_ns: "{{ hcloud_prefix | md5 }}" -hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" +hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" diff --git a/ansible_collections/hetzner/hcloud/tests/sanity/ignore-2.13.txt b/ansible_collections/hetzner/hcloud/tests/sanity/ignore-2.13.txt deleted file mode 100644 index 185a458e3..000000000 --- a/ansible_collections/hetzner/hcloud/tests/sanity/ignore-2.13.txt +++ /dev/null @@ -1,69 +0,0 @@ -plugins/inventory/hcloud.py validate-modules:illegal-future-imports -plugins/inventory/hcloud.py validate-modules:import-before-documentation -plugins/inventory/hcloud.py yamllint:unparsable-with-libyaml # bug in ansible-test - https://github.com/ansible/ansible/issues/82353 -plugins/modules/certificate_info.py validate-modules:illegal-future-imports -plugins/modules/certificate_info.py validate-modules:import-before-documentation -plugins/modules/certificate.py validate-modules:illegal-future-imports -plugins/modules/certificate.py validate-modules:import-before-documentation -plugins/modules/datacenter_info.py validate-modules:illegal-future-imports -plugins/modules/datacenter_info.py validate-modules:import-before-documentation -plugins/modules/firewall_info.py validate-modules:illegal-future-imports -plugins/modules/firewall_info.py validate-modules:import-before-documentation -plugins/modules/firewall_resource.py validate-modules:illegal-future-imports -plugins/modules/firewall_resource.py validate-modules:import-before-documentation -plugins/modules/firewall.py validate-modules:illegal-future-imports -plugins/modules/firewall.py validate-modules:import-before-documentation -plugins/modules/floating_ip_info.py validate-modules:illegal-future-imports -plugins/modules/floating_ip_info.py validate-modules:import-before-documentation -plugins/modules/floating_ip.py validate-modules:illegal-future-imports -plugins/modules/floating_ip.py validate-modules:import-before-documentation -plugins/modules/image_info.py validate-modules:illegal-future-imports -plugins/modules/image_info.py validate-modules:import-before-documentation -plugins/modules/iso_info.py validate-modules:illegal-future-imports -plugins/modules/iso_info.py validate-modules:import-before-documentation -plugins/modules/load_balancer_info.py validate-modules:illegal-future-imports -plugins/modules/load_balancer_info.py validate-modules:import-before-documentation -plugins/modules/load_balancer_network.py validate-modules:illegal-future-imports -plugins/modules/load_balancer_network.py validate-modules:import-before-documentation -plugins/modules/load_balancer_service.py validate-modules:illegal-future-imports -plugins/modules/load_balancer_service.py validate-modules:import-before-documentation -plugins/modules/load_balancer_target.py validate-modules:illegal-future-imports -plugins/modules/load_balancer_target.py validate-modules:import-before-documentation -plugins/modules/load_balancer_type_info.py validate-modules:illegal-future-imports -plugins/modules/load_balancer_type_info.py validate-modules:import-before-documentation -plugins/modules/load_balancer.py validate-modules:illegal-future-imports -plugins/modules/load_balancer.py validate-modules:import-before-documentation -plugins/modules/location_info.py validate-modules:illegal-future-imports -plugins/modules/location_info.py validate-modules:import-before-documentation -plugins/modules/network_info.py validate-modules:illegal-future-imports -plugins/modules/network_info.py validate-modules:import-before-documentation -plugins/modules/network.py validate-modules:illegal-future-imports -plugins/modules/network.py validate-modules:import-before-documentation -plugins/modules/placement_group.py validate-modules:illegal-future-imports -plugins/modules/placement_group.py validate-modules:import-before-documentation -plugins/modules/primary_ip_info.py validate-modules:illegal-future-imports -plugins/modules/primary_ip_info.py validate-modules:import-before-documentation -plugins/modules/primary_ip.py validate-modules:illegal-future-imports -plugins/modules/primary_ip.py validate-modules:import-before-documentation -plugins/modules/rdns.py validate-modules:illegal-future-imports -plugins/modules/rdns.py validate-modules:import-before-documentation -plugins/modules/route.py validate-modules:illegal-future-imports -plugins/modules/route.py validate-modules:import-before-documentation -plugins/modules/server_info.py validate-modules:illegal-future-imports -plugins/modules/server_info.py validate-modules:import-before-documentation -plugins/modules/server_network.py validate-modules:illegal-future-imports -plugins/modules/server_network.py validate-modules:import-before-documentation -plugins/modules/server_type_info.py validate-modules:illegal-future-imports -plugins/modules/server_type_info.py validate-modules:import-before-documentation -plugins/modules/server.py validate-modules:illegal-future-imports -plugins/modules/server.py validate-modules:import-before-documentation -plugins/modules/ssh_key_info.py validate-modules:illegal-future-imports -plugins/modules/ssh_key_info.py validate-modules:import-before-documentation -plugins/modules/ssh_key.py validate-modules:illegal-future-imports -plugins/modules/ssh_key.py validate-modules:import-before-documentation -plugins/modules/subnetwork.py validate-modules:illegal-future-imports -plugins/modules/subnetwork.py validate-modules:import-before-documentation -plugins/modules/volume_info.py validate-modules:illegal-future-imports -plugins/modules/volume_info.py validate-modules:import-before-documentation -plugins/modules/volume.py validate-modules:illegal-future-imports -plugins/modules/volume.py validate-modules:import-before-documentation diff --git a/ansible_collections/hetzner/hcloud/tests/unit/conftest.py b/ansible_collections/hetzner/hcloud/tests/unit/conftest.py new file mode 100644 index 000000000..af891afc2 --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/unit/conftest.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from unittest.mock import MagicMock + +import pytest + + +@pytest.fixture() +def module(): + obj = MagicMock() + obj.params = { + "api_token": "dummy", + "api_endpoint": "https://api.hetzner.cloud/v1", + } + return obj diff --git a/ansible_collections/hetzner/hcloud/tests/unit/inventory/test_hcloud.py b/ansible_collections/hetzner/hcloud/tests/unit/inventory/test_hcloud.py new file mode 100644 index 000000000..b5d3b777b --- /dev/null +++ b/ansible_collections/hetzner/hcloud/tests/unit/inventory/test_hcloud.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +import json +from unittest.mock import MagicMock + +from plugins.inventory.hcloud import InventoryModule, first_ipv6_address +from plugins.module_utils.vendor.hcloud.servers import BoundServer + + +def test_first_ipv6_address(): + found = first_ipv6_address("2001:db8::/64") + assert isinstance(found, str) + assert found == "2001:db8::1" + + +def test_build_inventory_server(): + client = MagicMock() + inventory = InventoryModule() + inventory.get_option = MagicMock() + inventory.get_option.return_value = None + + server = BoundServer( + client, + { + "id": 45921624, + "name": "my-server", + "labels": {}, + "status": "running", + "public_net": { + "ipv4": { + "id": 56583278, + "ip": "127.0.0.1", + "blocked": False, + "dns_ptr": "static.1.0.0.127.clients.your-server.de", + }, + "ipv6": {"id": 56583279, "ip": "2001:db8::/64", "blocked": False, "dns_ptr": []}, + "floating_ips": [], + "firewalls": [], + }, + "private_net": [], + "server_type": {"id": 1, "name": "cx11", "architecture": "x86"}, + "datacenter": { + "id": 3, + "name": "hel1-dc2", + "location": {"id": 3, "name": "hel1"}, + }, + "image": {"id": 114690387, "name": "debian-12", "os_flavor": "debian", "os_version": "12"}, + }, + ) + # pylint: disable=protected-access + variables = inventory._build_inventory_server(server) + + # Ensure the host_vars are json serializable + json.dumps(variables) + + assert variables == { + "id": 45921624, + "name": "my-server", + "status": "running", + "type": "cx11", + "server_type": "cx11", + "architecture": "x86", + "location": "hel1", + "datacenter": "hel1-dc2", + "labels": {}, + "ipv4": "127.0.0.1", + "ipv6": "2001:db8::1", + "ipv6_network": "2001:db8::", + "ipv6_network_mask": "64", + "private_networks": [], + "image_id": 114690387, + "image_name": "debian-12", + "image_os_flavor": "debian", + "ansible_host": None, + } diff --git a/ansible_collections/hetzner/hcloud/tests/unit/module_utils/test_hcloud.py b/ansible_collections/hetzner/hcloud/tests/unit/module_utils/test_hcloud.py index c1a9ffb77..2f5e7509f 100644 --- a/ansible_collections/hetzner/hcloud/tests/unit/module_utils/test_hcloud.py +++ b/ansible_collections/hetzner/hcloud/tests/unit/module_utils/test_hcloud.py @@ -2,8 +2,8 @@ from __future__ import annotations import traceback from datetime import datetime, timezone -from unittest.mock import MagicMock +import pytest from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import AnsibleHCloud from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud import ( APIException, @@ -16,12 +16,7 @@ from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.actio ) -def test_hcloud_fail_json_hcloud(): - module = MagicMock() - module.params = { - "api_token": "fake_token", - "api_endpoint": "https://api.hetzner.cloud/v1", - } +def test_hcloud_fail_json_hcloud(module): AnsibleHCloud.represent = "hcloud_test" hcloud = AnsibleHCloud(module) @@ -123,3 +118,28 @@ def test_hcloud_fail_json_hcloud(): } }, ) + + +@pytest.mark.parametrize( + ("kwargs", "msg"), + [ + ({"required": ["key1"]}, None), + ({"required": ["missing"]}, "missing required arguments: missing"), + ({"required_one_of": [["key1", "missing"]]}, None), + ({"required_one_of": [["missing1", "missing2"]]}, "one of the following is required: missing1, missing2"), + ], +) +def test_hcloud_fail_on_invalid_params(module, kwargs, msg): + AnsibleHCloud.represent = "hcloud_test" + hcloud = AnsibleHCloud(module) + + module.params = { + "key1": "value", + "key2": "value", + } + + hcloud.fail_on_invalid_params(**kwargs) + if msg is None: + module.fail_json.assert_not_called() + else: + module.fail_json.assert_called_with(msg=msg) |