summaryrefslogtreecommitdiffstats
path: root/collections-debian-merged/ansible_collections/hetzner/hcloud
diff options
context:
space:
mode:
Diffstat (limited to 'collections-debian-merged/ansible_collections/hetzner/hcloud')
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/.gitignore387
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/.gitlab-ci.yml164
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/CHANGELOG.rst76
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/COPYING675
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/FILES.json2056
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/MANIFEST.json36
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/README.md21
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/.gitignore1
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml74
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/config.yaml28
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/meta/runtime.yml35
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/hcloud.py28
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py269
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py64
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py258
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py167
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py165
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py165
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py359
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py190
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py190
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py203
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py203
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py323
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py403
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py201
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py613
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py310
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py163
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py164
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py164
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py247
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py295
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py273
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py195
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py564
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py224
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py224
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py243
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py182
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py182
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py245
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py174
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py174
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py246
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py345
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py191
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py191
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/shippable.yml56
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/.gitignore1
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/requirements.txt2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/meta/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/tasks/main.yml123
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/meta/main.yml2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/tasks/main.yml39
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/tasks/main.yml40
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/tasks/main.yml443
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/tasks/main.yml87
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/tasks/main.yml62
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/tasks/main.yml247
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/tasks/main.yml128
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/tasks/main.yml155
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/tasks/main.yml112
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/defaults/main.yml7
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/tasks/main.yml129
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/tasks/main.yml38
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/tasks/main.yml57
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/aliases3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/tasks/main.yml215
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/tasks/main.yml117
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/tasks/main.yml140
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/tasks/main.yml99
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/tasks/main.yml648
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/tasks/main.yml97
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/aliases3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/tasks/main.yml222
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/tasks/main.yml38
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/defaults/main.yml8
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/meta/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/tasks/main.yml144
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/meta/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/tasks/main.yml68
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/tasks/main.yml125
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/defaults/main.yml6
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/tasks/main.yml289
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/aliases2
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/defaults/main.yml5
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/meta/main.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/tasks/main.yml101
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_selfsigned_certificate/tasks/main.yml27
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_sshkey/tasks/main.yml55
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/requirements.yml3
-rw-r--r--collections-debian-merged/ansible_collections/hetzner/hcloud/tests/sanity/requirements.txt4
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/gitlab.sh96
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/integration.sh15
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/sanity.sh47
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/check_matrix.py120
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/hcloud.sh34
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/sanity.sh44
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/shippable.sh125
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.py16
-rwxr-xr-xcollections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.sh5
172 files changed, 17244 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/.gitignore b/collections-debian-merged/ansible_collections/hetzner/hcloud/.gitignore
new file mode 100644
index 00000000..c6fc14ad
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/.gitignore
@@ -0,0 +1,387 @@
+
+# Created by https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
+# Edit at https://www.gitignore.io/?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
+
+### dotenv ###
+.env
+
+### Emacs ###
+# -*- mode: gitignore; -*-
+*~
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+auto-save-list
+tramp
+.\#*
+
+# Org-mode
+.org-id-locations
+*_archive
+
+# flymake-mode
+*_flymake.*
+
+# eshell files
+/eshell/history
+/eshell/lastdir
+
+# elpa packages
+/elpa/
+
+# reftex files
+*.rel
+
+# AUCTeX auto folder
+/auto/
+
+# cask packages
+.cask/
+dist/
+
+# Flycheck
+flycheck_*.el
+
+# server auth directory
+/server/
+
+# projectiles files
+.projectile
+
+# directory configuration
+.dir-locals.el
+
+# network security
+/network-security.data
+
+
+### Git ###
+# Created by git for backups. To disable backups in Git:
+# $ git config --global mergetool.keepBackup false
+*.orig
+
+# Created by git when using merge tools for conflicts
+*.BACKUP.*
+*.BASE.*
+*.LOCAL.*
+*.REMOTE.*
+*_BACKUP_*.txt
+*_BASE_*.txt
+*_LOCAL_*.txt
+*_REMOTE_*.txt
+
+#!! ERROR: jupyternotebook is undefined. Use list command to see defined gitignore types !!#
+
+### Linux ###
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### PyCharm+all ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### PyCharm+all Patch ###
+# Ignores the whole .idea folder and all .iml files
+# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
+
+.idea/
+
+# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
+
+*.iml
+modules.xml
+.idea/misc.xml
+*.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### pydev ###
+.pydevproject
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# pyenv
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# Mr Developer
+.mr.developer.cfg
+.project
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+### Vim ###
+# Swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-rt-v][a-z]
+[._]ss[a-gi-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+Sessionx.vim
+
+# Temporary
+.netrwhist
+# Auto-generated tag files
+tags
+# Persistent undo
+[._]*.un~
+
+### WebStorm ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+
+# Generated files
+
+# Sensitive or high-churn files
+
+# Gradle
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+
+# Mongo Explorer plugin
+
+# File-based project format
+
+# IntelliJ
+
+# mpeltonen/sbt-idea plugin
+
+# JIRA plugin
+
+# Cursive Clojure plugin
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+
+# Editor-based Rest Client
+
+# Android studio 3.1+ serialized cache file
+
+### WebStorm Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator/
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/.gitlab-ci.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/.gitlab-ci.yml
new file mode 100644
index 00000000..57b1b4d1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/.gitlab-ci.yml
@@ -0,0 +1,164 @@
+stages:
+ - sanity
+ - integration
+
+ansible-devel-1/4:
+ stage: sanity
+ image: python:3.6-buster
+ allow_failure: true
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh devel/sanity/1
+ tags:
+ - hc-bladerunner
+
+ansible-devel-2/4:
+ stage: sanity
+ image: python:3.6-buster
+ allow_failure: true
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh devel/sanity/2
+ tags:
+ - hc-bladerunner
+
+ansible-devel-3/4:
+ stage: sanity
+ image: python:3.6-buster
+ allow_failure: true
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh devel/sanity/3
+ tags:
+ - hc-bladerunner
+
+ansible-devel-4/4:
+ stage: sanity
+ image: python:3.6-buster
+ allow_failure: true
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh devel/sanity/4
+ tags:
+ - hc-bladerunner
+
+ansible-210-1/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.10/sanity/1
+ tags:
+ - hc-bladerunner
+
+ansible-210-2/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.10/sanity/2
+ tags:
+ - hc-bladerunner
+
+ansible-210-3/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.10/sanity/3
+ tags:
+ - hc-bladerunner
+
+ansible-210-4/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.10/sanity/4
+ tags:
+ - hc-bladerunner
+
+ansible-29-1/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.9/sanity/1
+ tags:
+ - hc-bladerunner
+
+ansible-29-2/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.9/sanity/2
+ tags:
+ - hc-bladerunner
+
+ansible-29-3/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.9/sanity/3
+ tags:
+ - hc-bladerunner
+
+ansible-29-4/4:
+ stage: sanity
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - bash tests/utils/gitlab/gitlab.sh 2.9/sanity/4
+ tags:
+ - hc-bladerunner
+
+ansible-devel-1/3:
+ stage: integration
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - echo "$HCLOUD_TOKEN" >> "$(pwd)/hcloud_token.txt"
+ - echo "py38-$CI_JOB_ID" >> "$(pwd)/prefix.txt"
+ - bash tests/utils/gitlab/gitlab.sh devel/hcloud/3.6/1
+ tags:
+ - hc-bladerunner
+
+
+ansible-devel-2/3:
+ stage: integration
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - echo "$HCLOUD_TOKEN" >> "$(pwd)/hcloud_token.txt"
+ - echo "py39-$CI_JOB_ID" >> "$(pwd)/prefix.txt"
+ - bash tests/utils/gitlab/gitlab.sh devel/hcloud/3.6/2
+ tags:
+ - hc-bladerunner
+
+ansible-devel-3/3:
+ stage: integration
+ image: python:3.6-buster
+ except:
+ - tags
+ script:
+ - echo "$HCLOUD_TOKEN" >> "$(pwd)/hcloud_token.txt"
+ - echo "py39-$CI_JOB_ID" >> "$(pwd)/prefix.txt"
+ - bash tests/utils/gitlab/gitlab.sh devel/hcloud/3.6/3
+ tags:
+ - hc-bladerunner
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/CHANGELOG.rst b/collections-debian-merged/ansible_collections/hetzner/hcloud/CHANGELOG.rst
new file mode 100644
index 00000000..2832f9a7
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/CHANGELOG.rst
@@ -0,0 +1,76 @@
+==============================================
+Hetzner Cloud Ansible Collection Release Notes
+==============================================
+
+.. contents:: Topics
+
+v1.2.1
+======
+
+Bugfixes
+--------
+- Inventory Restore Python 2.7 compatibility
+
+
+v1.2.0
+======
+
+Minor Changes
+-------------
+
+- Dynamic Inventory Add option to specifiy the token_env variable which is used for identification if now token is set
+- Improve imports of API Exception
+- hcloud_server_network Allow updating alias ips
+- hcloud_subnetwork Allow creating vswitch subnetworks
+
+New Modules
+-----------
+
+- hcloud_load_balancer_info - Gather infos about your Hetzner Cloud load_balancers.
+
+v1.1.0
+======
+
+Minor Changes
+-------------
+
+- hcloud_floating_ip Allow creating Floating IP with protection
+- hcloud_load_balancer Allow creating Load Balancer with protection
+- hcloud_network Allow creating Network with protection
+- hcloud_server Allow creating server with protection
+- hcloud_volume Allow creating Volumes with protection
+
+Bugfixes
+--------
+
+- hcloud_floating_ip Fix idempotency when floating ip is assigned to server
+
+v1.0.0
+======
+
+Minor Changes
+-------------
+
+- hcloud_load_balancer Allow changing the type of a Load Balancer
+- hcloud_server Allow the creation of servers with enabled backups
+
+v0.2.0
+======
+
+Bugfixes
+--------
+
+- hcloud inventory plugin - Allow usage of hcloud.yml and hcloud.yaml - this was removed by error within the migration from build-in ansible to our collection
+
+v0.1.0
+======
+
+New Modules
+-----------
+
+- hcloud_floating_ip - Create and manage cloud Floating IPs on the Hetzner Cloud.
+- hcloud_load_balancer - Create and manage cloud Load Balancers on the Hetzner Cloud.
+- hcloud_load_balancer_network - Manage the relationship between Hetzner Cloud Networks and Load Balancers
+- hcloud_load_balancer_service - Create and manage the services of cloud Load Balancers on the Hetzner Cloud.
+- hcloud_load_balancer_target - Manage Hetzner Cloud Load Balancer targets
+- hcloud_load_balancer_type_info - Gather infos about the Hetzner Cloud Load Balancer types.
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/COPYING b/collections-debian-merged/ansible_collections/hetzner/hcloud/COPYING
new file mode 100644
index 00000000..10926e87
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/COPYING
@@ -0,0 +1,675 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/FILES.json b/collections-debian-merged/ansible_collections/hetzner/hcloud/FILES.json
new file mode 100644
index 00000000..eda0aaec
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/FILES.json
@@ -0,0 +1,2056 @@
+{
+ "files": [
+ {
+ "name": ".",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "meta/runtime.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b4b578c3b0063c1ef211c696ec9158f75f39a395a3e9be13425c2a78c3740cb9",
+ "format": 1
+ },
+ {
+ "name": "changelogs",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "changelogs/config.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cfa06a718f8b3c226c944d5f33fd3ba5a07415293b07146631503539bea5d1ea",
+ "format": 1
+ },
+ {
+ "name": "changelogs/changelog.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "87cacedd54f163c2ba13d76e527bdda1c883084025d01e76751f89219b6dbcfe",
+ "format": 1
+ },
+ {
+ "name": "changelogs/.gitignore",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "919ef00776e7d2ff349950ac4b806132aa9faf006e214d5285de54533e443b33",
+ "format": 1
+ },
+ {
+ "name": "COPYING",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0ae0485a5bd37a63e63603596417e4eb0e653334fa6c7f932ca3a0e85d4af227",
+ "format": 1
+ },
+ {
+ "name": "plugins",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/module_utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/module_utils/__init__.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "format": 1
+ },
+ {
+ "name": "plugins/module_utils/hcloud.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6b1903cfe01b2da9c786dac3f272a079802d830f7351c3cb89e11f292ff4b7f1",
+ "format": 1
+ },
+ {
+ "name": "plugins/inventory",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/inventory/__init__.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "format": 1
+ },
+ {
+ "name": "plugins/inventory/hcloud.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c73b9e487d8e2eba10e375a41ffd455087ad5e2f5d9116d36206bd6c2e7913d7",
+ "format": 1
+ },
+ {
+ "name": "plugins/doc_fragments",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/doc_fragments/__init__.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "format": 1
+ },
+ {
+ "name": "plugins/doc_fragments/hcloud.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "224f4646d2d213ca52c5f0ed8ae665651e55e3a9d90f4dddfe5447d90b2abcd3",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_network.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8203a2ae529d02c5bd585a8a8494b9ffba4495abbb50629375d096bad30cfd53",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_server_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "446068bc883596000e4504e6c144a74ca904effcbfda4d0ca6aa44940844aaf8",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_floating_ip_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "66ab0912eee104e2cb71dd37ec769b8bcd7fbdf99da8eef4e5273921ccd49cbe",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_load_balancer_network.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "05ecadef86a5bdd740ef717b36619d146fd81f0cafe58aeb5379d06f285b7d2a",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_server_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "446068bc883596000e4504e6c144a74ca904effcbfda4d0ca6aa44940844aaf8",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_load_balancer.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b8abc3a38f7eb6f7e74af3a29554f5b339c5aba029949b5246ca3ff9252a4e8b",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_datacenter_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "73d46cc61148b85cd0316154fdb81b18a42b467325e5744bacbfbbb6af514f8c",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_server_network.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4ebcbf05345e63fdfa1282fd96d80134b350bdc68d119a68a24f668efdb31404",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_ssh_key_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "892aed8ae0b7c6f774eaa100c0da0783d6131b97baba5d81699cf2af570d35bd",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_certificate_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "855f63917f75af5569f57cc33a6a360bccfc02243c9dc59fdf38bb2be31b34c3",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_datacenter_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "73d46cc61148b85cd0316154fdb81b18a42b467325e5744bacbfbbb6af514f8c",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_location_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "69fa37a55cbbd1d7ce21abdf86403442c240c5ea128947d7b44412d053d3016d",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_load_balancer_type_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8b0908510d39df65055a3f9239c5b93b71c3d4a359fd3c6ae8c64646628bf6c1",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_location_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "69fa37a55cbbd1d7ce21abdf86403442c240c5ea128947d7b44412d053d3016d",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_load_balancer_service.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "215bebedbb86dfc9089c7ca12e148e75f471e404d846e404ca75b67d53b1846f",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_image_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ad749e72e6e5325cf26f4804812551c60a3ed406e75caf11c7f4fd2d4d2007f4",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_network_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "772dff9ce369127c6d8c766c8aae104532308411f89f82045e017fbaee4fe84f",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_load_balancer_target.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2653cd9784b7cf4ff4b0aec7612fff37b2e405af802c3139c7f3236ed3012b61",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_volume.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "fd76ce59902015efc40a43574d487ab66b51c47d18d6f62ec72eb0c457b254df",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_rdns.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "61acd1b4634a2d1f4e3622a9369cceae01e6f8e9bc63ff510737415179f9548a",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_server_type_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7b9183f5d1e07b903d59d2af9b7c695478adc1797dd61d59de9f4cb8eb5db1ca",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_floating_ip.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "92ebe5645394caad0f56f3574afe2a6b4693ce1c9ba2bfd9c146d554a6fae157",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_ssh_key_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "892aed8ae0b7c6f774eaa100c0da0783d6131b97baba5d81699cf2af570d35bd",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_server_type_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7b9183f5d1e07b903d59d2af9b7c695478adc1797dd61d59de9f4cb8eb5db1ca",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/__init__.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_image_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ad749e72e6e5325cf26f4804812551c60a3ed406e75caf11c7f4fd2d4d2007f4",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_certificate.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "275fd6277c3615513ed4d22d7854f93a57e3225e135a659c6454137d191dd2da",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_route.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "44a5f0aa244751d0a51c63cfd4474c9b16be73d76fafa43a8acfaf5b1f11df64",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_server.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "fe5ecbc8e86a28649316ea893d59b645c8ee913563b10ba7608c7469dc3e072f",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_ssh_key.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0cccf6ecad3cac14ede5a58ca985ac174c67c64498e5a52c9366cea4337c6a17",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_volume_facts.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1be0874dc7da8b266ec02577dd9109fb8071dc6d40852dae78c8bf09ece8c1b0",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_floating_ip_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "66ab0912eee104e2cb71dd37ec769b8bcd7fbdf99da8eef4e5273921ccd49cbe",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_load_balancer_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5c48d5ec5081a5381a035cf7b9a6272b81f75f9102e42b7c8c21d3207802221f",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_subnetwork.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ee43ae805d0067d9b226ead1bfb8ce740fbda7569a31bc1391f18d8b2f8995af",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/hcloud_volume_info.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1be0874dc7da8b266ec02577dd9109fb8071dc6d40852dae78c8bf09ece8c1b0",
+ "format": 1
+ },
+ {
+ "name": "CHANGELOG.rst",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5829f1b6c7063c39303ff2bf1527192113a5d484692c9c19900de2696a23a886",
+ "format": 1
+ },
+ {
+ "name": ".gitlab-ci.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1f6a78e5006d04406e2d889ec840d85250feff00cbc2a23fa09cc1798e8e194a",
+ "format": 1
+ },
+ {
+ "name": "tests",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/requirements.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "bdf5cf6c8dad0da0a4e726e341c0ba44124759ce387da8c1ab158a6662cb2bb6",
+ "format": 1
+ },
+ {
+ "name": "tests/sanity",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/sanity/requirements.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c8a4ac4bfdef88e75d6e748e35a42fb4915947dfa2b7dd788626fd829600e014",
+ "format": 1
+ },
+ {
+ "name": "tests/integration",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "df576bb718f55147bb2cebabd4d9597350018d8822ae06acef853e3377d9dacf",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6046d0d6217a122060d5475f76a7cf78577850caca478faa95e8483cbb53d753",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c35ec449e5b6556c7c7205e598fdc98b7dff12a9b4a6be290b3fffd936422dc4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cd53b64efc25ba17d0b8dd5db034e63ddd2bc30bd912766fd8e6f4bed585510a",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3e6a9c2bf10ea4a9deac6d22874c15244e4ac4615b59d2ef130feee4e3a7af61",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_network/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1c40ed3cdce067725ce85e113cd17f6462840570bd584662538784e8830ba6d2",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ee118e09355fa5085716b09c60ededee02cb6c104d15c293fb472bf1462ce821",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b41df455c2d9c29dad9308de40a386808471e6c386ca104bb9f3fcd0f7b86555",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a48fdbe183742154c38aa6c1658c907b2fac5a90170aca3f813c65234a33845e",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "5cb1793ca396033d9ad4fe54838da01861653b7898f91b1476a7fb5f88fc6991",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_subnetwork/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a1b71650fde2c710274a8e017cca68e43832ed6360f5aa83eb5909f8f8dc00fd",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1d6fc1e922be2f83fe92a2cce093a713b95fc4e609aa4c374d9308ff1ec3d08d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c595101d0d1838a92198660b95c472514fc903757989378c3905cb1d644e5fcd",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6e57d8acecc565433bacbbf7047387474700f9f57200f1a03d5d12948c49386f",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_floating_ip/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8fa4c135f29ccbe6563a77d7c2eb5eac7909459a53d7a69bc516fbc42f8dabd5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "67633416742aa9e9480b796190982c057f5a9b7cff7c57625029c3958b07bfb4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f657286f00631c9b264009a06a4fd667a47de6f108d10e6bcd454fad518ca97d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_network/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "93baf9ebc898fb93f961dad90033a1a50e0aa9aa4c9cc197aa78587738e42616",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cf9085335e8c310c57255c35c9a7f9ed61437277b0eb23af810565ed3a1b63d9",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c8325d94bc19646c1e3f9bd9d2cd049103a0375d37003f5eea801417987d1e06",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_route/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "754a7fee0573b3a5c27cba4c53e7f66bb36ca485e153305efbd3b332d52c36d7",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f977a248bf7c50a9f2765b1553da531ce03bc453f0af2b20a860dfdcf700d3c2",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2adfa5d38588f02b5540d12b07623b11cad61d7e3b30eca187c9df2cce855b93",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2267e95d9e1412bfa94ca2ecb76ecf5ea027753e4b50f87cf59c9450f9090b00",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7f92f7b3339191886638aa24095180b60af477e10314e059bb1e3671c571d509",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f2ac15fb16f8e251a10741c938b839bbe4786accfa7ac34a52624f1b03c4d1a9",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2267e95d9e1412bfa94ca2ecb76ecf5ea027753e4b50f87cf59c9450f9090b00",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c11de83da62fb58106ae5cc42b59fc55edfff557682656d9c0d4530d8d9c505a",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_ssh_key/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ee90ee27c8375ce531832b39ee4a3ae2f420343ac2efe2c4444a6ae8c5917a52",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "49468959c5285a8c2c8bccefa9c1d9dca5f0239158eb292bb8f4b768af0fc387",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_location_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6915c116ecff24f780c1e1268142e89399335eed0b756c9179f00cefd5dc6956",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1b20be52b226752cbaf5fa1a0c189361ccecd53ea0863b7e0b8b07c5016adabc",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_volume_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "85ad9de1a55e08bfa43a2fc065a515eda84b9c4cc411fee92084c7f47ad7485b",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4c8ffb7b82917fe7ca28a48bacc9b9a6ceae89e8fa1867711a4d6272605803d7",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "37823961c8a8ad27ade27df4d929423373e9ad5d8037240f6f137747e39f3c72",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "40e03f6534c2f7203b2b3f2aaa720b36d1ef10bfb6e6ab7f46e34bed8c976ec0",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_datacenter_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "fb76e4cbdc32b97d3a94f29edde5b730544c0006f157a89787069990044b4db5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1be0206ddc23c1059392c89a7d0e321ceccf2f3f04a0a33f2d72ff209fb51b62",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_type_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cbc4ccf4a22f6d7cf98a9c1c5710a93611f4992817dd6ffd8260e7c503274852",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e2fc1ea9b6c91b5e7979f9900ab1cd81efe8aaf0e657cc7fa0b3b5076af7c055",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_service/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "863d2c7c325991e0c83139253285f482976c7f90b5cf21422b8b390f2d564fc6",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/setup_sshkey",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/setup_sshkey/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/setup_sshkey/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "016d4c789eb18f7d6cd03c5cd32300a5e1ccec5bb6695aa35b60105c0a5d5d2d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a613e3027e9e2dd78cda228949082fa43284dae03c297b946e974ee3c0e76129",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7ed7d7d7857c25a2ae886c496afb411cc3d4918871ffa7261ef6de4eee39c909",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "096e178a932e3ee2385d05cbffd661e637be2578d65a9d9d7a99cf53739cf7aa",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f977a248bf7c50a9f2765b1553da531ce03bc453f0af2b20a860dfdcf700d3c2",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "701c31b2b52635600eb1556c68c4924f2a8a22b5da4323a445d8cb31412acb1d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6e5494d36b85275f2dd65d9e871553d4b97bb194f3c7102bf8eea017e4756036",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "54abe03862bd73dde2caed2d60073ae9a9f43aa16642f877891afde936dbadd1",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_certificate_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3e9247cbc9aa06b1c689414aa36c75e6dfb29e64018ea49411875a01c574aab4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e5641db8ac5de1ea6954d78949fbf6ac9829f86f9135ae9361859aa8220d1892",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_type_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "56fc91b4ed15be279423b2859d700b70589bb1e10bee32a829fa263253917fa2",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "864269fd363e663625df637c1cca2ad3a47ca364bbbad59da58cb75c6002a827",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b014b86e13e0e10f3b7cd1d94965ef4f8c624136662a0f534e34a38739aecbf6",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_server_network/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4aaf9b7f5c70031287488817d492fb19e9b23cb8e2f886bcf9c7f2b6bb647bf0",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/setup_selfsigned_certificate",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/setup_selfsigned_certificate/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/setup_selfsigned_certificate/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e4d4d2cd1069f55d65c9e6c8017b934023575ecb0540445ac65714d85d422323",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "cf9085335e8c310c57255c35c9a7f9ed61437277b0eb23af810565ed3a1b63d9",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "67d2e240c3add68c8276b477e63c725757f3dcee116e8dd0cddd34d09223026c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_rdns/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a6d34200e348025b85276ed0fd20d2d1ef289f893cedd0a269aef95567d2a2ca",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b02a426443d5b1f10b9edc49bad4cdaf57c66f422bdaf60f1b4b904529431fb5",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e68277c0b4e480098115380f2b03968ffea0f3318de6f9d640e768be0d479545",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_image_info/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "2969d23cfa6870f0df9924fd64064ad2aa335181b05e0399329478bce669ac62",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eb96249de09a0a3fdd399aca62aa600ee7bb7b66670ffb65e000fdbe3419d986",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/aliases",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "899ec496fc016f5e221bdf39f63bcf73374fe136f199b14cac9dd23375c989e4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4b3f8ebf1cfdac4bc445bbb94718fd47ffb1e9f10044c39cb8884e56d0e8a720",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/hcloud_load_balancer_target/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "49917a272e0f3ea6d16bd63441b76c2bec09d2f08c8bf97d1495a712b13efa43",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/requirements.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f8c3336e9a6315d376c59719374e5aced8a1be5d81934e0b39bc9483fdb49dc6",
+ "format": 1
+ },
+ {
+ "name": "tests/.gitignore",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b5726d3ec9335a09c124469eca039523847a6b0f08a083efaefd002b83326600",
+ "format": 1
+ },
+ {
+ "name": "tests/utils",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable/check_matrix.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eca2864515b1854d55dd78b481962969ac030fa8d10a4fd4edb9833797ee85fb",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable/sanity.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a1c968fc55bac46136d755c3c9bbbc8c410bf659d41a59816f143cf313ab3cbf",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable/timing.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ebb7d3553349747ad41d80899ed353e13cf32fcbecbb6566cf36e9d2bc33703e",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable/shippable.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c76455e44c5fcb99b91304565065a7038faa8898bd09336c79d35d3b1b069d1d",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable/hcloud.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "99db6946e47cf9e49ab2fccbe0aca8ffc9aaa0918fdc9e3ef543601c55a98713",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/shippable/timing.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f3f3cc03a997cdba719b0542fe668fc612451841cbe840ab36865f30aa54a1bd",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/gitlab",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/utils/gitlab/gitlab.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1cee085f785834aaef060499855774c4a0035fae372bb5a9895dead5db45b92c",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/gitlab/sanity.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "fbfffdeff0e937f847ba0ab2d7f1996cb2ab0e19ce87f3ea0e2041491dacd372",
+ "format": 1
+ },
+ {
+ "name": "tests/utils/gitlab/integration.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b68bb45e91cd28465c3344832c467c24df2a3abf75b184ba70b0ae5a1e55e23b",
+ "format": 1
+ },
+ {
+ "name": "shippable.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "344f26797924cbccbe1de233cc7e917eb1b362ac8bba3fae7291a60130232809",
+ "format": 1
+ },
+ {
+ "name": ".gitignore",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "258e4be3cfda40797fe734b375b6f94c110c9a9bebce196fedce319a457ce720",
+ "format": 1
+ },
+ {
+ "name": "README.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c4973cd35a5ed2b70d42f55c7d22bfcaf54dec3f04229f58285102b09dd1088f",
+ "format": 1
+ }
+ ],
+ "format": 1
+} \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/MANIFEST.json b/collections-debian-merged/ansible_collections/hetzner/hcloud/MANIFEST.json
new file mode 100644
index 00000000..f5d10c6f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/MANIFEST.json
@@ -0,0 +1,36 @@
+{
+ "collection_info": {
+ "namespace": "hetzner",
+ "name": "hcloud",
+ "version": "1.2.1",
+ "authors": [
+ "Hetzner Cloud (github.com/hetznercloud)"
+ ],
+ "readme": "README.md",
+ "tags": [
+ "hetzner",
+ "cloud",
+ "hcloud"
+ ],
+ "description": "A Collection for managing Hetzner Cloud resources",
+ "license": [
+ "GPL-3.0-or-later"
+ ],
+ "license_file": null,
+ "dependencies": {
+ "ansible.netcommon": ">=0.0.1"
+ },
+ "repository": "https://github.com/ansible-collections/hetzner.hcloud",
+ "documentation": "https://github.com/ansible-collections/hetzner.hcloud/tree/master/docs",
+ "homepage": "https://github.com/ansible-collections/hetzner.hcloud",
+ "issues": "https://github.com/ansible-collections/hetzner.hcloud/issues"
+ },
+ "file_manifest_file": {
+ "name": "FILES.json",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "53cfd501f092788b834b4eafa0a921deadeb25f123a7586189f89c95fef73dda",
+ "format": 1
+ },
+ "format": 1
+} \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/README.md b/collections-debian-merged/ansible_collections/hetzner/hcloud/README.md
new file mode 100644
index 00000000..eed66003
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/README.md
@@ -0,0 +1,21 @@
+[![Run Status](https://api.shippable.com/projects/5e66776c8b17a60007e4c277/badge?branch=master)]()
+
+Ansible Collection: hetzner.hcloud
+=================================================
+
+Ansible Hetzner Cloud Collection for controlling your Hetzner Cloud Resources.
+
+## Release notes
+
+See [here](https://github.com/ansible-collections/hetzner.hcloud/tree/master/CHANGELOG.rst).
+
+
+## Publishing New Version
+
+
+TBD Basic instructions without release branches:
+
+1. Create `changelogs/fragments/<version>.yml` with `release_summary:` section (which must be a string, not a list).
+2. Run `antsibull-changelog release --collection-flatmap yes`
+3. Make sure `CHANGELOG.rst` and `changelogs/changelog.yaml` are added to git, and the deleted fragments have been removed.
+4. Tag the commit with `<version>`. Push changes and tag to the main repository.
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/.gitignore b/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/.gitignore
new file mode 100644
index 00000000..6be6b533
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/.gitignore
@@ -0,0 +1 @@
+/.plugin-cache.yaml
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml b/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml
new file mode 100644
index 00000000..7e2c2f56
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/changelog.yaml
@@ -0,0 +1,74 @@
+ancestor: null
+releases:
+ 0.1.0:
+ modules:
+ - description: Create and manage cloud Floating IPs on the Hetzner Cloud.
+ name: hcloud_floating_ip
+ namespace: ''
+ - description: Create and manage cloud Load Balancers on the Hetzner Cloud.
+ name: hcloud_load_balancer
+ namespace: ''
+ - description: Manage the relationship between Hetzner Cloud Networks and Load
+ Balancers
+ name: hcloud_load_balancer_network
+ namespace: ''
+ - description: Create and manage the services of cloud Load Balancers on the Hetzner
+ Cloud.
+ name: hcloud_load_balancer_service
+ namespace: ''
+ - description: Manage Hetzner Cloud Load Balancer targets
+ name: hcloud_load_balancer_target
+ namespace: ''
+ - description: Gather infos about the Hetzner Cloud Load Balancer types.
+ name: hcloud_load_balancer_type_info
+ namespace: ''
+ release_date: '2020-06-29'
+ 0.2.0:
+ changes:
+ bugfixes:
+ - hcloud inventory plugin - Allow usage of hcloud.yml and hcloud.yaml - this
+ was removed by error within the migration from build-in ansible to our collection
+ fragments:
+ - inventory-allow-usage-of-pre-migration-configuration-fuiles.yml
+ release_date: '2020-06-30'
+ 1.0.0:
+ changes:
+ minor_changes:
+ - hcloud_load_balancer Allow changing the type of a Load Balancer
+ - hcloud_server Allow the creation of servers with enabled backups
+ fragments:
+ - gh7-allow-enabling-of-backups-on-server-creation.yml
+ - lb-allow-change-type.yml
+ release_date: '2020-08-11'
+ 1.1.0:
+ changes:
+ bugfixes:
+ - hcloud_floating_ip Fix idempotency when floating ip is assigned to server
+ minor_changes:
+ - hcloud_floating_ip Allow creating Floating IP with protection
+ - hcloud_load_balancer Allow creating Load Balancer with protection
+ - hcloud_network Allow creating Network with protection
+ - hcloud_server Allow creating server with protection
+ - hcloud_volume Allow creating Volumes with protection
+ fragments:
+ - fix-idempotency-floating-ip.yml
+ - gh-28-allow-setting-of-protection-on-creation.yml
+ release_date: '2020-10-05'
+ 1.2.0:
+ changes:
+ minor_changes:
+ - Dynamic Inventory Add option to specifiy the token_env variable which is used
+ for identification if now token is set
+ - Improve imports of API Exception
+ - hcloud_server_network Allow updating alias ips
+ - hcloud_subnetwork Allow creating vswitch subnetworks
+ modules:
+ - description: Gather infos about your Hetzner Cloud load_balancers.
+ name: hcloud_load_balancer_info
+ namespace: ''
+ release_date: '2020-12-01'
+ 1.2.1:
+ changes:
+ bugfixes:
+ - Inventory Restore Python 2.7 compatibility
+ release_date: '2020-12-16'
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/config.yaml b/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/config.yaml
new file mode 100644
index 00000000..739603a4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/changelogs/config.yaml
@@ -0,0 +1,28 @@
+title: Hetzner Cloud Ansible Collection
+changelog_filename_template: ../CHANGELOG.rst
+changelog_filename_version_depth: 0
+changes_file: changelog.yaml
+changes_format: combined
+keep_fragments: false
+mention_ancestor: true
+new_plugins_after_name: removed_features
+notesdir: fragments
+prelude_section_name: release_summary
+prelude_section_title: Release Summary
+sections:
+- - major_changes
+ - Major Changes
+- - minor_changes
+ - Minor Changes
+- - breaking_changes
+ - Breaking Changes / Porting Guide
+- - deprecated_features
+ - Deprecated Features
+- - removed_features
+ - Removed Features (previously deprecated)
+- - security_fixes
+ - Security Fixes
+- - bugfixes
+ - Bugfixes
+- - known_issues
+ - Known Issues
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/meta/runtime.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/meta/runtime.yml
new file mode 100644
index 00000000..1f7fb2f4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/meta/runtime.yml
@@ -0,0 +1,35 @@
+requires_ansible: '>=2.9.10'
+plugin_routing:
+ modules:
+ hcloud_location_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_server_type_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_image_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_volume_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_floating_ip_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_ssh_key_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_datacenter_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
+ hcloud_server_facts:
+ deprecation:
+ removal_version: 2.0.0
+ warning_text: see plugin documentation for details
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/__init__.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/__init__.py
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/hcloud.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/hcloud.py
new file mode 100644
index 00000000..2548b1e6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/doc_fragments/hcloud.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# 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)
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+class ModuleDocFragment(object):
+ DOCUMENTATION = '''
+options:
+ api_token:
+ description:
+ - This is the API Token for the Hetzner Cloud.
+ required: True
+ type: str
+ endpoint:
+ description:
+ - This is the API Endpoint for the Hetzner Cloud.
+ default: https://api.hetzner.cloud/v1
+ type: str
+requirements:
+ - hcloud-python >= 1.0.0
+seealso:
+- name: Documentation for Hetzner Cloud API
+ description: Complete reference for the Hetzner Cloud API.
+ link: https://docs.hetzner.cloud/
+'''
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/__init__.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/__init__.py
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py
new file mode 100644
index 00000000..080327e7
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py
@@ -0,0 +1,269 @@
+# 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)
+
+from __future__ import (absolute_import, division, print_function)
+
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+ name: hcloud
+ plugin_type: inventory
+ author:
+ - Lukas Kaemmerling (@lkaemmerling)
+ short_description: Ansible dynamic inventory plugin for the Hetzner Cloud.
+ requirements:
+ - python >= 2.7
+ - hcloud-python >= 1.0.0
+ description:
+ - Reads inventories from the Hetzner Cloud API.
+ - Uses a YAML configuration file that ends with hcloud.(yml|yaml).
+ extends_documentation_fragment:
+ - constructed
+ options:
+ plugin:
+ description: marks this as an instance of the "hcloud" plugin
+ required: true
+ choices: ["hcloud"]
+ token:
+ description: The Hetzner Cloud API Token.
+ required: false
+ token_env:
+ description: Environment variable to load the Hetzner Cloud API Token from.
+ default: HCLOUD_TOKEN
+ type: str
+ required: false
+ connect_with:
+ description: Connect to the server using the value from this field.
+ default: public_ipv4
+ type: str
+ choices:
+ - public_ipv4
+ - hostname
+ - ipv4_dns_ptr
+ - private_ipv4
+ locations:
+ description: Populate inventory with instances in this location.
+ default: []
+ type: list
+ required: false
+ types:
+ description: Populate inventory with instances with this type.
+ default: []
+ type: list
+ required: false
+ images:
+ description: Populate inventory with instances with this image name, only available for system images.
+ default: []
+ type: list
+ required: false
+ label_selector:
+ description: Populate inventory with instances with this label.
+ default: ""
+ type: str
+ required: false
+ network:
+ description: Populate inventory with instances which are attached to this network name or ID.
+ default: ""
+ type: str
+ required: false
+'''
+
+EXAMPLES = r"""
+# Minimal example. `HCLOUD_TOKEN` is exposed in environment.
+plugin: hcloud
+
+# Example with locations, types, groups and token
+plugin: hcloud
+token: foobar
+locations:
+ - nbg1
+types:
+ - cx11
+
+# Group by a location with prefix e.g. "hcloud_location_nbg1"
+# and image_os_flavor without prefix and separator e.g. "ubuntu"
+# and status with prefix e.g. "server_status_running"
+plugin: hcloud
+keyed_groups:
+ - key: location
+ prefix: hcloud_location
+ - key: image_os_flavor
+ separator: ""
+ - key: status
+ prefix: server_status
+"""
+
+import os
+from ansible.errors import AnsibleError
+from ansible.module_utils._text import to_native
+from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
+from ansible.release import __version__
+
+try:
+ from hcloud import hcloud
+ from hcloud import APIException
+except ImportError:
+ raise AnsibleError("The Hetzner Cloud dynamic inventory plugin requires hcloud-python.")
+
+
+class InventoryModule(BaseInventoryPlugin, Constructable):
+ NAME = 'hetzner.hcloud.hcloud'
+
+ def _configure_hcloud_client(self):
+ self.token_env = self.get_option("token_env")
+ self.api_token = self.get_option("token") or os.getenv(self.token_env)
+ if self.api_token is None:
+ raise AnsibleError(
+ "Please specify a token, via the option token, via environment variable HCLOUD_TOKEN "
+ "or via custom environment variable set by token_env option."
+ )
+
+ self.endpoint = os.getenv("HCLOUD_ENDPOINT") or "https://api.hetzner.cloud/v1"
+
+ self.client = hcloud.Client(token=self.api_token,
+ api_endpoint=self.endpoint,
+ application_name="ansible-inventory",
+ application_version=__version__)
+
+ def _test_hcloud_token(self):
+ try:
+ # We test the API Token against the location API, because this is the API with the smallest result
+ # and not controllable from the customer.
+ self.client.locations.get_all()
+ except APIException:
+ raise AnsibleError("Invalid Hetzner Cloud API Token.")
+
+ def _get_servers(self):
+ if len(self.get_option("label_selector")) > 0:
+ self.servers = self.client.servers.get_all(label_selector=self.get_option("label_selector"))
+ else:
+ self.servers = self.client.servers.get_all()
+
+ def _filter_servers(self):
+ if self.get_option("network"):
+ try:
+ self.network = self.client.networks.get_by_name(self.get_option("network"))
+ if self.network is None:
+ self.network = self.client.networks.get_by_id(self.get_option("network"))
+ except APIException:
+ raise AnsibleError(
+ "The given network is not found.")
+
+ tmp = []
+ for server in self.servers:
+ for server_private_network in server.private_net:
+ if server_private_network.network.id == self.network.id:
+ tmp.append(server)
+ self.servers = tmp
+
+ if self.get_option("locations"):
+ tmp = []
+ for server in self.servers:
+ if server.datacenter.location.name in self.get_option("locations"):
+ tmp.append(server)
+ self.servers = tmp
+
+ if self.get_option("types"):
+ tmp = []
+ for server in self.servers:
+ if server.server_type.name in self.get_option("types"):
+ tmp.append(server)
+ self.servers = tmp
+
+ if self.get_option("images"):
+ tmp = []
+ for server in self.servers:
+ if server.image is not None and server.image.os_flavor in self.get_option("images"):
+ tmp.append(server)
+ self.servers = tmp
+
+ def _set_server_attributes(self, server):
+ self.inventory.set_variable(server.name, "id", to_native(server.id))
+ self.inventory.set_variable(server.name, "name", to_native(server.name))
+ self.inventory.set_variable(server.name, "status", to_native(server.status))
+ self.inventory.set_variable(server.name, "type", to_native(server.server_type.name))
+
+ # Network
+ self.inventory.set_variable(server.name, "ipv4", to_native(server.public_net.ipv4.ip))
+ self.inventory.set_variable(server.name, "ipv6_network", to_native(server.public_net.ipv6.network))
+ self.inventory.set_variable(server.name, "ipv6_network_mask", to_native(server.public_net.ipv6.network_mask))
+
+ if self.get_option("network"):
+ for server_private_network in server.private_net:
+ if server_private_network.network.id == self.network.id:
+ self.inventory.set_variable(server.name, "private_ipv4", to_native(server_private_network.ip))
+
+ if self.get_option("connect_with") == "public_ipv4":
+ self.inventory.set_variable(server.name, "ansible_host", to_native(server.public_net.ipv4.ip))
+ elif self.get_option("connect_with") == "hostname":
+ self.inventory.set_variable(server.name, "ansible_host", to_native(server.name))
+ elif self.get_option("connect_with") == "ipv4_dns_ptr":
+ self.inventory.set_variable(server.name, "ansible_host", to_native(server.public_net.ipv4.dns_ptr))
+ elif self.get_option("connect_with") == "private_ipv4":
+ if self.get_option("network"):
+ for server_private_network in server.private_net:
+ if server_private_network.network.id == self.network.id:
+ self.inventory.set_variable(server.name, "ansible_host", to_native(server_private_network.ip))
+ else:
+ raise AnsibleError(
+ "You can only connect via private IPv4 if you specify a network")
+
+ # Server Type
+ if server.image is not None and server.image.name is not None:
+ self.inventory.set_variable(server.name, "server_type", to_native(server.image.name))
+ else:
+ self.inventory.set_variable(server.name, "server_type", to_native("No Image name found."))
+
+ # Datacenter
+ self.inventory.set_variable(server.name, "datacenter", to_native(server.datacenter.name))
+ self.inventory.set_variable(server.name, "location", to_native(server.datacenter.location.name))
+
+ # Image
+ if server.image is not None:
+ self.inventory.set_variable(server.name, "image_id", to_native(server.image.id))
+ self.inventory.set_variable(server.name, "image_os_flavor", to_native(server.image.os_flavor))
+ if server.image.name is not None:
+ self.inventory.set_variable(server.name, "image_name", to_native(server.image.name))
+ else:
+ self.inventory.set_variable(server.name, "image_name", to_native(server.image.description))
+ else:
+ self.inventory.set_variable(server.name, "image_id", to_native("No Image ID found"))
+ self.inventory.set_variable(server.name, "image_name", to_native("No Image Name found"))
+ self.inventory.set_variable(server.name, "image_os_flavor", to_native("No Image OS Flavor found"))
+
+ # Labels
+ self.inventory.set_variable(server.name, "labels", dict(server.labels))
+
+ def verify_file(self, path):
+ """Return the possibly of a file being consumable by this plugin."""
+ return (
+ super(InventoryModule, self).verify_file(path) and
+ path.endswith(("hcloud.yaml", "hcloud.yml"))
+ )
+
+ def parse(self, inventory, loader, path, cache=True):
+ super(InventoryModule, self).parse(inventory, loader, path, cache)
+ self._read_config_data(path)
+ self._configure_hcloud_client()
+ self._test_hcloud_token()
+ self._get_servers()
+ self._filter_servers()
+
+ # Add a top group 'hcloud'
+ self.inventory.add_group(group="hcloud")
+
+ for server in self.servers:
+ self.inventory.add_host(server.name, group="hcloud")
+ self._set_server_attributes(server)
+
+ # Use constructed if applicable
+ strict = self.get_option('strict')
+
+ # Composed variables
+ self._set_composite_vars(self.get_option('compose'), self.inventory.get_host(server.name).get_vars(), server.name, strict=strict)
+
+ # Complex groups based on jinja2 conditionals, hosts that meet the conditional are added to group
+ self._add_host_to_composed_groups(self.get_option('groups'), {}, server.name, strict=strict)
+
+ # Create groups based on variable values and add the corresponding hosts to it
+ self._add_host_to_keyed_groups(self.get_option('keyed_groups'), {}, server.name, strict=strict)
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/__init__.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/__init__.py
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py
new file mode 100644
index 00000000..e1bc6c58
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright: (c) 2019, Hetzner Cloud GmbH <info@hetzner-cloud.de>
+
+# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+from ansible.module_utils.ansible_release import __version__
+from ansible.module_utils.basic import env_fallback, missing_required_lib
+
+try:
+ import hcloud
+ from hcloud import APIException
+
+ HAS_HCLOUD = True
+except ImportError:
+ HAS_HCLOUD = False
+
+
+class Hcloud(object):
+ def __init__(self, module, represent):
+ self.module = module
+ self.represent = represent
+ self.result = {"changed": False, self.represent: None}
+ if not HAS_HCLOUD:
+ module.fail_json(msg=missing_required_lib("hcloud-python"))
+ self._build_client()
+
+ def _build_client(self):
+ self.client = hcloud.Client(
+ token=self.module.params["api_token"],
+ api_endpoint=self.module.params["endpoint"],
+ application_name="ansible-module",
+ application_version=__version__,
+ )
+
+ def _mark_as_changed(self):
+ self.result["changed"] = True
+
+ @staticmethod
+ def base_module_arguments():
+ return {
+ "api_token": {
+ "type": "str",
+ "required": True,
+ "fallback": (env_fallback, ["HCLOUD_TOKEN"]),
+ "no_log": True,
+ },
+ "endpoint": {"type": "str", "default": "https://api.hetzner.cloud/v1"},
+ }
+
+ def _prepare_result(self):
+ """Prepare the result for every module
+
+ :return: dict
+ """
+ return {}
+
+ def get_result(self):
+ if getattr(self, self.represent) is not None:
+ self.result[self.represent] = self._prepare_result()
+ return self.result
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/__init__.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/__init__.py
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py
new file mode 100644
index 00000000..9b6c6864
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate.py
@@ -0,0 +1,258 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_certificate
+
+short_description: Create and manage certificates on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage certificates on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud certificate to manage.
+ - Only required if no certificate I(name) is given
+ type: int
+ name:
+ description:
+ - The Name of the Hetzner Cloud certificate to manage.
+ - Only required if no certificate I(id) is given or a certificate does not exists.
+ type: str
+ labels:
+ description:
+ - User-defined labels (key-value pairs)
+ type: dict
+ certificate:
+ description:
+ - Certificate and chain in PEM format, in order so that each record directly certifies the one preceding.
+ - Required if certificate does not exists.
+ type: str
+ private_key:
+ description:
+ - Certificate key in PEM format.
+ - Required if certificate does not exists.
+ type: str
+ state:
+ description:
+ - State of the certificate.
+ default: present
+ choices: [ absent, present ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic certificate
+ hcloud_certificate:
+ name: my-certificate
+ certificate: "ssh-rsa AAAjjk76kgf...Xt"
+ private_key: "ssh-rsa AAAjjk76kgf...Xt"
+ state: present
+
+- name: Create a certificate with labels
+ hcloud_certificate:
+ name: my-certificate
+ certificate: "ssh-rsa AAAjjk76kgf...Xt"
+ private_key: "ssh-rsa AAAjjk76kgf...Xt"
+ labels:
+ key: value
+ mylabel: 123
+ state: present
+
+- name: Ensure the certificate is absent (remove if needed)
+ hcloud_certificate:
+ name: my-certificate
+ state: absent
+"""
+
+RETURN = """
+hcloud_certificate:
+ description: The certificate instance
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the certificate
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the certificate
+ returned: always
+ type: str
+ sample: my website cert
+ fingerprint:
+ description: Fingerprint of the certificate
+ returned: always
+ type: str
+ sample: "03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f"
+ certificate:
+ description: Certificate and chain in PEM format
+ returned: always
+ type: str
+ sample: "-----BEGIN CERTIFICATE-----..."
+ domain_names:
+ description: List of Domains and Subdomains covered by the Certificate
+ returned: always
+ type: dict
+ not_valid_before:
+ description: Point in time when the Certificate becomes valid (in ISO-8601 format)
+ returned: always
+ type: str
+ not_valid_after:
+ description: Point in time when the Certificate stops being valid (in ISO-8601 format)
+ returned: always
+ type: str
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud.certificates.domain import Certificate
+ from hcloud.certificates.domain import Server
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudCertificate(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_certificate")
+ self.hcloud_certificate = None
+
+ def _prepare_result(self):
+ return {
+ "id": to_native(self.hcloud_certificate.id),
+ "name": to_native(self.hcloud_certificate.name),
+ "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],
+ "labels": self.hcloud_certificate.labels
+ }
+
+ def _get_certificate(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_certificate = self.client.certificates.get_by_id(
+ self.module.params.get("id")
+ )
+ elif self.module.params.get("name") is not None:
+ self.hcloud_certificate = self.client.certificates.get_by_name(
+ self.module.params.get("name")
+ )
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_certificate(self):
+ self.module.fail_on_missing_params(
+ required_params=["name", "certificate", "private_key"]
+ )
+ params = {
+ "name": self.module.params.get("name"),
+ "certificate": self.module.params.get("certificate"),
+ "private_key": self.module.params.get("private_key"),
+ "labels": self.module.params.get("labels")
+ }
+
+ if not self.module.check_mode:
+ try:
+ self.client.certificates.create(**params)
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+ self._mark_as_changed()
+ self._get_certificate()
+
+ def _update_certificate(self):
+ name = self.module.params.get("name")
+ if name is not None and self.hcloud_certificate.name != name:
+ self.module.fail_on_missing_params(
+ required_params=["id"]
+ )
+ if not self.module.check_mode:
+ self.hcloud_certificate.update(name=name)
+ self._mark_as_changed()
+
+ labels = self.module.params.get("labels")
+ if labels is not None and self.hcloud_certificate.labels != labels:
+ if not self.module.check_mode:
+ self.hcloud_certificate.update(labels=labels)
+ self._mark_as_changed()
+
+ self._get_certificate()
+
+ def present_certificate(self):
+ self._get_certificate()
+ if self.hcloud_certificate is None:
+ self._create_certificate()
+ else:
+ self._update_certificate()
+
+ def delete_certificate(self):
+ self._get_certificate()
+ if self.hcloud_certificate is not None:
+ if not self.module.check_mode:
+ self.client.certificates.delete(self.hcloud_certificate)
+ self._mark_as_changed()
+ self.hcloud_certificate = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ certificate={"type": "str"},
+ private_key={"type": "str"},
+ labels={"type": "dict"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name']],
+ required_if=[['state', 'present', ['name']]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudCertificate.define_module()
+
+ hcloud = AnsibleHcloudCertificate(module)
+ state = module.params.get("state")
+ if state == "absent":
+ hcloud.delete_certificate()
+ elif state == "present":
+ hcloud.present_certificate()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py
new file mode 100644
index 00000000..479613af
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_certificate_info.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_certificate_info
+short_description: Gather infos about your Hetzner Cloud certificates.
+description:
+ - Gather facts about your Hetzner Cloud certificates.
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+options:
+ id:
+ description:
+ - The ID of the certificate you want to get.
+ type: int
+ name:
+ description:
+ - The name of the certificate you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the certificate you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud certificate infos
+ hcloud_certificate_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_certificate_info
+"""
+
+RETURN = """
+hcloud_certificate_info:
+ description: The certificate instances
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the certificate
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the certificate
+ returned: always
+ type: str
+ sample: my website cert
+ fingerprint:
+ description: Fingerprint of the certificate
+ returned: always
+ type: str
+ sample: "03:c7:55:9b:2a:d1:04:17:09:f6:d0:7f:18:34:63:d4:3e:5f"
+ certificate:
+ description: Certificate and chain in PEM format
+ returned: always
+ type: str
+ sample: "-----BEGIN CERTIFICATE-----..."
+ domain_names:
+ description: List of Domains and Subdomains covered by the Certificate
+ returned: always
+ type: dict
+ not_valid_before:
+ description: Point in time when the Certificate becomes valid (in ISO-8601 format)
+ returned: always
+ type: str
+ not_valid_after:
+ description: Point in time when the Certificate stops being valid (in ISO-8601 format)
+ returned: always
+ type: str
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudCertificateInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_certificate_info")
+ self.hcloud_certificate_info = None
+
+ def _prepare_result(self):
+ certificates = []
+
+ 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
+
+ def get_certificates(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_certificate_info = [self.client.certificates.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_certificate_info = [self.client.certificates.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_certificate_info = self.client.certificates.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_certificate_info = self.client.certificates.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudCertificateInfo.define_module()
+
+ hcloud = AnsibleHcloudCertificateInfo(module)
+ hcloud.get_certificates()
+ result = hcloud.get_result()
+
+ ansible_info = {
+ 'hcloud_certificate_info': result['hcloud_certificate_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py
new file mode 100644
index 00000000..6c53672a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_facts.py
@@ -0,0 +1,165 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_datacenter_info
+
+short_description: Gather info about the Hetzner Cloud datacenters.
+
+description:
+ - Gather info about your Hetzner Cloud datacenters.
+ - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
+ Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the datacenter you want to get.
+ type: int
+ name:
+ description:
+ - The name of the datacenter you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud datacenter info
+ hcloud_datacenter_info:
+ register: output
+- name: Print the gathered info
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_datacenter_info:
+ description:
+ - The datacenter info as list
+ - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
+ Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the datacenter
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the datacenter
+ returned: always
+ type: str
+ sample: fsn1-dc8
+ description:
+ description: Detail description of the datacenter
+ returned: always
+ type: str
+ sample: Falkenstein DC 8
+ location:
+ description: Name of the location where the datacenter resides in
+ returned: always
+ type: str
+ sample: fsn1
+ city:
+ description: City of the location
+ returned: always
+ type: str
+ sample: fsn1
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudDatacenterInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_datacenter_info")
+ self.hcloud_datacenter_info = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for datacenter in self.hcloud_datacenter_info:
+ if datacenter is not None:
+ tmp.append({
+ "id": to_native(datacenter.id),
+ "name": to_native(datacenter.name),
+ "description": to_native(datacenter.description),
+ "location": to_native(datacenter.location.name)
+ })
+
+ return tmp
+
+ def get_datacenters(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_datacenter_info = [self.client.datacenters.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_datacenter_info = [self.client.datacenters.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_datacenter_info = self.client.datacenters.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudDatacenterInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_datacenter_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_datacenter_facts' module has been renamed to 'hcloud_datacenter_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+ hcloud = AnsibleHcloudDatacenterInfo(module)
+
+ hcloud.get_datacenters()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_datacenter_facts': result['hcloud_datacenter_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_datacenter_info': result['hcloud_datacenter_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py
new file mode 100644
index 00000000..6c53672a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_datacenter_info.py
@@ -0,0 +1,165 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_datacenter_info
+
+short_description: Gather info about the Hetzner Cloud datacenters.
+
+description:
+ - Gather info about your Hetzner Cloud datacenters.
+ - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
+ Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the datacenter you want to get.
+ type: int
+ name:
+ description:
+ - The name of the datacenter you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud datacenter info
+ hcloud_datacenter_info:
+ register: output
+- name: Print the gathered info
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_datacenter_info:
+ description:
+ - The datacenter info as list
+ - This module was called C(hcloud_datacenter_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_datacenter_facts).
+ Note that the M(hetzner.hcloud.hcloud_datacenter_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_datacenter_info)!
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the datacenter
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the datacenter
+ returned: always
+ type: str
+ sample: fsn1-dc8
+ description:
+ description: Detail description of the datacenter
+ returned: always
+ type: str
+ sample: Falkenstein DC 8
+ location:
+ description: Name of the location where the datacenter resides in
+ returned: always
+ type: str
+ sample: fsn1
+ city:
+ description: City of the location
+ returned: always
+ type: str
+ sample: fsn1
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudDatacenterInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_datacenter_info")
+ self.hcloud_datacenter_info = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for datacenter in self.hcloud_datacenter_info:
+ if datacenter is not None:
+ tmp.append({
+ "id": to_native(datacenter.id),
+ "name": to_native(datacenter.name),
+ "description": to_native(datacenter.description),
+ "location": to_native(datacenter.location.name)
+ })
+
+ return tmp
+
+ def get_datacenters(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_datacenter_info = [self.client.datacenters.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_datacenter_info = [self.client.datacenters.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_datacenter_info = self.client.datacenters.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudDatacenterInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_datacenter_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_datacenter_facts' module has been renamed to 'hcloud_datacenter_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+ hcloud = AnsibleHcloudDatacenterInfo(module)
+
+ hcloud.get_datacenters()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_datacenter_facts': result['hcloud_datacenter_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_datacenter_info': result['hcloud_datacenter_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py
new file mode 100644
index 00000000..5cba5d5d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip.py
@@ -0,0 +1,359 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_floating_ip
+
+short_description: Create and manage cloud Floating IPs on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage cloud Floating IPs on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+version_added: 0.1.0
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud Floating IPs to manage.
+ - Only required if no Floating IP I(name) is given.
+ type: int
+ name:
+ description:
+ - The Name of the Hetzner Cloud Floating IPs to manage.
+ - Only required if no Floating IP I(id) is given or a Floating IP does not exists.
+ type: str
+ description:
+ description:
+ - The Description of the Hetzner Cloud Floating IPs.
+ type: str
+ home_location:
+ description:
+ - Home Location of the Hetzner Cloud Floating IP.
+ - Required if no I(server) is given and Floating IP does not exists.
+ type: str
+ server:
+ description:
+ - Server Name the Floating IP should be assigned to.
+ - Required if no I(home_location) is given and Floating IP does not exists.
+ type: str
+ type:
+ description:
+ - Type of the Floating IP.
+ - Required if Floating IP does not exists
+ choices: [ ipv4, ipv6 ]
+ type: str
+ force:
+ description:
+ - Force the assignment or deletion of the Floating IP.
+ type: bool
+ delete_protection:
+ description:
+ - Protect the Floating IP for deletion.
+ type: bool
+ labels:
+ description:
+ - User-defined labels (key-value pairs).
+ type: dict
+ state:
+ description:
+ - State of the Floating IP.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.6.0
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic IPv4 Floating IP
+ hcloud_floating_ip:
+ name: my-floating-ip
+ home_location: fsn1
+ type: ipv4
+ state: present
+- name: Create a basic IPv6 Floating IP
+ hcloud_floating_ip:
+ name: my-floating-ip
+ home_location: fsn1
+ type: ipv6
+ state: present
+- name: Assign a Floating IP to a server
+ hcloud_floating_ip:
+ name: my-floating-ip
+ server: 1234
+ state: present
+- name: Assign a Floating IP to another server
+ hcloud_floating_ip:
+ name: my-floating-ip
+ server: 1234
+ force: yes
+ state: present
+- name: Floating IP should be absent
+ hcloud_floating_ip:
+ name: my-floating-ip
+ state: absent
+"""
+
+RETURN = """
+hcloud_floating_ip:
+ description: The Floating IP instance
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: ID of the Floating IP
+ type: int
+ returned: Always
+ sample: 12345
+ name:
+ description: Name of the Floating IP
+ type: str
+ returned: Always
+ sample: my-floating-ip
+ description:
+ description: Description of the Floating IP
+ type: str
+ returned: Always
+ sample: my-floating-ip
+ ip:
+ description: IP Address of the Floating IP
+ type: str
+ returned: Always
+ sample: 116.203.104.109
+ type:
+ description: Type of the Floating IP
+ type: str
+ returned: Always
+ sample: ipv4
+ home_location:
+ description: Name of the home location of the Floating IP
+ type: str
+ returned: Always
+ sample: fsn1
+ server:
+ description: Name of the server the Floating IP is assigned to.
+ type: str
+ returned: Always
+ sample: "my-server"
+ delete_protection:
+ description: True if Floating IP is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+ labels:
+ description: User-defined labels (key-value pairs)
+ type: dict
+ returned: Always
+ sample:
+ key: value
+ mylabel: 123
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudFloatingIP(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_floating_ip")
+ self.hcloud_floating_ip = 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),
+ "labels": self.hcloud_floating_ip.labels,
+ "server": server,
+ "delete_protection": self.hcloud_floating_ip.protection["delete"],
+ }
+
+ def _get_floating_ip(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_floating_ip = self.client.floating_ips.get_by_id(
+ self.module.params.get("id")
+ )
+ else:
+ self.hcloud_floating_ip = self.client.floating_ips.get_by_name(
+ self.module.params.get("name")
+ )
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_floating_ip(self):
+ self.module.fail_on_missing_params(
+ required_params=["type"]
+ )
+
+ params = {
+ "description": self.module.params.get("description"),
+ "type": self.module.params.get("type"),
+ "name": self.module.params.get("name"),
+ }
+ if self.module.params.get("home_location") is not None:
+ params["home_location"] = self.client.locations.get_by_name(
+ self.module.params.get("home_location")
+ )
+ elif self.module.params.get("server") is not None:
+ params["server"] = self.client.servers.get_by_name(
+ self.module.params.get("server")
+ )
+ else:
+ self.module.fail_json(msg="one of the following is required: home_location, server")
+
+ 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.floating_ips.create(**params)
+ self.hcloud_floating_ip = resp.floating_ip
+
+ 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()
+
+ self._mark_as_changed()
+ self._get_floating_ip()
+
+ def _update_floating_ip(self):
+ try:
+ labels = self.module.params.get("labels")
+ if labels is not None and labels != self.hcloud_floating_ip.labels:
+ if not self.module.check_mode:
+ self.hcloud_floating_ip.update(labels=labels)
+ self._mark_as_changed()
+
+ description = self.module.params.get("description")
+ if description is not None and description != self.hcloud_floating_ip.description:
+ if not self.module.check_mode:
+ self.hcloud_floating_ip.update(description=description)
+ self._mark_as_changed()
+
+ server = self.module.params.get("server")
+ if server is not None and self.hcloud_floating_ip.server is not None:
+ if self.module.params.get("force") and server != self.hcloud_floating_ip.server.name:
+ if not self.module.check_mode:
+ self.hcloud_floating_ip.assign(
+ self.client.servers.get_by_name(server)
+ )
+ self._mark_as_changed()
+ elif server != self.hcloud_floating_ip.server.name:
+ self.module.warn(
+ "Floating IP is already assigned to another server %s. You need to unassign the Floating IP or use force=yes."
+ % self.hcloud_floating_ip.server.name
+ )
+ self._mark_as_changed()
+ elif server is not None and self.hcloud_floating_ip.server is None:
+ if not self.module.check_mode:
+ self.hcloud_floating_ip.assign(
+ self.client.servers.get_by_name(server)
+ )
+ self._mark_as_changed()
+ elif server is None and self.hcloud_floating_ip.server is not None:
+ if not self.module.check_mode:
+ self.hcloud_floating_ip.unassign()
+ self._mark_as_changed()
+
+ 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()
+ self._mark_as_changed()
+
+ self._get_floating_ip()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def present_floating_ip(self):
+ self._get_floating_ip()
+ if self.hcloud_floating_ip is None:
+ self._create_floating_ip()
+ else:
+ self._update_floating_ip()
+
+ def delete_floating_ip(self):
+ try:
+ self._get_floating_ip()
+ if self.hcloud_floating_ip is not None:
+ if self.module.params.get("force") or self.hcloud_floating_ip.server is None:
+ if not self.module.check_mode:
+ self.client.floating_ips.delete(self.hcloud_floating_ip)
+ else:
+ self.module.warn(
+ "Floating IP is currently assigned to server %s. You need to unassign the Floating IP or use force=yes."
+ % self.hcloud_floating_ip.server.name
+ )
+ self._mark_as_changed()
+ self.hcloud_floating_ip = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ description={"type": "str"},
+ server={"type": "str"},
+ home_location={"type": "str"},
+ force={"type": "bool"},
+ type={"choices": ["ipv4", "ipv6"]},
+ labels={"type": "dict"},
+ delete_protection={"type": "bool"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name']],
+ mutually_exclusive=[['home_location', 'server']],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudFloatingIP.define_module()
+
+ hcloud = AnsibleHcloudFloatingIP(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_floating_ip()
+ elif state == "present":
+ hcloud.present_floating_ip()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py
new file mode 100644
index 00000000..ea335d16
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_facts.py
@@ -0,0 +1,190 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_floating_ip_info
+
+short_description: Gather infos about the Hetzner Cloud Floating IPs.
+
+description:
+ - Gather facts about your Hetzner Cloud Floating IPs.
+ - This module was called C(hcloud_floating_ip_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_floating_ip_facts).
+ Note that the M(hetzner.hcloud.hcloud_floating_ip_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_floating_ip_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Floating IP you want to get.
+ type: int
+ label_selector:
+ description:
+ - The label selector for the Floating IP you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud Floating ip infos
+ hcloud_floating_ip_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_floating_ip_info:
+ description: The Floating ip infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Floating IP
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Floating IP
+ returned: Always
+ type: str
+ sample: my-floating-ip
+ version_added: "0.1.0"
+ description:
+ description: Description of the Floating IP
+ returned: always
+ type: str
+ sample: Falkenstein DC 8
+ ip:
+ description: IP address of the Floating IP
+ returned: always
+ type: str
+ sample: 131.232.99.1
+ type:
+ description: Type of the Floating IP
+ returned: always
+ type: str
+ sample: ipv4
+ server:
+ description: Name of the server where the Floating IP is assigned to.
+ returned: always
+ type: str
+ sample: my-server
+ home_location:
+ description: Location the Floating IP was created in
+ returned: always
+ type: str
+ sample: fsn1
+ delete_protection:
+ description: True if the Floating IP is protected for deletion
+ returned: always
+ type: bool
+ version_added: "0.1.0"
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudFloatingIPInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_floating_ip_info")
+ self.hcloud_floating_ip_info = None
+
+ def _prepare_result(self):
+ 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"],
+ })
+
+ return tmp
+
+ def get_floating_ips(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_floating_ip_info = [self.client.floating_ips.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_floating_ip_info = self.client.floating_ips.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_floating_ip_info = self.client.floating_ips.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudFloatingIPInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_floating_ip_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_floating_ip_facts' module has been renamed to 'hcloud_floating_ip_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudFloatingIPInfo(module)
+
+ hcloud.get_floating_ips()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_floating_ip_facts': result['hcloud_floating_ip_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_floating_ip_info': result['hcloud_floating_ip_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py
new file mode 100644
index 00000000..ea335d16
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_floating_ip_info.py
@@ -0,0 +1,190 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_floating_ip_info
+
+short_description: Gather infos about the Hetzner Cloud Floating IPs.
+
+description:
+ - Gather facts about your Hetzner Cloud Floating IPs.
+ - This module was called C(hcloud_floating_ip_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_floating_ip_facts).
+ Note that the M(hetzner.hcloud.hcloud_floating_ip_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_floating_ip_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Floating IP you want to get.
+ type: int
+ label_selector:
+ description:
+ - The label selector for the Floating IP you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud Floating ip infos
+ hcloud_floating_ip_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_floating_ip_info:
+ description: The Floating ip infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Floating IP
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Floating IP
+ returned: Always
+ type: str
+ sample: my-floating-ip
+ version_added: "0.1.0"
+ description:
+ description: Description of the Floating IP
+ returned: always
+ type: str
+ sample: Falkenstein DC 8
+ ip:
+ description: IP address of the Floating IP
+ returned: always
+ type: str
+ sample: 131.232.99.1
+ type:
+ description: Type of the Floating IP
+ returned: always
+ type: str
+ sample: ipv4
+ server:
+ description: Name of the server where the Floating IP is assigned to.
+ returned: always
+ type: str
+ sample: my-server
+ home_location:
+ description: Location the Floating IP was created in
+ returned: always
+ type: str
+ sample: fsn1
+ delete_protection:
+ description: True if the Floating IP is protected for deletion
+ returned: always
+ type: bool
+ version_added: "0.1.0"
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudFloatingIPInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_floating_ip_info")
+ self.hcloud_floating_ip_info = None
+
+ def _prepare_result(self):
+ 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"],
+ })
+
+ return tmp
+
+ def get_floating_ips(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_floating_ip_info = [self.client.floating_ips.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_floating_ip_info = self.client.floating_ips.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_floating_ip_info = self.client.floating_ips.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudFloatingIPInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_floating_ip_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_floating_ip_facts' module has been renamed to 'hcloud_floating_ip_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudFloatingIPInfo(module)
+
+ hcloud.get_floating_ips()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_floating_ip_facts': result['hcloud_floating_ip_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_floating_ip_info': result['hcloud_floating_ip_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py
new file mode 100644
index 00000000..658c0fa1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_facts.py
@@ -0,0 +1,203 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_image_info
+
+short_description: Gather infos about your Hetzner Cloud images.
+
+
+description:
+ - Gather infos about your Hetzner Cloud images.
+ - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
+ Note that the M(hetzner.hcloud.hcloud_image_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_image_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the image you want to get.
+ type: int
+ name:
+ description:
+ - The name of the image you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the images you want to get.
+ type: str
+ type:
+ description:
+ - The label selector for the images you want to get.
+ default: system
+ choices: [ system, snapshot, backup ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud image infos
+ hcloud_image_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_image_info:
+ description: The image infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the image
+ returned: always
+ type: int
+ sample: 1937415
+ type:
+ description: Type of the image
+ returned: always
+ type: str
+ sample: system
+ status:
+ description: Status of the image
+ returned: always
+ type: str
+ sample: available
+ name:
+ description: Name of the image
+ returned: always
+ type: str
+ sample: ubuntu-18.04
+ description:
+ description: Detail description of the image
+ returned: always
+ type: str
+ sample: Ubuntu 18.04 Standard 64 bit
+ os_flavor:
+ description: OS flavor of the image
+ returned: always
+ type: str
+ sample: ubuntu
+ os_version:
+ description: OS version of the image
+ returned: always
+ type: str
+ sample: 18.04
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudImageInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_image_info")
+ self.hcloud_image_info = None
+
+ def _prepare_result(self):
+ 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),
+ "labels": image.labels,
+ })
+ return tmp
+
+ def get_images(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_image_info = [self.client.images.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_image_info = [self.client.images.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ params = {}
+ label_selector = self.module.params.get("label_selector")
+ if label_selector:
+ params["label_selector"] = label_selector
+
+ image_type = self.module.params.get("type")
+ if image_type:
+ params["type"] = image_type
+
+ self.hcloud_image_info = self.client.images.get_all(**params)
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ type={"choices": ["system", "snapshot", "backup"], "default": "system", "type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudImageInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_image_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_image_facts' module has been renamed to 'hcloud_image_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudImageInfo(module)
+ hcloud.get_images()
+ result = hcloud.get_result()
+
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_imagen_facts': result['hcloud_image_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_image_info': result['hcloud_image_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py
new file mode 100644
index 00000000..658c0fa1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_image_info.py
@@ -0,0 +1,203 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_image_info
+
+short_description: Gather infos about your Hetzner Cloud images.
+
+
+description:
+ - Gather infos about your Hetzner Cloud images.
+ - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
+ Note that the M(hetzner.hcloud.hcloud_image_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_image_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the image you want to get.
+ type: int
+ name:
+ description:
+ - The name of the image you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the images you want to get.
+ type: str
+ type:
+ description:
+ - The label selector for the images you want to get.
+ default: system
+ choices: [ system, snapshot, backup ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud image infos
+ hcloud_image_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_image_info:
+ description: The image infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the image
+ returned: always
+ type: int
+ sample: 1937415
+ type:
+ description: Type of the image
+ returned: always
+ type: str
+ sample: system
+ status:
+ description: Status of the image
+ returned: always
+ type: str
+ sample: available
+ name:
+ description: Name of the image
+ returned: always
+ type: str
+ sample: ubuntu-18.04
+ description:
+ description: Detail description of the image
+ returned: always
+ type: str
+ sample: Ubuntu 18.04 Standard 64 bit
+ os_flavor:
+ description: OS flavor of the image
+ returned: always
+ type: str
+ sample: ubuntu
+ os_version:
+ description: OS version of the image
+ returned: always
+ type: str
+ sample: 18.04
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudImageInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_image_info")
+ self.hcloud_image_info = None
+
+ def _prepare_result(self):
+ 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),
+ "labels": image.labels,
+ })
+ return tmp
+
+ def get_images(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_image_info = [self.client.images.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_image_info = [self.client.images.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ params = {}
+ label_selector = self.module.params.get("label_selector")
+ if label_selector:
+ params["label_selector"] = label_selector
+
+ image_type = self.module.params.get("type")
+ if image_type:
+ params["type"] = image_type
+
+ self.hcloud_image_info = self.client.images.get_all(**params)
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ type={"choices": ["system", "snapshot", "backup"], "default": "system", "type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudImageInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_image_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_image_facts' module has been renamed to 'hcloud_image_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudImageInfo(module)
+ hcloud.get_images()
+ result = hcloud.get_result()
+
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_imagen_facts': result['hcloud_image_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_image_info': result['hcloud_image_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py
new file mode 100644
index 00000000..6e080545
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer.py
@@ -0,0 +1,323 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_load_balancer
+
+short_description: Create and manage cloud Load Balancers on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage cloud Load Balancers on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+version_added: 0.1.0
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud Load Balancer to manage.
+ - Only required if no Load Balancer I(name) is given
+ type: int
+ name:
+ description:
+ - The Name of the Hetzner Cloud Load Balancer to manage.
+ - Only required if no Load Balancer I(id) is given or a Load Balancer does not exists.
+ type: str
+ load_balancer_type:
+ description:
+ - The Load Balancer Type of the Hetzner Cloud Load Balancer to manage.
+ - Required if Load Balancer does not exists.
+ type: str
+ location:
+ description:
+ - Location of Load Balancer.
+ - Required if no I(network_zone) is given and Load Balancer does not exists.
+ type: str
+ network_zone:
+ description:
+ - Network Zone of Load Balancer.
+ - Required of no I(location) is given and Load Balancer does not exists.
+ type: str
+ labels:
+ description:
+ - User-defined labels (key-value pairs).
+ type: dict
+ disable_public_interface:
+ description:
+ - Disables the public interface.
+ type: bool
+ default: False
+ delete_protection:
+ description:
+ - Protect the Load Balancer for deletion.
+ type: bool
+ state:
+ description:
+ - State of the Load Balancer.
+ default: present
+ choices: [ absent, present ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+requirements:
+ - hcloud-python >= 1.8.0
+'''
+
+EXAMPLES = """
+- name: Create a basic Load Balancer
+ hcloud_load_balancer:
+ name: my-Load Balancer
+ load_balancer_type: lb11
+ location: fsn1
+ state: present
+
+- name: Ensure the Load Balancer is absent (remove if needed)
+ hcloud_load_balancer:
+ name: my-Load Balancer
+ state: absent
+
+"""
+
+RETURN = """
+hcloud_load_balancer:
+ description: The Load Balancer instance
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Load Balancer
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Load Balancer
+ returned: always
+ type: str
+ sample: my-Load-Balancer
+ status:
+ description: Status of the Load Balancer
+ returned: always
+ type: str
+ sample: running
+ load_balancer_type:
+ description: Name of the Load Balancer type of the Load Balancer
+ returned: always
+ type: str
+ sample: cx11
+ ipv4_address:
+ description: Public IPv4 address of the Load Balancer
+ returned: always
+ type: str
+ sample: 116.203.104.109
+ ipv6_address:
+ description: Public IPv6 address of the Load Balancer
+ returned: always
+ type: str
+ sample: 2a01:4f8:1c1c:c140::1
+ location:
+ description: Name of the location of the Load Balancer
+ returned: always
+ type: str
+ sample: fsn1
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if Load Balancer is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ disable_public_interface:
+ description: True if Load Balancer public interface is disabled
+ type: bool
+ returned: always
+ sample: false
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud.load_balancers.domain import LoadBalancer
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudLoadBalancer(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_load_balancer")
+ self.hcloud_load_balancer = 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),
+ "location": to_native(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,
+ }
+
+ def _get_load_balancer(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_id(
+ self.module.params.get("id")
+ )
+ else:
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
+ self.module.params.get("name")
+ )
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_load_balancer(self):
+
+ self.module.fail_on_missing_params(
+ required_params=["name", "load_balancer_type"]
+ )
+
+ params = {
+ "name": self.module.params.get("name"),
+ "load_balancer_type": self.client.load_balancer_types.get_by_name(
+ self.module.params.get("load_balancer_type")
+ ),
+ "labels": self.module.params.get("labels"),
+ }
+
+ if self.module.params.get("location") is None and self.module.params.get("network_zone") is None:
+ self.module.fail_json(msg="one of the following is required: location, network_zone")
+ elif self.module.params.get("location") is not None and self.module.params.get("network_zone") is None:
+ params["location"] = self.client.locations.get_by_name(
+ self.module.params.get("location")
+ )
+ elif self.module.params.get("location") is None and self.module.params.get("network_zone") is not None:
+ params["network_zone"] = self.module.params.get("network_zone")
+
+ if not self.module.check_mode:
+ resp = self.client.load_balancers.create(**params)
+ resp.action.wait_until_finished(max_retries=1000)
+
+ 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()
+
+ self._mark_as_changed()
+ self._get_load_balancer()
+
+ def _update_load_balancer(self):
+ try:
+ labels = self.module.params.get("labels")
+ if labels is not None and labels != self.hcloud_load_balancer.labels:
+ if not self.module.check_mode:
+ self.hcloud_load_balancer.update(labels=labels)
+ self._mark_as_changed()
+
+ 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()
+ self._mark_as_changed()
+ self._get_load_balancer()
+
+ disable_public_interface = self.module.params.get("disable_public_interface")
+ if disable_public_interface is not None and disable_public_interface != (not self.hcloud_load_balancer.public_net.enabled):
+ if not self.module.check_mode:
+ if disable_public_interface is True:
+ self.hcloud_load_balancer.disable_public_interface().wait_until_finished()
+ else:
+ self.hcloud_load_balancer.enable_public_interface().wait_until_finished()
+ self._mark_as_changed()
+
+ load_balancer_type = self.module.params.get("load_balancer_type")
+ if load_balancer_type is not None and self.hcloud_load_balancer.load_balancer_type.name != load_balancer_type:
+ new_load_balancer_type = self.client.load_balancer_types.get_by_name(load_balancer_type)
+ 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(
+ load_balancer_type=new_load_balancer_type,
+ ).wait_until_finished(max_retries=1000)
+
+ self._mark_as_changed()
+ self._get_load_balancer()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def present_load_balancer(self):
+ self._get_load_balancer()
+ if self.hcloud_load_balancer is None:
+ self._create_load_balancer()
+ else:
+ self._update_load_balancer()
+
+ def delete_load_balancer(self):
+ try:
+ self._get_load_balancer()
+ if self.hcloud_load_balancer is not None:
+ if not self.module.check_mode:
+ self.client.load_balancers.delete(self.hcloud_load_balancer)
+ self._mark_as_changed()
+ self.hcloud_load_balancer = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ load_balancer_type={"type": "str"},
+ location={"type": "str"},
+ network_zone={"type": "str"},
+ labels={"type": "dict"},
+ delete_protection={"type": "bool"},
+ disable_public_interface={"type": "bool", "default": False},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name']],
+ mutually_exclusive=[["location", "network_zone"]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLoadBalancer.define_module()
+
+ hcloud = AnsibleHcloudLoadBalancer(module)
+ state = module.params.get("state")
+ if state == "absent":
+ hcloud.delete_load_balancer()
+ elif state == "present":
+ hcloud.present_load_balancer()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py
new file mode 100644
index 00000000..b9463f50
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_info.py
@@ -0,0 +1,403 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_load_balancer_info
+
+short_description: Gather infos about your Hetzner Cloud Load Balancers.
+
+
+description:
+ - Gather infos about your Hetzner Cloud Load Balancers..
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Load Balancers you want to get.
+ type: int
+ name:
+ description:
+ - The name of the Load Balancers you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the Load Balancers you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud load_balancer infos
+ hcloud_load_balancer_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_load_balancer_info:
+ description: The load_balancer infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Load Balancer
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Load Balancer
+ returned: always
+ type: str
+ sample: my-Load-Balancer
+ status:
+ description: Status of the Load Balancer
+ returned: always
+ type: str
+ sample: running
+ load_balancer_type:
+ description: Name of the Load Balancer type of the Load Balancer
+ returned: always
+ type: str
+ sample: cx11
+ ipv4_address:
+ description: Public IPv4 address of the Load Balancer
+ returned: always
+ type: str
+ sample: 116.203.104.109
+ ipv6_address:
+ description: Public IPv6 address of the Load Balancer
+ returned: always
+ type: str
+ sample: 2a01:4f8:1c1c:c140::1
+ location:
+ description: Name of the location of the Load Balancer
+ returned: always
+ type: str
+ sample: fsn1
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if Load Balancer is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ disable_public_interface:
+ description: True if Load Balancer public interface is disabled
+ type: bool
+ returned: always
+ sample: false
+ targets:
+ description: The targets of the Load Balancer
+ returned: always
+ type: complex
+ contains:
+ type:
+ description: Type of the Load Balancer Target
+ type: str
+ returned: always
+ sample: server
+ load_balancer:
+ description: Name of the Load Balancer
+ type: str
+ returned: always
+ sample: my-LoadBalancer
+ server:
+ description: Name of the Server
+ type: str
+ returned: if I(type) is server
+ sample: my-server
+ label_selector:
+ description: Label Selector
+ type: str
+ returned: if I(type) is label_selector
+ sample: application=backend
+ ip:
+ description: IP of the dedicated server
+ type: str
+ returned: if I(type) is ip
+ sample: 127.0.0.1
+ use_private_ip:
+ description:
+ - Route the traffic over the private IP of the Load Balancer through a Hetzner Cloud Network.
+ - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.hcloud.hcloud_load_balancer_network)
+ type: bool
+ sample: true
+ returned: always
+ services:
+ description: all services from this Load Balancer
+ returned: Always
+ type: complex
+ contains:
+ listen_port:
+ description: The port the service listens on, i.e. the port users can connect to.
+ returned: always
+ type: int
+ sample: 443
+ protocol:
+ description: Protocol of the service
+ returned: always
+ type: str
+ sample: http
+ destination_port:
+ description:
+ - The port traffic is forwarded to, i.e. the port the targets are listening and accepting connections on.
+ returned: always
+ type: int
+ sample: 80
+ proxyprotocol:
+ description:
+ - Enable the PROXY protocol.
+ returned: always
+ type: bool
+ sample: false
+ http:
+ description: Configuration for HTTP and HTTPS services
+ returned: always
+ type: complex
+ contains:
+ cookie_name:
+ description: Name of the cookie which will be set when you enable sticky sessions
+ returned: always
+ type: str
+ sample: HCLBSTICKY
+ cookie_lifetime:
+ description: Lifetime of the cookie which will be set when you enable sticky sessions, in seconds
+ returned: always
+ type: int
+ sample: 3600
+ certificates:
+ description: List of Names or IDs of certificates
+ returned: always
+ type: list
+ elements: str
+ sticky_sessions:
+ description: Enable or disable sticky_sessions
+ returned: always
+ type: bool
+ sample: true
+ redirect_http:
+ description: Redirect Traffic from Port 80 to Port 443, only available if protocol is https
+ returned: always
+ type: bool
+ sample: false
+ health_check:
+ description: Configuration for health checks
+ returned: always
+ type: complex
+ contains:
+ protocol:
+ description: Protocol the health checks will be performed over
+ returned: always
+ type: str
+ sample: http
+ port:
+ description: Port the health check will be performed on
+ returned: always
+ type: int
+ sample: 80
+ interval:
+ description: Interval of health checks, in seconds
+ returned: always
+ type: int
+ sample: 15
+ timeout:
+ description: Timeout of health checks, in seconds
+ returned: always
+ type: int
+ sample: 10
+ retries:
+ description: Number of retries until a target is marked as unhealthy
+ returned: always
+ type: int
+ sample: 3
+ http:
+ description: Additional Configuration of health checks with protocol http/https
+ returned: always
+ type: complex
+ contains:
+ domain:
+ description: Domain we will set within the HTTP HOST header
+ returned: always
+ type: str
+ sample: example.com
+ path:
+ description: Path we will try to access
+ returned: always
+ type: str
+ sample: /
+ response:
+ description: Response we expect, if response is not within the health check response the target is unhealthy
+ returned: always
+ type: str
+ status_codes:
+ description: List of HTTP status codes we expect to get when we perform the health check.
+ returned: always
+ type: list
+ elements: str
+ sample: ["2??","3??"]
+ tls:
+ description: Verify the TLS certificate, only available if health check protocol is https
+ returned: always
+ type: bool
+ sample: false
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudLoadBalancerInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_load_balancer_info")
+ self.hcloud_load_balancer_info = None
+
+ def _prepare_result(self):
+ 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
+ })
+ return tmp
+
+ @staticmethod
+ def _prepare_service_result(service):
+ http = None
+ if service.protocol != "tcp":
+ http = {
+ "cookie_name": to_native(service.http.cookie_name),
+ "cookie_lifetime": service.http.cookie_name,
+ "redirect_http": service.http.redirect_http,
+ "sticky_sessions": service.http.sticky_sessions,
+ "certificates": [to_native(certificate.name) for certificate in
+ service.http.certificates],
+ }
+ health_check = {
+ "protocol": to_native(service.health_check.protocol),
+ "port": service.health_check.port,
+ "interval": service.health_check.interval,
+ "timeout": service.health_check.timeout,
+ "retries": service.health_check.retries,
+ }
+ 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],
+ "tls": service.health_check.http.tls,
+ }
+ return {
+ "protocol": to_native(service.protocol),
+ "listen_port": service.listen_port,
+ "destination_port": service.destination_port,
+ "proxyprotocol": service.proxyprotocol,
+ "http": http,
+ "health_check": health_check,
+ }
+
+ @staticmethod
+ def _prepare_target_result(target):
+ result = {
+ "type": to_native(target.type),
+ "use_private_ip": target.use_private_ip
+ }
+ if target.type == "server":
+ result["server"] = to_native(target.server.name)
+ elif target.type == "label_selector":
+ result["label_selector"] = to_native(target.label_selector.selector)
+ elif target.type == "ip":
+ result["ip"] = to_native(target.ip.ip)
+ return result
+
+ def get_load_balancers(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_load_balancer_info = [self.client.load_balancers.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_load_balancer_info = [self.client.load_balancers.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ params = {}
+ label_selector = self.module.params.get("label_selector")
+ if label_selector:
+ params["label_selector"] = label_selector
+
+ self.hcloud_load_balancer_info = self.client.load_balancers.get_all(**params)
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLoadBalancerInfo.define_module()
+
+ hcloud = AnsibleHcloudLoadBalancerInfo(module)
+ hcloud.get_load_balancers()
+ result = hcloud.get_result()
+
+ ansible_info = {
+ 'hcloud_load_balancer_info': result['hcloud_load_balancer_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py
new file mode 100644
index 00000000..542c3e86
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_network.py
@@ -0,0 +1,201 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_load_balancer_network
+
+short_description: Manage the relationship between Hetzner Cloud Networks and Load Balancers
+
+
+description:
+ - Create and delete the relationship Hetzner Cloud Networks and Load Balancers
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+version_added: 0.1.0
+options:
+ network:
+ description:
+ - The name of the Hetzner Cloud Networks.
+ type: str
+ required: true
+ load_balancer:
+ description:
+ - The name of the Hetzner Cloud Load Balancer.
+ type: str
+ required: true
+ ip:
+ description:
+ - The IP the Load Balancer should have.
+ type: str
+ state:
+ description:
+ - State of the load_balancer_network.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.8.1
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic Load Balancer network
+ hcloud_load_balancer_network:
+ network: my-network
+ load_balancer: my-LoadBalancer
+ state: present
+
+- name: Create a Load Balancer network and specify the ip address
+ hcloud_load_balancer_network:
+ network: my-network
+ load_balancer: my-LoadBalancer
+ ip: 10.0.0.1
+ state: present
+
+- name: Ensure the Load Balancer network is absent (remove if needed)
+ hcloud_load_balancer_network:
+ network: my-network
+ load_balancer: my-LoadBalancer
+ state: absent
+"""
+
+RETURN = """
+hcloud_load_balancer_network:
+ description: The relationship between a Load Balancer and a network
+ returned: always
+ type: complex
+ contains:
+ network:
+ description: Name of the Network
+ type: str
+ returned: always
+ sample: my-network
+ load_balancer:
+ description: Name of the Load Balancer
+ type: str
+ returned: always
+ sample: my-LoadBalancer
+ ip:
+ description: IP of the Load Balancer within the Network ip range
+ type: str
+ returned: always
+ sample: 10.0.0.8
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+ NetworkSubnet = None
+
+
+class AnsibleHcloudLoadBalancerNetwork(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_load_balancer_network")
+ self.hcloud_network = None
+ self.hcloud_load_balancer = None
+ self.hcloud_load_balancer_network = None
+
+ 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),
+ }
+
+ def _get_load_balancer_and_network(self):
+ try:
+ self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_name(self.module.params.get("load_balancer"))
+ self.hcloud_load_balancer_network = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _get_load_balancer_network(self):
+ for privateNet in self.hcloud_load_balancer.private_net:
+ if privateNet.network.id == self.hcloud_network.id:
+ self.hcloud_load_balancer_network = privateNet
+
+ def _create_load_balancer_network(self):
+ params = {
+ "network": self.hcloud_network
+ }
+
+ if self.module.params.get("ip") is not None:
+ params["ip"] = self.module.params.get("ip")
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_load_balancer.attach_to_network(**params).wait_until_finished()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ self._mark_as_changed()
+ self._get_load_balancer_and_network()
+ self._get_load_balancer_network()
+
+ def present_load_balancer_network(self):
+ self._get_load_balancer_and_network()
+ self._get_load_balancer_network()
+ if self.hcloud_load_balancer_network is None:
+ self._create_load_balancer_network()
+
+ def delete_load_balancer_network(self):
+ self._get_load_balancer_and_network()
+ self._get_load_balancer_network()
+ if self.hcloud_load_balancer_network is not None and self.hcloud_load_balancer is not None:
+ if not self.module.check_mode:
+ self.hcloud_load_balancer.detach_from_network(
+ self.hcloud_load_balancer_network.network).wait_until_finished()
+ self._mark_as_changed()
+ self.hcloud_load_balancer_network = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ network={"type": "str", "required": True},
+ load_balancer={"type": "str", "required": True},
+ ip={"type": "str"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLoadBalancerNetwork.define_module()
+
+ hcloud = AnsibleHcloudLoadBalancerNetwork(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_load_balancer_network()
+ elif state == "present":
+ hcloud.present_load_balancer_network()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py
new file mode 100644
index 00000000..4ef46346
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_service.py
@@ -0,0 +1,613 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_load_balancer_service
+
+short_description: Create and manage the services of cloud Load Balancers on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage the services of cloud Load Balancers on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+version_added: 0.1.0
+options:
+ load_balancer:
+ description:
+ - The Name of the Hetzner Cloud Load Balancer the service belongs to
+ type: str
+ required: true
+ listen_port:
+ description:
+ - The port the service listens on, i.e. the port users can connect to.
+ type: int
+ required: true
+ destination_port:
+ description:
+ - The port traffic is forwarded to, i.e. the port the targets are listening and accepting connections on.
+ - Required if services does not exists and protocol is tcp.
+ type: int
+ protocol:
+ description:
+ - Protocol of the service.
+ - Required if Load Balancer does not exists.
+ type: str
+ choices: [ http, https, tcp ]
+ proxyprotocol:
+ description:
+ - Enable the PROXY protocol.
+ type: bool
+ default: False
+ http:
+ description:
+ - Configuration for HTTP and HTTPS services
+ type: dict
+ suboptions:
+ cookie_name:
+ description:
+ - Name of the cookie which will be set when you enable sticky sessions
+ type: str
+ cookie_lifetime:
+ description:
+ - Lifetime of the cookie which will be set when you enable sticky sessions, in seconds
+ type: int
+ certificates:
+ description:
+ - List of Names or IDs of certificates
+ type: list
+ elements: str
+ sticky_sessions:
+ description:
+ - Enable or disable sticky_sessions
+ type: bool
+ default: False
+ redirect_http:
+ description:
+ - Redirect Traffic from Port 80 to Port 443, only available if protocol is https
+ type: bool
+ default: False
+ health_check:
+ description:
+ - Configuration for health checks
+ type: dict
+ suboptions:
+ protocol:
+ description:
+ - Protocol the health checks will be performed over
+ type: str
+ choices: [ http, https, tcp ]
+ port:
+ description:
+ - Port the health check will be performed on
+ type: int
+ interval:
+ description:
+ - Interval of health checks, in seconds
+ type: int
+ timeout:
+ description:
+ - Timeout of health checks, in seconds
+ type: int
+ retries:
+ description:
+ - Number of retries until a target is marked as unhealthy
+ type: int
+ http:
+ description:
+ - Additional Configuration of health checks with protocol http/https
+ type: dict
+ suboptions:
+ domain:
+ description:
+ - Domain we will set within the HTTP HOST header
+ type: str
+ path:
+ description:
+ - Path we will try to access
+ type: str
+ response:
+ description:
+ - Response we expect, if response is not within the health check response the target is unhealthy
+ type: str
+ status_codes:
+ description:
+ - List of HTTP status codes we expect to get when we perform the health check.
+ type: list
+ elements: str
+ tls:
+ description:
+ - Verify the TLS certificate, only available if health check protocol is https
+ type: bool
+ default: False
+ state:
+ description:
+ - State of the Load Balancer.
+ default: present
+ choices: [ absent, present ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+requirements:
+ - hcloud-python >= 1.8.1
+'''
+
+EXAMPLES = """
+- name: Create a basic Load Balancer service with Port 80
+ hcloud_load_balancer_service:
+ load_balancer: my-load-balancer
+ protocol: http
+ listen_port: 80
+ state: present
+
+- name: Ensure the Load Balancer is absent (remove if needed)
+ hcloud_load_balancer_service:
+ load_balancer: my-Load Balancer
+ protocol: http
+ listen_port: 80
+ state: absent
+"""
+
+RETURN = """
+hcloud_load_balancer_service:
+ description: The Load Balancer service instance
+ returned: Always
+ type: complex
+ contains:
+ load_balancer:
+ description: The name of the Load Balancer where the service belongs to
+ returned: always
+ type: str
+ sample: my-load-balancer
+ listen_port:
+ description: The port the service listens on, i.e. the port users can connect to.
+ returned: always
+ type: int
+ sample: 443
+ protocol:
+ description: Protocol of the service
+ returned: always
+ type: str
+ sample: http
+ destination_port:
+ description:
+ - The port traffic is forwarded to, i.e. the port the targets are listening and accepting connections on.
+ returned: always
+ type: int
+ sample: 80
+ proxyprotocol:
+ description:
+ - Enable the PROXY protocol.
+ returned: always
+ type: bool
+ sample: false
+ http:
+ description: Configuration for HTTP and HTTPS services
+ returned: always
+ type: complex
+ contains:
+ cookie_name:
+ description: Name of the cookie which will be set when you enable sticky sessions
+ returned: always
+ type: str
+ sample: HCLBSTICKY
+ cookie_lifetime:
+ description: Lifetime of the cookie which will be set when you enable sticky sessions, in seconds
+ returned: always
+ type: int
+ sample: 3600
+ certificates:
+ description: List of Names or IDs of certificates
+ returned: always
+ type: list
+ elements: str
+ sticky_sessions:
+ description: Enable or disable sticky_sessions
+ returned: always
+ type: bool
+ sample: true
+ redirect_http:
+ description: Redirect Traffic from Port 80 to Port 443, only available if protocol is https
+ returned: always
+ type: bool
+ sample: false
+ health_check:
+ description: Configuration for health checks
+ returned: always
+ type: complex
+ contains:
+ protocol:
+ description: Protocol the health checks will be performed over
+ returned: always
+ type: str
+ sample: http
+ port:
+ description: Port the health check will be performed on
+ returned: always
+ type: int
+ sample: 80
+ interval:
+ description: Interval of health checks, in seconds
+ returned: always
+ type: int
+ sample: 15
+ timeout:
+ description: Timeout of health checks, in seconds
+ returned: always
+ type: int
+ sample: 10
+ retries:
+ description: Number of retries until a target is marked as unhealthy
+ returned: always
+ type: int
+ sample: 3
+ http:
+ description: Additional Configuration of health checks with protocol http/https
+ returned: always
+ type: complex
+ contains:
+ domain:
+ description: Domain we will set within the HTTP HOST header
+ returned: always
+ type: str
+ sample: example.com
+ path:
+ description: Path we will try to access
+ returned: always
+ type: str
+ sample: /
+ response:
+ description: Response we expect, if response is not within the health check response the target is unhealthy
+ returned: always
+ type: str
+ status_codes:
+ description: List of HTTP status codes we expect to get when we perform the health check.
+ returned: always
+ type: list
+ elements: str
+ sample: ["2??","3??"]
+ tls:
+ description: Verify the TLS certificate, only available if health check protocol is https
+ returned: always
+ type: bool
+ sample: false
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud.load_balancers.domain import LoadBalancer, LoadBalancerService, LoadBalancerServiceHttp, \
+ LoadBalancerServiceHealthCheck, LoadBalancerServiceHealthCheckHttp
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudLoadBalancerService(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_load_balancer_service")
+ self.hcloud_load_balancer = None
+ self.hcloud_load_balancer_service = None
+
+ def _prepare_result(self):
+ 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,
+ "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],
+ }
+ health_check = {
+ "protocol": to_native(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,
+ "retries": self.hcloud_load_balancer_service.health_check.retries,
+ }
+ 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),
+ "certificates": [to_native(status_code) for status_code in
+ 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),
+ "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,
+ "http": http,
+ "health_check": health_check,
+ }
+
+ def _get_load_balancer(self):
+ try:
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_name(
+ self.module.params.get("load_balancer")
+ )
+ self._get_load_balancer_service()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_load_balancer_service(self):
+
+ self.module.fail_on_missing_params(
+ required_params=["protocol"]
+ )
+ if self.module.params.get("protocol") == "tcp":
+ self.module.fail_on_missing_params(
+ required_params=["destination_port"]
+ )
+
+ params = {
+ "protocol": self.module.params.get("protocol"),
+ "listen_port": self.module.params.get("listen_port"),
+ "proxyprotocol": self.module.params.get("proxyprotocol")
+ }
+
+ if self.module.params.get("destination_port"):
+ params["destination_port"] = self.module.params.get("destination_port")
+
+ if self.module.params.get("http"):
+ params["http"] = self.__get_service_http(http_arg=self.module.params.get("http"))
+
+ if self.module.params.get("health_check"):
+ params["health_check"] = self.__get_service_health_checks(
+ health_check=self.module.params.get("health_check"))
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_load_balancer.add_service(LoadBalancerService(**params)).wait_until_finished(
+ max_retries=1000)
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+ self._mark_as_changed()
+ self._get_load_balancer()
+ self._get_load_balancer_service()
+
+ def __get_service_http(self, http_arg):
+ service_http = LoadBalancerServiceHttp(certificates=[])
+ if http_arg.get("cookie_name") is not None:
+ service_http.cookie_name = http_arg.get("cookie_name")
+ if http_arg.get("cookie_lifetime") is not None:
+ service_http.cookie_lifetime = http_arg.get("cookie_lifetime")
+ if http_arg.get("sticky_sessions") is not None:
+ service_http.sticky_sessions = http_arg.get("sticky_sessions")
+ if http_arg.get("redirect_http") is not None:
+ service_http.redirect_http = http_arg.get("redirect_http")
+ if http_arg.get("certificates") is not None:
+ certificates = http_arg.get("certificates")
+ if certificates is not None:
+ for certificate in certificates:
+ hcloud_cert = None
+ try:
+ try:
+ hcloud_cert = self.client.certificates.get_by_name(
+ certificate
+ )
+ except APIException:
+ hcloud_cert = self.client.certificates.get_by_id(
+ certificate
+ )
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+ service_http.certificates.append(hcloud_cert)
+
+ return service_http
+
+ def __get_service_health_checks(self, health_check):
+ service_health_check = LoadBalancerServiceHealthCheck()
+ if health_check.get("protocol") is not None:
+ service_health_check.protocol = health_check.get("protocol")
+ if health_check.get("port") is not None:
+ service_health_check.port = health_check.get("port")
+ if health_check.get("interval") is not None:
+ service_health_check.interval = health_check.get("interval")
+ if health_check.get("timeout") is not None:
+ service_health_check.timeout = health_check.get("timeout")
+ if health_check.get("retries") is not None:
+ service_health_check.retries = health_check.get("retries")
+ if health_check.get("http") is not None:
+ health_check_http = health_check.get("http")
+ service_health_check.http = LoadBalancerServiceHealthCheckHttp()
+ if health_check_http.get("domain") is not None:
+ service_health_check.http.domain = health_check_http.get("domain")
+ if health_check_http.get("path") is not None:
+ service_health_check.http.path = health_check_http.get("path")
+ if health_check_http.get("response") is not None:
+ service_health_check.http.response = health_check_http.get("response")
+ if health_check_http.get("status_codes") is not None:
+ service_health_check.http.status_codes = health_check_http.get("status_codes")
+ if health_check_http.get("tls") is not None:
+ service_health_check.http.tls = health_check_http.get("tls")
+
+ return service_health_check
+
+ def _update_load_balancer_service(self):
+ changed = False
+ try:
+ params = {
+ "listen_port": self.module.params.get("listen_port"),
+ }
+
+ if self.module.params.get("destination_port") is not None:
+ if self.hcloud_load_balancer_service.destination_port != self.module.params.get("destination_port"):
+ params["destination_port"] = self.module.params.get("destination_port")
+ changed = True
+
+ if self.module.params.get("protocol") is not None:
+ if self.hcloud_load_balancer_service.protocol != self.module.params.get("protocol"):
+ params["protocol"] = self.module.params.get("protocol")
+ changed = True
+
+ if self.module.params.get("proxyprotocol") is not None:
+ if self.hcloud_load_balancer_service.proxyprotocol != self.module.params.get("proxyprotocol"):
+ params["proxyprotocol"] = self.module.params.get("proxyprotocol")
+ changed = True
+
+ if self.module.params.get("http") is not None:
+ params["http"] = self.__get_service_http(http_arg=self.module.params.get("http"))
+ changed = True
+
+ if self.module.params.get("health_check") is not None:
+ params["health_check"] = self.__get_service_health_checks(
+ health_check=self.module.params.get("health_check"))
+ changed = True
+
+ if not self.module.check_mode:
+ self.hcloud_load_balancer.update_service(LoadBalancerService(**params)).wait_until_finished(
+ max_retries=1000)
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+ self._get_load_balancer()
+
+ if changed:
+ self._mark_as_changed()
+
+ def _get_load_balancer_service(self):
+ for service in self.hcloud_load_balancer.services:
+ if self.module.params.get("listen_port") == service.listen_port:
+ self.hcloud_load_balancer_service = service
+
+ def present_load_balancer_service(self):
+ self._get_load_balancer()
+ if self.hcloud_load_balancer_service is None:
+ self._create_load_balancer_service()
+ else:
+ self._update_load_balancer_service()
+
+ def delete_load_balancer_service(self):
+ try:
+ self._get_load_balancer()
+ if self.hcloud_load_balancer_service is not None:
+ if not self.module.check_mode:
+ self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service).wait_until_finished(
+ max_retries=1000)
+ self._mark_as_changed()
+ self.hcloud_load_balancer_service = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ load_balancer={"type": "str", "required": True},
+ listen_port={"type": "int", "required": True},
+ destination_port={"type": "int"},
+ protocol={
+ "type": "str",
+ "choices": ["http", "https", "tcp"],
+ },
+ proxyprotocol={"type": "bool", "default": False},
+ http={
+ "type": "dict",
+ "options": dict(
+ cookie_name={
+ "type": "str"
+ },
+ cookie_lifetime={
+ "type": "int"
+ },
+ sticky_sessions={
+ "type": "bool",
+ "default": False
+ },
+ redirect_http={
+ "type": "bool",
+ "default": False
+ },
+ certificates={
+ "type": "list",
+ "elements": "str"
+ },
+
+ )
+ },
+ health_check={
+ "type": "dict",
+ "options": dict(
+ protocol={
+ "type": "str",
+ "choices": ["http", "https", "tcp"],
+ },
+ port={
+ "type": "int"
+ },
+ interval={
+ "type": "int"
+ },
+ timeout={
+ "type": "int"
+ },
+ retries={
+ "type": "int"
+ },
+ http={
+ "type": "dict",
+ "options": dict(
+ domain={
+ "type": "str"
+ },
+ path={
+ "type": "str"
+ },
+ response={
+ "type": "str"
+ },
+ status_codes={
+ "type": "list",
+ "elements": "str"
+ },
+ tls={
+ "type": "bool",
+ "default": False
+ },
+ )
+ }
+ )
+
+ },
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLoadBalancerService.define_module()
+
+ hcloud = AnsibleHcloudLoadBalancerService(module)
+ state = module.params.get("state")
+ if state == "absent":
+ hcloud.delete_load_balancer_service()
+ elif state == "present":
+ hcloud.present_load_balancer_service()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py
new file mode 100644
index 00000000..e1afde8d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_target.py
@@ -0,0 +1,310 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_load_balancer_target
+
+short_description: Manage Hetzner Cloud Load Balancer targets
+
+
+description:
+ - Create and delete Hetzner Cloud Load Balancer targets
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+version_added: 0.1.0
+options:
+ type:
+ description:
+ - The type of the target.
+ type: str
+ choices: [ server, label_selector, ip ]
+ required: true
+ load_balancer:
+ description:
+ - The name of the Hetzner Cloud Load Balancer.
+ type: str
+ required: true
+ server:
+ description:
+ - The name of the Hetzner Cloud Server.
+ - Required if I(type) is server
+ type: str
+ label_selector:
+ description:
+ - A Label Selector that will be used to determine the targets dynamically
+ - Required if I(type) is label_selector
+ type: str
+ ip:
+ description:
+ - An IP from a Hetzner Dedicated Server, needs to belongs to the same user as the project.
+ - Required if I(type) is ip
+ type: str
+ use_private_ip:
+ description:
+ - Route the traffic over the private IP of the Load Balancer through a Hetzner Cloud Network.
+ - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.hcloud.hcloud_load_balancer_network)
+ type: bool
+ default: False
+ state:
+ description:
+ - State of the load_balancer_network.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.8.1
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a server Load Balancer target
+ hcloud_load_balancer_target:
+ type: server
+ load_balancer: my-LoadBalancer
+ server: my-server
+ state: present
+
+- name: Create a label_selector Load Balancer target
+ hcloud_load_balancer_target:
+ type: server
+ load_balancer: my-LoadBalancer
+ label_selector: application=backend
+ state: present
+
+- name: Create an IP Load Balancer target
+ hcloud_load_balancer_target:
+ type: server
+ load_balancer: my-LoadBalancer
+ ip: 127.0.0.1
+ state: present
+
+- name: Ensure the Load Balancer target is absent (remove if needed)
+ hcloud_load_balancer_target:
+ type: server
+ load_balancer: my-LoadBalancer
+ server: my-server
+ state: absent
+"""
+
+RETURN = """
+hcloud_load_balancer_target:
+ description: The relationship between a Load Balancer and a network
+ returned: always
+ type: complex
+ contains:
+ type:
+ description: Type of the Load Balancer Target
+ type: str
+ returned: always
+ sample: server
+ load_balancer:
+ description: Name of the Load Balancer
+ type: str
+ returned: always
+ sample: my-LoadBalancer
+ server:
+ description: Name of the Server
+ type: str
+ returned: if I(type) is server
+ sample: my-server
+ label_selector:
+ description: Label Selector
+ type: str
+ returned: if I(type) is label_selector
+ sample: application=backend
+ ip:
+ description: IP of the dedicated server
+ type: str
+ returned: if I(type) is ip
+ sample: 127.0.0.1
+ use_private_ip:
+ description:
+ - Route the traffic over the private IP of the Load Balancer through a Hetzner Cloud Network.
+ - Load Balancer needs to be attached to a network. See M(hetzner.hcloud.hcloud.hcloud_load_balancer_network)
+ type: bool
+ sample: true
+ returned: always
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+ from hcloud.load_balancers.domain import LoadBalancerTarget, LoadBalancerTargetLabelSelector, LoadBalancerTargetIP
+except ImportError:
+ APIException = None
+ LoadBalancerTarget = None
+ LoadBalancerTargetLabelSelector = None
+ LoadBalancerTargetIP = None
+
+
+class AnsibleHcloudLoadBalancerTarget(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_load_balancer_target")
+ self.hcloud_load_balancer = None
+ self.hcloud_load_balancer_target = None
+ self.hcloud_server = None
+
+ def _prepare_result(self):
+ result = {
+ "type": to_native(self.hcloud_load_balancer_target.type),
+ "load_balancer": to_native(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)
+ elif self.hcloud_load_balancer_target.type == "label_selector":
+ result["label_selector"] = to_native(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)
+ return result
+
+ def _get_load_balancer_and_target(self):
+ try:
+ self.hcloud_load_balancer = self.client.load_balancers.get_by_name(self.module.params.get("load_balancer"))
+ if self.module.params.get("type") == "server":
+ self.hcloud_server = self.client.servers.get_by_name(self.module.params.get("server"))
+ self.hcloud_load_balancer_target = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _get_load_balancer_target(self):
+ for target in self.hcloud_load_balancer.targets:
+ if self.module.params.get("type") == "server" and target.type == "server":
+ if target.server.id == self.hcloud_server.id:
+ self.hcloud_load_balancer_target = target
+ elif self.module.params.get("type") == "label_selector" and target.type == "label_selector":
+ if target.label_selector.selector == self.module.params.get("label_selector"):
+ self.hcloud_load_balancer_target = target
+ elif self.module.params.get("type") == "ip" and target.type == "ip":
+ if target.ip.ip == self.module.params.get("ip"):
+ self.hcloud_load_balancer_target = target
+
+ def _create_load_balancer_target(self):
+ params = {
+ "target": None
+ }
+
+ if self.module.params.get("type") == "server":
+ self.module.fail_on_missing_params(
+ required_params=["server"]
+ )
+ params["target"] = LoadBalancerTarget(type=self.module.params.get("type"), server=self.hcloud_server,
+ use_private_ip=self.module.params.get("use_private_ip"))
+ elif self.module.params.get("type") == "label_selector":
+ self.module.fail_on_missing_params(
+ required_params=["label_selector"]
+ )
+ params["target"] = LoadBalancerTarget(type=self.module.params.get("type"),
+ label_selector=LoadBalancerTargetLabelSelector(
+ selector=self.module.params.get("label_selector")),
+ use_private_ip=self.module.params.get("use_private_ip"))
+ elif self.module.params.get("type") == "ip":
+ self.module.fail_on_missing_params(
+ required_params=["ip"]
+ )
+ params["target"] = LoadBalancerTarget(type=self.module.params.get("type"),
+ ip=LoadBalancerTargetIP(ip=self.module.params.get("ip")),
+ use_private_ip=False)
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_load_balancer.add_target(**params).wait_until_finished()
+ except APIException as e:
+ if e.code == "locked" or e.code == "conflict":
+ self._create_load_balancer_target()
+ else:
+ self.module.fail_json(msg=e.message)
+
+ self._mark_as_changed()
+ self._get_load_balancer_and_target()
+ self._get_load_balancer_target()
+
+ def present_load_balancer_target(self):
+ self._get_load_balancer_and_target()
+ self._get_load_balancer_target()
+ if self.hcloud_load_balancer_target is None:
+ self._create_load_balancer_target()
+
+ def delete_load_balancer_target(self):
+ self._get_load_balancer_and_target()
+ self._get_load_balancer_target()
+ if self.hcloud_load_balancer_target is not None and self.hcloud_load_balancer is not None:
+ if not self.module.check_mode:
+ target = None
+ if self.module.params.get("type") == "server":
+ self.module.fail_on_missing_params(
+ required_params=["server"]
+ )
+ target = LoadBalancerTarget(type=self.module.params.get("type"),
+ server=self.hcloud_server)
+ elif self.module.params.get("type") == "label_selector":
+ self.module.fail_on_missing_params(
+ required_params=["label_selector"]
+ )
+ target = LoadBalancerTarget(type=self.module.params.get("type"),
+ label_selector=LoadBalancerTargetLabelSelector(
+ selector=self.module.params.get("label_selector")),
+ use_private_ip=self.module.params.get("use_private_ip"))
+ elif self.module.params.get("type") == "ip":
+ self.module.fail_on_missing_params(
+ required_params=["ip"]
+ )
+ target = LoadBalancerTarget(type=self.module.params.get("type"),
+ ip=LoadBalancerTargetIP(ip=self.module.params.get("ip")),
+ use_private_ip=False)
+ self.hcloud_load_balancer.remove_target(target).wait_until_finished()
+ self._mark_as_changed()
+ self.hcloud_load_balancer_target = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ type={"type": "str", "required": True, "choices": ["server", "label_selector", "ip"]},
+ load_balancer={"type": "str", "required": True},
+ server={"type": "str"},
+ label_selector={"type": "str"},
+ ip={"type": "str"},
+ use_private_ip={"type": "bool", "default": False},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLoadBalancerTarget.define_module()
+
+ hcloud = AnsibleHcloudLoadBalancerTarget(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_load_balancer_target()
+ elif state == "present":
+ hcloud.present_load_balancer_target()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py
new file mode 100644
index 00000000..96450093
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_load_balancer_type_info.py
@@ -0,0 +1,163 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_load_balancer_type_info
+
+short_description: Gather infos about the Hetzner Cloud Load Balancer types.
+
+
+description:
+ - Gather infos about your Hetzner Cloud Load Balancer types.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+version_added: 0.1.0
+options:
+ id:
+ description:
+ - The ID of the Load Balancer type you want to get.
+ type: int
+ name:
+ description:
+ - The name of the Load Balancer type you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud Load Balancer type infos
+ hcloud_load_balancer_type_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_load_balancer_type_info
+"""
+
+RETURN = """
+hcloud_load_balancer_type_info:
+ description: The Load Balancer type infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Load Balancer type
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Load Balancer type
+ returned: always
+ type: str
+ sample: lb11
+ description:
+ description: Description of the Load Balancer type
+ returned: always
+ type: str
+ sample: LB11
+ max_connections:
+ description: Number of maximum simultaneous open connections
+ returned: always
+ type: int
+ sample: 1
+ max_services:
+ description: Number of services a Load Balancer of this type can have
+ returned: always
+ type: int
+ sample: 1
+ max_targets:
+ description: Number of targets a single Load Balancer can have
+ returned: always
+ type: int
+ sample: 25
+ max_assigned_certificates:
+ description: Number of SSL Certificates that can be assigned to a single Load Balancer
+ returned: always
+ type: int
+ sample: 5
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ pass
+
+
+class AnsibleHcloudLoadBalancerTypeInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_load_balancer_type_info")
+ self.hcloud_load_balancer_type_info = None
+
+ def _prepare_result(self):
+ 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
+ })
+ return tmp
+
+ def get_load_balancer_types(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_load_balancer_type_info = [self.client.load_balancer_types.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_load_balancer_type_info = [self.client.load_balancer_types.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_load_balancer_type_info = self.client.load_balancer_types.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLoadBalancerTypeInfo.define_module()
+
+ hcloud = AnsibleHcloudLoadBalancerTypeInfo(module)
+ hcloud.get_load_balancer_types()
+ result = hcloud.get_result()
+ ansible_info = {
+ 'hcloud_load_balancer_type_info': result['hcloud_load_balancer_type_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py
new file mode 100644
index 00000000..21f4774f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_facts.py
@@ -0,0 +1,164 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_location_info
+
+short_description: Gather infos about your Hetzner Cloud locations.
+
+
+description:
+ - Gather infos about your Hetzner Cloud locations.
+ - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
+ Note that the M(hetzner.hcloud.hcloud_location_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_location_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the location you want to get.
+ type: int
+ name:
+ description:
+ - The name of the location you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud location infos
+ hcloud_location_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_location_info:
+ description: The location infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the location
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the location
+ returned: always
+ type: str
+ sample: fsn1
+ description:
+ description: Detail description of the location
+ returned: always
+ type: str
+ sample: Falkenstein DC Park 1
+ country:
+ description: Country code of the location
+ returned: always
+ type: str
+ sample: DE
+ city:
+ description: City of the location
+ returned: always
+ type: str
+ sample: Falkenstein
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudLocationInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_location_info")
+ self.hcloud_location_info = None
+
+ def _prepare_result(self):
+ 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)
+ })
+ return tmp
+
+ def get_locations(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_location_info = [self.client.locations.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_location_info = [self.client.locations.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_location_info = self.client.locations.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLocationInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_location_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_location_info' module has been renamed to 'hcloud_location_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudLocationInfo(module)
+ hcloud.get_locations()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_location_facts': result['hcloud_location_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_location_info': result['hcloud_location_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py
new file mode 100644
index 00000000..21f4774f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_location_info.py
@@ -0,0 +1,164 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_location_info
+
+short_description: Gather infos about your Hetzner Cloud locations.
+
+
+description:
+ - Gather infos about your Hetzner Cloud locations.
+ - This module was called C(hcloud_location_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_location_facts).
+ Note that the M(hetzner.hcloud.hcloud_location_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_location_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the location you want to get.
+ type: int
+ name:
+ description:
+ - The name of the location you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud location infos
+ hcloud_location_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output
+"""
+
+RETURN = """
+hcloud_location_info:
+ description: The location infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the location
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the location
+ returned: always
+ type: str
+ sample: fsn1
+ description:
+ description: Detail description of the location
+ returned: always
+ type: str
+ sample: Falkenstein DC Park 1
+ country:
+ description: Country code of the location
+ returned: always
+ type: str
+ sample: DE
+ city:
+ description: City of the location
+ returned: always
+ type: str
+ sample: Falkenstein
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudLocationInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_location_info")
+ self.hcloud_location_info = None
+
+ def _prepare_result(self):
+ 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)
+ })
+ return tmp
+
+ def get_locations(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_location_info = [self.client.locations.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_location_info = [self.client.locations.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_location_info = self.client.locations.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudLocationInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_location_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_location_info' module has been renamed to 'hcloud_location_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudLocationInfo(module)
+ hcloud.get_locations()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_location_facts': result['hcloud_location_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_location_info': result['hcloud_location_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py
new file mode 100644
index 00000000..f99a7fd5
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network.py
@@ -0,0 +1,247 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_network
+
+short_description: Create and manage cloud Networks on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage cloud Networks on the Hetzner Cloud.
+ - You need at least hcloud-python 1.3.0.
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud Networks to manage.
+ - Only required if no Network I(name) is given.
+ type: int
+ name:
+ description:
+ - The Name of the Hetzner Cloud Network to manage.
+ - Only required if no Network I(id) is given or a Network does not exists.
+ type: str
+ ip_range:
+ description:
+ - IP range of the Network.
+ - Required if Network does not exists.
+ type: str
+ labels:
+ description:
+ - User-defined labels (key-value pairs).
+ type: dict
+ delete_protection:
+ description:
+ - Protect the Network for deletion.
+ type: bool
+ state:
+ description:
+ - State of the Network.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.3.0
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic network
+ hcloud_network:
+ name: my-network
+ ip_range: 10.0.0.0/8
+ state: present
+
+- name: Ensure the Network is absent (remove if needed)
+ hcloud_network:
+ name: my-network
+ state: absent
+"""
+
+RETURN = """
+hcloud_network:
+ description: The Network
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: ID of the Network
+ type: int
+ returned: always
+ sample: 12345
+ name:
+ description: Name of the Network
+ type: str
+ returned: always
+ sample: my-volume
+ ip_range:
+ description: IP range of the Network
+ type: str
+ returned: always
+ sample: 10.0.0.0/8
+ delete_protection:
+ description: True if Network is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+ labels:
+ description: User-defined labels (key-value pairs)
+ type: dict
+ returned: always
+ sample:
+ key: value
+ mylabel: 123
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudNetwork(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_network")
+ self.hcloud_network = None
+
+ 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),
+ "delete_protection": self.hcloud_network.protection["delete"],
+ "labels": self.hcloud_network.labels,
+ }
+
+ def _get_network(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_network = self.client.networks.get_by_id(
+ self.module.params.get("id")
+ )
+ else:
+ self.hcloud_network = self.client.networks.get_by_name(
+ self.module.params.get("name")
+ )
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_network(self):
+
+ self.module.fail_on_missing_params(
+ required_params=["name", "ip_range"]
+ )
+ params = {
+ "name": self.module.params.get("name"),
+ "ip_range": self.module.params.get("ip_range"),
+ "labels": self.module.params.get("labels"),
+ }
+
+ if not self.module.check_mode:
+ self.client.networks.create(**params)
+
+ 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()
+
+ self._mark_as_changed()
+ self._get_network()
+
+ def _update_network(self):
+ try:
+ labels = self.module.params.get("labels")
+ if labels is not None and labels != self.hcloud_network.labels:
+ if not self.module.check_mode:
+ self.hcloud_network.update(labels=labels)
+ self._mark_as_changed()
+
+ 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()
+ self._mark_as_changed()
+
+ 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()
+ self._mark_as_changed()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+ self._get_network()
+
+ def present_network(self):
+ self._get_network()
+ if self.hcloud_network is None:
+ self._create_network()
+ else:
+ self._update_network()
+
+ def delete_network(self):
+ try:
+ self._get_network()
+ if self.hcloud_network is not None:
+ if not self.module.check_mode:
+ self.client.networks.delete(self.hcloud_network)
+ self._mark_as_changed()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+ self.hcloud_network = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ ip_range={"type": "str"},
+ labels={"type": "dict"},
+ delete_protection={"type": "bool"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name']],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudNetwork.define_module()
+
+ hcloud = AnsibleHcloudNetwork(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_network()
+ elif state == "present":
+ hcloud.present_network()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py
new file mode 100644
index 00000000..7eafbdea
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_network_info.py
@@ -0,0 +1,295 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_network_info
+
+short_description: Gather info about your Hetzner Cloud networks.
+
+
+description:
+ - Gather info about your Hetzner Cloud networks.
+
+author:
+ - Christopher Schmitt (@cschmitt-hcloud)
+
+options:
+ id:
+ description:
+ - The ID of the network you want to get.
+ type: int
+ name:
+ description:
+ - The name of the network you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the network you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud network info
+ local_action:
+ module: hcloud_network_info
+
+- name: Print the gathered info
+ debug:
+ var: hcloud_network_info
+"""
+
+RETURN = """
+hcloud_network_info:
+ description: The network info as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the network
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the network
+ returned: always
+ type: str
+ sample: awesome-network
+ ip_range:
+ description: IP range of the network
+ returned: always
+ type: str
+ sample: 10.0.0.0/16
+ subnetworks:
+ description: Subnetworks belonging to the network
+ returned: always
+ type: complex
+ contains:
+ type:
+ description: Type of the subnetwork.
+ returned: always
+ type: str
+ sample: cloud
+ network_zone:
+ description: Network of the subnetwork.
+ returned: always
+ type: str
+ sample: eu-central
+ ip_range:
+ description: IP range of the subnetwork
+ returned: always
+ type: str
+ sample: 10.0.0.0/24
+ gateway:
+ description: Gateway of this subnetwork
+ returned: always
+ type: str
+ sample: 10.0.0.1
+ routes:
+ description: Routes belonging to the network
+ returned: always
+ type: complex
+ contains:
+ ip_range:
+ description: Destination network or host of this route.
+ returned: always
+ type: str
+ sample: 10.0.0.0/16
+ gateway:
+ description: Gateway of this route
+ returned: always
+ type: str
+ sample: 10.0.0.1
+ servers:
+ description: Servers attached to the network
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server
+ returned: always
+ type: str
+ sample: my-server
+ status:
+ description: Status of the server
+ returned: always
+ type: str
+ sample: running
+ server_type:
+ description: Name of the server type of the server
+ returned: always
+ type: str
+ sample: cx11
+ ipv4_address:
+ description: Public IPv4 address of the server
+ returned: always
+ type: str
+ sample: 116.203.104.109
+ ipv6:
+ description: IPv6 network of the server
+ returned: always
+ type: str
+ sample: 2a01:4f8:1c1c:c140::/64
+ location:
+ description: Name of the location of the server
+ returned: always
+ type: str
+ sample: fsn1
+ datacenter:
+ description: Name of the datacenter of the server
+ returned: always
+ type: str
+ sample: fsn1-dc14
+ rescue_enabled:
+ description: True if rescue mode is enabled, Server will then boot into rescue system on next reboot
+ returned: always
+ type: bool
+ sample: false
+ backup_window:
+ description: Time window (UTC) in which the backup will run, or null if the backups are not enabled
+ returned: always
+ type: bool
+ sample: 22-02
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if the network is protected for deletion
+ returned: always
+ type: bool
+ version_added: "0.1.0"
+ labels:
+ description: Labels of the network
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudNetworkInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_network_info")
+ self.hcloud_network_info = None
+
+ def _prepare_result(self):
+ 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:
+ prepared_server = {
+ "id": to_native(server.id),
+ "name": to_native(server.name),
+ "ipv4_address": to_native(server.public_net.ipv4.ip),
+ "ipv6": to_native(server.public_net.ipv6.ip),
+ "image": to_native(server.image.name),
+ "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,
+ "servers": servers,
+ "labels": network.labels,
+ "delete_protection": network.protection["delete"],
+ })
+ return tmp
+
+ def get_networks(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_network_info = [self.client.networks.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_network_info = [self.client.networks.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_network_info = self.client.networks.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_network_info = self.client.networks.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudNetworkInfo.define_module()
+
+ hcloud = AnsibleHcloudNetworkInfo(module)
+ hcloud.get_networks()
+ result = hcloud.get_result()
+ info = {
+ 'hcloud_network_info': result['hcloud_network_info']
+ }
+ module.exit_json(**info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py
new file mode 100644
index 00000000..8bbfaedc
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_rdns.py
@@ -0,0 +1,273 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_rdns
+
+short_description: Create and manage reverse DNS entries on the Hetzner Cloud.
+
+
+description:
+ - Create, update and delete reverse DNS entries on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+
+options:
+ server:
+ description:
+ - The name of the Hetzner Cloud server you want to add the reverse DNS entry to.
+ type: str
+ floating_ip:
+ description:
+ - The name of the Hetzner Cloud Floating IP you want to add the reverse DNS entry to.
+ type: str
+ ip_address:
+ description:
+ - The IP address that should point to I(dns_ptr).
+ type: str
+ required: true
+ dns_ptr:
+ description:
+ - The DNS address the I(ip_address) should resolve to.
+ - Omit the param to reset the reverse DNS entry to the default value.
+ type: str
+ state:
+ description:
+ - State of the reverse DNS entry.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.3.0
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a reverse DNS entry for a server
+ hcloud_rdns:
+ server: my-server
+ ip_address: 123.123.123.123
+ dns_ptr: example.com
+ state: present
+
+- name: Create a reverse DNS entry for a Floating IP
+ hcloud_rdns:
+ floating_ip: my-floating-ip
+ ip_address: 123.123.123.123
+ dns_ptr: example.com
+ state: present
+
+- name: Ensure the reverse DNS entry is absent (remove if needed)
+ hcloud_rdns:
+ server: my-server
+ ip_address: 123.123.123.123
+ dns_ptr: example.com
+ state: absent
+"""
+
+RETURN = """
+hcloud_rdns:
+ description: The reverse DNS entry
+ returned: always
+ type: complex
+ contains:
+ server:
+ description: Name of the server
+ type: str
+ returned: always
+ sample: my-server
+ floating_ip:
+ description: Name of the Floating IP
+ type: str
+ returned: always
+ sample: my-floating-ip
+ ip_address:
+ description: The IP address that point to the DNS ptr
+ type: str
+ returned: always
+ sample: 123.123.123.123
+ dns_ptr:
+ description: The DNS that resolves to the IP
+ type: str
+ returned: always
+ sample: example.com
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudReverseDNS(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_rdns")
+ self.hcloud_resource = None
+ self.hcloud_rdns = None
+
+ def _prepare_result(self):
+ result = {
+ "server": None,
+ "floating_ip": None,
+ "ip_address": to_native(self.hcloud_rdns["ip_address"]),
+ "dns_ptr": to_native(self.hcloud_rdns["dns_ptr"]),
+ }
+
+ if self.module.params.get("server"):
+ result["server"] = to_native(self.hcloud_resource.name)
+ elif self.module.params.get("floating_ip"):
+ result["floating_ip"] = to_native(self.hcloud_resource.name)
+ return result
+
+ def _get_resource(self):
+ try:
+ if self.module.params.get("server"):
+ self.hcloud_resource = self.client.servers.get_by_name(
+ self.module.params.get("server")
+ )
+ elif self.module.params.get("floating_ip"):
+ self.hcloud_resource = self.client.floating_ips.get_by_name(
+ self.module.params.get("floating_ip")
+ )
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _get_rdns(self):
+ ip_address = self.module.params.get("ip_address")
+ if utils.validate_ip_address(ip_address):
+ if self.module.params.get("server"):
+ if self.hcloud_resource.public_net.ipv4.ip == ip_address:
+ self.hcloud_rdns = {
+ "ip_address": self.hcloud_resource.public_net.ipv4.ip,
+ "dns_ptr": self.hcloud_resource.public_net.ipv4.dns_ptr,
+ }
+ else:
+ self.module.fail_json(msg="The selected server does not have this IP address")
+ elif self.module.params.get("floating_ip"):
+ if self.hcloud_resource.ip == ip_address:
+ self.hcloud_rdns = {
+ "ip_address": self.hcloud_resource.ip,
+ "dns_ptr": self.hcloud_resource.dns_ptr[0]["dns_ptr"],
+ }
+ else:
+ self.module.fail_json(msg="The selected Floating IP does not have this IP address")
+
+ elif utils.validate_ip_v6_address(ip_address):
+ if self.module.params.get("server"):
+ for ipv6_address_dns_ptr in self.hcloud_resource.public_net.ipv6.dns_ptr:
+ if ipv6_address_dns_ptr["ip"] == ip_address:
+ self.hcloud_rdns = {
+ "ip_address": ipv6_address_dns_ptr["ip"],
+ "dns_ptr": ipv6_address_dns_ptr["dns_ptr"],
+ }
+ elif self.module.params.get("floating_ip"):
+ for ipv6_address_dns_ptr in self.hcloud_resource.dns_ptr:
+ if ipv6_address_dns_ptr["ip"] == ip_address:
+ self.hcloud_rdns = {
+ "ip_address": ipv6_address_dns_ptr["ip"],
+ "dns_ptr": ipv6_address_dns_ptr["dns_ptr"],
+ }
+ else:
+ self.module.fail_json(msg="The given IP address is not valid")
+
+ def _create_rdns(self):
+ self.module.fail_on_missing_params(
+ required_params=["dns_ptr"]
+ )
+ params = {
+ "ip": self.module.params.get("ip_address"),
+ "dns_ptr": self.module.params.get("dns_ptr"),
+ }
+
+ if not self.module.check_mode:
+ self.hcloud_resource.change_dns_ptr(**params).wait_until_finished()
+
+ self._mark_as_changed()
+ self._get_resource()
+ self._get_rdns()
+
+ def _update_rdns(self):
+ dns_ptr = self.module.params.get("dns_ptr")
+ if dns_ptr != self.hcloud_rdns["dns_ptr"]:
+ params = {
+ "ip": self.module.params.get("ip_address"),
+ "dns_ptr": dns_ptr,
+ }
+
+ if not self.module.check_mode:
+ self.hcloud_resource.change_dns_ptr(**params).wait_until_finished()
+
+ self._mark_as_changed()
+ self._get_resource()
+ self._get_rdns()
+
+ def present_rdns(self):
+ self._get_resource()
+ self._get_rdns()
+ if self.hcloud_rdns is None:
+ self._create_rdns()
+ else:
+ self._update_rdns()
+
+ def delete_rdns(self):
+ self._get_resource()
+ self._get_rdns()
+ if self.hcloud_rdns is not None:
+ if not self.module.check_mode:
+ self.hcloud_resource.change_dns_ptr(ip=self.hcloud_rdns['ip_address'], dns_ptr=None)
+ self._mark_as_changed()
+ self.hcloud_rdns = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ server={"type": "str"},
+ floating_ip={"type": "str"},
+ ip_address={"type": "str", "required": True},
+ dns_ptr={"type": "str"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['server', 'floating_ip']],
+ mutually_exclusive=[["server", "floating_ip"]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudReverseDNS.define_module()
+
+ hcloud = AnsibleHcloudReverseDNS(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_rdns()
+ elif state == "present":
+ hcloud.present_rdns()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py
new file mode 100644
index 00000000..fce3844e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_route.py
@@ -0,0 +1,195 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_route
+
+short_description: Create and delete cloud routes on the Hetzner Cloud.
+
+
+description:
+ - Create, update and delete cloud routes on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+
+options:
+ network:
+ description:
+ - The name of the Hetzner Cloud Network.
+ type: str
+ required: true
+ destination:
+ description:
+ - Destination network or host of this route.
+ type: str
+ required: true
+ gateway:
+ description:
+ - Gateway for the route.
+ type: str
+ required: true
+ state:
+ description:
+ - State of the route.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.3.0
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic route
+ hcloud_route:
+ network: my-network
+ destination: 10.100.1.0/24
+ gateway: 10.0.1.1
+ state: present
+
+- name: Ensure the route is absent
+ hcloud_route:
+ network: my-network
+ destination: 10.100.1.0/24
+ gateway: 10.0.1.1
+ state: absent
+"""
+
+RETURN = """
+hcloud_route:
+ description: One Route of a Network
+ returned: always
+ type: complex
+ contains:
+ network:
+ description: Name of the Network
+ type: str
+ returned: always
+ sample: my-network
+ destination:
+ description: Destination network or host of this route
+ type: str
+ returned: always
+ sample: 10.0.0.0/8
+ gateway:
+ description: Gateway of the route
+ type: str
+ returned: always
+ sample: 10.0.0.1
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+ from hcloud.networks.domain import NetworkRoute
+except ImportError:
+ APIException = None
+ NetworkRoute = None
+
+
+class AnsibleHcloudRoute(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_route")
+ self.hcloud_network = None
+ self.hcloud_route = None
+
+ def _prepare_result(self):
+ return {
+ "network": to_native(self.hcloud_network.name),
+ "destination": to_native(self.hcloud_route.destination),
+ "gateway": self.hcloud_route.gateway,
+ }
+
+ def _get_network(self):
+ try:
+ self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
+ self.hcloud_route = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _get_route(self):
+ destination = self.module.params.get("destination")
+ gateway = self.module.params.get("gateway")
+ for route in self.hcloud_network.routes:
+ if route.destination == destination and route.gateway == gateway:
+ self.hcloud_route = route
+
+ def _create_route(self):
+ route = NetworkRoute(
+ destination=self.module.params.get("destination"),
+ gateway=self.module.params.get('gateway')
+ )
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_network.add_route(route=route).wait_until_finished()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ self._mark_as_changed()
+ self._get_network()
+ self._get_route()
+
+ def present_route(self):
+ self._get_network()
+ self._get_route()
+ if self.hcloud_route is None:
+ self._create_route()
+
+ def delete_route(self):
+ self._get_network()
+ self._get_route()
+ if self.hcloud_route is not None and self.hcloud_network is not None:
+ if not self.module.check_mode:
+ self.hcloud_network.delete_route(self.hcloud_route).wait_until_finished()
+ self._mark_as_changed()
+ self.hcloud_route = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ network={"type": "str", "required": True},
+ gateway={"type": "str", "required": True},
+ destination={"type": "str", "required": True},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudRoute.define_module()
+
+ hcloud = AnsibleHcloudRoute(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_route()
+ elif state == "present":
+ hcloud.present_route()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py
new file mode 100644
index 00000000..4cc48875
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server.py
@@ -0,0 +1,564 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_server
+
+short_description: Create and manage cloud servers on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage cloud servers on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud server to manage.
+ - Only required if no server I(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 exists.
+ type: str
+ server_type:
+ description:
+ - The Server Type of the Hetzner Cloud server to manage.
+ - Required if server does not exists.
+ 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.
+ type: list
+ elements: str
+ volumes:
+ description:
+ - List of Volumes IDs that should be attached to the server on server creation.
+ type: list
+ elements: str
+ image:
+ description:
+ - Image the server should be created from.
+ - Required if server does not exists.
+ type: str
+ location:
+ description:
+ - Location of Server.
+ - Required if no I(datacenter) is given and server does not exists.
+ type: str
+ datacenter:
+ description:
+ - Datacenter of Server.
+ - Required of no I(location) is given and server does not exists.
+ type: str
+ backups:
+ description:
+ - Enable or disable Backups for the given Server.
+ type: bool
+ default: no
+ upgrade_disk:
+ description:
+ - Resize the disk size, when resizing a server.
+ - If you want to downgrade the server later, this value should be False.
+ type: bool
+ default: no
+ force_upgrade:
+ description:
+ - Force the upgrade of the server.
+ - Power off the server if it is running on upgrade.
+ type: bool
+ default: no
+ user_data:
+ description:
+ - User Data to be passed to the server on creation.
+ - Only used if server does not exists.
+ type: str
+ rescue_mode:
+ description:
+ - Add the Hetzner rescue system type you want the server to be booted into.
+ type: str
+ labels:
+ description:
+ - User-defined labels (key-value pairs).
+ type: dict
+ delete_protection:
+ description:
+ - Protect the Server for deletion.
+ - Needs to be the same as I(rebuild_protection).
+ type: bool
+ rebuild_protection:
+ description:
+ - Protect the Server for rebuild.
+ - Needs to be the same as I(delete_protection).
+ type: bool
+ state:
+ description:
+ - State of the server.
+ default: present
+ choices: [ absent, present, restarted, started, stopped, rebuild ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic server
+ hcloud_server:
+ name: my-server
+ server_type: cx11
+ image: ubuntu-18.04
+ state: present
+
+- name: Create a basic server with ssh key
+ hcloud_server:
+ name: my-server
+ server_type: cx11
+ image: ubuntu-18.04
+ location: fsn1
+ ssh_keys:
+ - me@myorganisation
+ state: present
+
+- name: Resize an existing server
+ hcloud_server:
+ name: my-server
+ server_type: cx21
+ upgrade_disk: yes
+ state: present
+
+- name: Ensure the server is absent (remove if needed)
+ hcloud_server:
+ name: my-server
+ state: absent
+
+- name: Ensure the server is started
+ hcloud_server:
+ name: my-server
+ state: started
+
+- name: Ensure the server is stopped
+ hcloud_server:
+ name: my-server
+ state: stopped
+
+- name: Ensure the server is restarted
+ hcloud_server:
+ name: my-server
+ state: restarted
+
+- name: Ensure the server is will be booted in rescue mode and therefore restarted
+ hcloud_server:
+ name: my-server
+ rescue_mode: linux64
+ state: restarted
+
+- name: Ensure the server is rebuild
+ hcloud_server:
+ name: my-server
+ image: ubuntu-18.04
+ state: rebuild
+"""
+
+RETURN = """
+hcloud_server:
+ description: The server instance
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server
+ returned: always
+ type: str
+ sample: my-server
+ status:
+ description: Status of the server
+ returned: always
+ type: str
+ sample: running
+ server_type:
+ description: Name of the server type of the server
+ returned: always
+ type: str
+ sample: cx11
+ ipv4_address:
+ description: Public IPv4 address of the server
+ returned: always
+ type: str
+ sample: 116.203.104.109
+ ipv6:
+ description: IPv6 network of the server
+ returned: always
+ type: str
+ sample: 2a01:4f8:1c1c:c140::/64
+ location:
+ description: Name of the location of the server
+ returned: always
+ type: str
+ sample: fsn1
+ datacenter:
+ description: Name of the datacenter of the server
+ returned: always
+ type: str
+ sample: fsn1-dc14
+ rescue_enabled:
+ description: True if rescue mode is enabled, Server will then boot into rescue system on next reboot
+ returned: always
+ type: bool
+ sample: false
+ backup_window:
+ description: Time window (UTC) in which the backup will run, or null if the backups are not enabled
+ returned: always
+ type: bool
+ sample: 22-02
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if server is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+ rebuild_protection:
+ description: True if server is protected for rebuild
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud.volumes.domain import Volume
+ from hcloud.ssh_keys.domain import SSHKey
+ from hcloud.servers.domain import Server
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+ Volume = None
+ SSHKey = None
+ Server = None
+
+
+class AnsibleHcloudServer(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_server")
+ self.hcloud_server = None
+
+ def _prepare_result(self):
+ image = None if self.hcloud_server.image is None else to_native(self.hcloud_server.image.name)
+ return {
+ "id": to_native(self.hcloud_server.id),
+ "name": to_native(self.hcloud_server.name),
+ "ipv4_address": to_native(self.hcloud_server.public_net.ipv4.ip),
+ "ipv6": to_native(self.hcloud_server.public_net.ipv6.ip),
+ "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),
+ "rescue_enabled": self.hcloud_server.rescue_enabled,
+ "backup_window": to_native(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),
+ }
+
+ def _get_server(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_server = self.client.servers.get_by_id(
+ self.module.params.get("id")
+ )
+ else:
+ self.hcloud_server = self.client.servers.get_by_name(
+ self.module.params.get("name")
+ )
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_server(self):
+
+ self.module.fail_on_missing_params(
+ required_params=["name", "server_type", "image"]
+ )
+
+ params = {
+ "name": self.module.params.get("name"),
+ "server_type": self.client.server_types.get_by_name(
+ self.module.params.get("server_type")
+ ),
+ "user_data": self.module.params.get("user_data"),
+ "labels": self.module.params.get("labels"),
+ }
+ if self.client.images.get_by_name(self.module.params.get("image")) is not None:
+ # When image name is not available look for id instead
+ params["image"] = self.client.images.get_by_name(self.module.params.get("image"))
+ else:
+ params["image"] = self.client.images.get_by_id(self.module.params.get("image"))
+
+ 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")
+ ]
+
+ if self.module.params.get("volumes") is not None:
+ params["volumes"] = [
+ Volume(id=volume_id) for volume_id in self.module.params.get("volumes")
+ ]
+
+ 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")
+ )
+ 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")
+ )
+
+ if not self.module.check_mode:
+ 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]
+
+ rescue_mode = self.module.params.get("rescue_mode")
+ if rescue_mode:
+ self._get_server()
+ self._set_rescue_mode(rescue_mode)
+
+ backups = self.module.params.get("backups")
+ if backups:
+ self._get_server()
+ self.hcloud_server.enable_backup().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(delete=delete_protection,
+ rebuild=rebuild_protection).wait_until_finished()
+ self._mark_as_changed()
+ self._get_server()
+
+ def _update_server(self):
+ try:
+ 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:
+ self._set_rescue_mode(rescue_mode)
+ 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()
+ self._mark_as_changed()
+
+ if self.module.params.get("backups") and self.hcloud_server.backup_window is None:
+ if not self.module.check_mode:
+ self.hcloud_server.enable_backup().wait_until_finished()
+ self._mark_as_changed()
+ elif not self.module.params.get("backups") and self.hcloud_server.backup_window is not None:
+ if not self.module.check_mode:
+ self.hcloud_server.disable_backup().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()
+
+ server_type = self.module.params.get("server_type")
+ if server_type is not None and self.hcloud_server.server_type.name != server_type:
+ previous_server_status = self.hcloud_server.status
+ state = self.module.params.get("state")
+ if previous_server_status == Server.STATUS_RUNNING:
+ if not self.module.check_mode:
+ if self.module.params.get("force_upgrade") or state == "stopped":
+ self.stop_server() # Only stopped server can be upgraded
+ else:
+ self.module.warn(
+ "You can not upgrade a running instance %s. You need to stop the instance or use force_upgrade=yes."
+ % self.hcloud_server.name
+ )
+ timeout = 100
+ if self.module.params.get("upgrade_disk"):
+ timeout = (
+ 1000
+ ) # When we upgrade the disk too the resize progress takes some more time.
+ if not self.module.check_mode:
+ self.hcloud_server.change_type(
+ server_type=self.client.server_types.get_by_name(server_type),
+ upgrade_disk=self.module.params.get("upgrade_disk"),
+ ).wait_until_finished(timeout)
+ if state == "present" and previous_server_status == Server.STATUS_RUNNING or state == "started":
+ self.start_server()
+
+ self._mark_as_changed()
+
+ 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) and (
+ delete_protection != self.hcloud_server.protection["delete"] or rebuild_protection !=
+ self.hcloud_server.protection["rebuild"]):
+ if not self.module.check_mode:
+ self.hcloud_server.change_protection(delete=delete_protection,
+ rebuild=rebuild_protection).wait_until_finished()
+ self._mark_as_changed()
+ self._get_server()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _set_rescue_mode(self, rescue_mode):
+ if self.module.params.get("ssh_keys"):
+ resp = self.hcloud_server.enable_rescue(type=rescue_mode,
+ ssh_keys=[self.client.ssh_keys.get_by_name(ssh_key_name).id
+ for
+ ssh_key_name in
+ self.module.params.get("ssh_keys")])
+ else:
+ resp = self.hcloud_server.enable_rescue(type=rescue_mode)
+ resp.action.wait_until_finished()
+ self.result["root_password"] = resp.root_password
+
+ def start_server(self):
+ try:
+ 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()
+ self._mark_as_changed()
+ self._get_server()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def stop_server(self):
+ try:
+ 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()
+ self._mark_as_changed()
+ self._get_server()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def rebuild_server(self):
+ self.module.fail_on_missing_params(
+ required_params=["image"]
+ )
+ try:
+ if not self.module.check_mode:
+ self.client.servers.rebuild(self.hcloud_server, self.client.images.get_by_name(
+ self.module.params.get("image"))).wait_until_finished()
+ self._mark_as_changed()
+
+ self._get_server()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def present_server(self):
+ self._get_server()
+ if self.hcloud_server is None:
+ self._create_server()
+ else:
+ self._update_server()
+
+ def delete_server(self):
+ try:
+ 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()
+ self._mark_as_changed()
+ self.hcloud_server = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ image={"type": "str"},
+ server_type={"type": "str"},
+ location={"type": "str"},
+ datacenter={"type": "str"},
+ user_data={"type": "str"},
+ ssh_keys={"type": "list", "elements": "str"},
+ volumes={"type": "list", "elements": "str"},
+ labels={"type": "dict"},
+ backups={"type": "bool", "default": False},
+ upgrade_disk={"type": "bool", "default": False},
+ force_upgrade={"type": "bool", "default": False},
+ rescue_mode={"type": "str"},
+ delete_protection={"type": "bool"},
+ rebuild_protection={"type": "bool"},
+ state={
+ "choices": ["absent", "present", "restarted", "started", "stopped", "rebuild"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name']],
+ mutually_exclusive=[["location", "datacenter"]],
+ required_together=[["delete_protection", "rebuild_protection"]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudServer.define_module()
+
+ hcloud = AnsibleHcloudServer(module)
+ state = module.params.get("state")
+ if state == "absent":
+ hcloud.delete_server()
+ elif state == "present":
+ hcloud.present_server()
+ elif state == "started":
+ hcloud.present_server()
+ hcloud.start_server()
+ elif state == "stopped":
+ hcloud.present_server()
+ hcloud.stop_server()
+ elif state == "restarted":
+ hcloud.present_server()
+ hcloud.stop_server()
+ hcloud.start_server()
+ elif state == "rebuild":
+ hcloud.present_server()
+ hcloud.rebuild_server()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py
new file mode 100644
index 00000000..f99d1c8c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_facts.py
@@ -0,0 +1,224 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_server_info
+
+short_description: Gather infos about your Hetzner Cloud servers.
+
+
+description:
+ - Gather infos about your Hetzner Cloud servers.
+ - This module was called C(hcloud_server_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_facts).
+ Note that the M(hetzner.hcloud.hcloud_server_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the server you want to get.
+ type: int
+ name:
+ description:
+ - The name of the server you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the server you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud server infos
+ hcloud_server_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_server_info
+"""
+
+RETURN = """
+hcloud_server_info:
+ description: The server infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server
+ returned: always
+ type: str
+ sample: my-server
+ status:
+ description: Status of the server
+ returned: always
+ type: str
+ sample: running
+ server_type:
+ description: Name of the server type of the server
+ returned: always
+ type: str
+ sample: cx11
+ ipv4_address:
+ description: Public IPv4 address of the server
+ returned: always
+ type: str
+ sample: 116.203.104.109
+ ipv6:
+ description: IPv6 network of the server
+ returned: always
+ type: str
+ sample: 2a01:4f8:1c1c:c140::/64
+ location:
+ description: Name of the location of the server
+ returned: always
+ type: str
+ sample: fsn1
+ datacenter:
+ description: Name of the datacenter of the server
+ returned: always
+ type: str
+ sample: fsn1-dc14
+ rescue_enabled:
+ description: True if rescue mode is enabled, Server will then boot into rescue system on next reboot
+ returned: always
+ type: bool
+ sample: false
+ backup_window:
+ description: Time window (UTC) in which the backup will run, or null if the backups are not enabled
+ returned: always
+ type: bool
+ sample: 22-02
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if server is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+ rebuild_protection:
+ description: True if server is protected for rebuild
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudServerInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_server_info")
+ self.hcloud_server_info = None
+
+ def _prepare_result(self):
+ 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)
+ tmp.append({
+ "id": to_native(server.id),
+ "name": to_native(server.name),
+ "ipv4_address": to_native(server.public_net.ipv4.ip),
+ "ipv6": to_native(server.public_net.ipv6.ip),
+ "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),
+ "delete_protection": server.protection["delete"],
+ "rebuild_protection": server.protection["rebuild"],
+ })
+ return tmp
+
+ def get_servers(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_server_info = [self.client.servers.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_server_info = [self.client.servers.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_server_info = self.client.servers.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_server_info = self.client.servers.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudServerInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_server_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_server_facts' module has been renamed to 'hcloud_server_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudServerInfo(module)
+ hcloud.get_servers()
+ result = hcloud.get_result()
+
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_server_facts': result['hcloud_server_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_server_info': result['hcloud_server_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py
new file mode 100644
index 00000000..f99d1c8c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_info.py
@@ -0,0 +1,224 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_server_info
+
+short_description: Gather infos about your Hetzner Cloud servers.
+
+
+description:
+ - Gather infos about your Hetzner Cloud servers.
+ - This module was called C(hcloud_server_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_facts).
+ Note that the M(hetzner.hcloud.hcloud_server_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the server you want to get.
+ type: int
+ name:
+ description:
+ - The name of the server you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the server you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud server infos
+ hcloud_server_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_server_info
+"""
+
+RETURN = """
+hcloud_server_info:
+ description: The server infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server
+ returned: always
+ type: str
+ sample: my-server
+ status:
+ description: Status of the server
+ returned: always
+ type: str
+ sample: running
+ server_type:
+ description: Name of the server type of the server
+ returned: always
+ type: str
+ sample: cx11
+ ipv4_address:
+ description: Public IPv4 address of the server
+ returned: always
+ type: str
+ sample: 116.203.104.109
+ ipv6:
+ description: IPv6 network of the server
+ returned: always
+ type: str
+ sample: 2a01:4f8:1c1c:c140::/64
+ location:
+ description: Name of the location of the server
+ returned: always
+ type: str
+ sample: fsn1
+ datacenter:
+ description: Name of the datacenter of the server
+ returned: always
+ type: str
+ sample: fsn1-dc14
+ rescue_enabled:
+ description: True if rescue mode is enabled, Server will then boot into rescue system on next reboot
+ returned: always
+ type: bool
+ sample: false
+ backup_window:
+ description: Time window (UTC) in which the backup will run, or null if the backups are not enabled
+ returned: always
+ type: bool
+ sample: 22-02
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+ delete_protection:
+ description: True if server is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+ rebuild_protection:
+ description: True if server is protected for rebuild
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudServerInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_server_info")
+ self.hcloud_server_info = None
+
+ def _prepare_result(self):
+ 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)
+ tmp.append({
+ "id": to_native(server.id),
+ "name": to_native(server.name),
+ "ipv4_address": to_native(server.public_net.ipv4.ip),
+ "ipv6": to_native(server.public_net.ipv6.ip),
+ "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),
+ "delete_protection": server.protection["delete"],
+ "rebuild_protection": server.protection["rebuild"],
+ })
+ return tmp
+
+ def get_servers(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_server_info = [self.client.servers.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_server_info = [self.client.servers.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_server_info = self.client.servers.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_server_info = self.client.servers.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudServerInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_server_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_server_facts' module has been renamed to 'hcloud_server_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudServerInfo(module)
+ hcloud.get_servers()
+ result = hcloud.get_result()
+
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_server_facts': result['hcloud_server_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_server_info': result['hcloud_server_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py
new file mode 100644
index 00000000..285b2fe3
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_network.py
@@ -0,0 +1,243 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_server_network
+
+short_description: Manage the relationship between Hetzner Cloud Networks and servers
+
+
+description:
+ - Create and delete the relationship Hetzner Cloud Networks and servers
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+
+options:
+ network:
+ description:
+ - The name of the Hetzner Cloud Networks.
+ type: str
+ required: true
+ server:
+ description:
+ - The name of the Hetzner Cloud server.
+ type: str
+ required: true
+ ip:
+ description:
+ - The IP the server should have.
+ type: str
+ alias_ips:
+ description:
+ - Alias IPs the server has.
+ type: list
+ elements: str
+ state:
+ description:
+ - State of the server_network.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.3.0
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic server network
+ hcloud_server_network:
+ network: my-network
+ server: my-server
+ state: present
+
+- name: Create a server network and specify the ip address
+ hcloud_server_network:
+ network: my-network
+ server: my-server
+ ip: 10.0.0.1
+ state: present
+
+- name: Create a server network and add alias ips
+ hcloud_server_network:
+ network: my-network
+ server: my-server
+ ip: 10.0.0.1
+ alias_ips:
+ - 10.1.0.1
+ - 10.2.0.1
+ state: present
+
+- name: Ensure the server network is absent (remove if needed)
+ hcloud_server_network:
+ network: my-network
+ server: my-server
+ state: absent
+"""
+
+RETURN = """
+hcloud_server_network:
+ description: The relationship between a server and a network
+ returned: always
+ type: complex
+ contains:
+ network:
+ description: Name of the Network
+ type: str
+ returned: always
+ sample: my-network
+ server:
+ description: Name of the server
+ type: str
+ returned: always
+ sample: my-server
+ ip:
+ description: IP of the server within the Network ip range
+ type: str
+ returned: always
+ sample: 10.0.0.8
+ alias_ips:
+ description: Alias IPs of the server within the Network ip range
+ type: str
+ returned: always
+ sample: [10.1.0.1, ...]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudServerNetwork(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_server_network")
+ self.hcloud_network = None
+ self.hcloud_server = None
+ self.hcloud_server_network = None
+
+ 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,
+ }
+
+ def _get_server_and_network(self):
+ try:
+ self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
+ self.hcloud_server = self.client.servers.get_by_name(self.module.params.get("server"))
+ self.hcloud_server_network = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _get_server_network(self):
+ for privateNet in self.hcloud_server.private_net:
+ if privateNet.network.id == self.hcloud_network.id:
+ self.hcloud_server_network = privateNet
+
+ def _create_server_network(self):
+ params = {
+ "network": self.hcloud_network
+ }
+
+ if self.module.params.get("ip") is not None:
+ params["ip"] = self.module.params.get("ip")
+ if self.module.params.get("alias_ips") is not None:
+ params["alias_ips"] = self.module.params.get("alias_ips")
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_server.attach_to_network(**params).wait_until_finished()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ self._mark_as_changed()
+ self._get_server_and_network()
+ self._get_server_network()
+
+ def _update_server_network(self):
+ params = {
+ "network": self.hcloud_network
+ }
+ alias_ips = self.module.params.get("alias_ips")
+ if alias_ips is not None and self.hcloud_server_network.alias_ips.sort() != alias_ips.sort():
+ params["alias_ips"] = alias_ips
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_server.change_alias_ips(**params).wait_until_finished()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ self._mark_as_changed()
+ self._get_server_and_network()
+ self._get_server_network()
+
+ def present_server_network(self):
+ self._get_server_and_network()
+ self._get_server_network()
+ if self.hcloud_server_network is None:
+ self._create_server_network()
+ else:
+ self._update_server_network()
+
+ def delete_server_network(self):
+ self._get_server_and_network()
+ self._get_server_network()
+ if self.hcloud_server_network is not None and self.hcloud_server is not None:
+ if not self.module.check_mode:
+ self.hcloud_server.detach_from_network(self.hcloud_server_network.network).wait_until_finished()
+ self._mark_as_changed()
+ self.hcloud_server_network = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ network={"type": "str", "required": True},
+ server={"type": "str", "required": True},
+ ip={"type": "str"},
+ alias_ips={"type": "list", "elements": "str"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudServerNetwork.define_module()
+
+ hcloud = AnsibleHcloudServerNetwork(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_server_network()
+ elif state == "present":
+ hcloud.present_server_network()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py
new file mode 100644
index 00000000..5b575d93
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_facts.py
@@ -0,0 +1,182 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_server_type_info
+
+short_description: Gather infos about the Hetzner Cloud server types.
+
+
+description:
+ - Gather infos about your Hetzner Cloud server types.
+ - This module was called C(hcloud_server_type_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_type_facts).
+ Note that the M(hetzner.hcloud.hcloud_server_type_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_type_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the server type you want to get.
+ type: int
+ name:
+ description:
+ - The name of the server type you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud server type infos
+ hcloud_server_type_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_server_type_info
+"""
+
+RETURN = """
+hcloud_server_type_info:
+ description: The server type infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server type
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server type
+ returned: always
+ type: str
+ sample: fsn1
+ description:
+ description: Detail description of the server type
+ returned: always
+ type: str
+ sample: Falkenstein DC Park 1
+ cores:
+ description: Number of cpu cores a server of this type will have
+ returned: always
+ type: int
+ sample: 1
+ memory:
+ description: Memory a server of this type will have in GB
+ returned: always
+ type: int
+ sample: 1
+ disk:
+ description: Disk size a server of this type will have in GB
+ returned: always
+ type: int
+ sample: 25
+ storage_type:
+ description: Type of server boot drive
+ returned: always
+ type: str
+ sample: local
+ cpu_type:
+ description: Type of cpu
+ returned: always
+ type: str
+ sample: shared
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudServerTypeInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_server_type_info")
+ self.hcloud_server_type_info = None
+
+ def _prepare_result(self):
+ 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)
+ })
+ return tmp
+
+ def get_server_types(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_server_type_info = [self.client.server_types.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_server_type_info = [self.client.server_types.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_server_type_info = self.client.server_types.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudServerTypeInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_server_type_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_server_type_info' module has been renamed to 'hcloud_server_type_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudServerTypeInfo(module)
+ hcloud.get_server_types()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_server_type_info': result['hcloud_server_type_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_server_type_info': result['hcloud_server_type_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py
new file mode 100644
index 00000000..5b575d93
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_server_type_info.py
@@ -0,0 +1,182 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_server_type_info
+
+short_description: Gather infos about the Hetzner Cloud server types.
+
+
+description:
+ - Gather infos about your Hetzner Cloud server types.
+ - This module was called C(hcloud_server_type_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_server_type_facts).
+ Note that the M(hetzner.hcloud.hcloud_server_type_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_server_type_info)!
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the server type you want to get.
+ type: int
+ name:
+ description:
+ - The name of the server type you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud server type infos
+ hcloud_server_type_info:
+ register: output
+
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_server_type_info
+"""
+
+RETURN = """
+hcloud_server_type_info:
+ description: The server type infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the server type
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the server type
+ returned: always
+ type: str
+ sample: fsn1
+ description:
+ description: Detail description of the server type
+ returned: always
+ type: str
+ sample: Falkenstein DC Park 1
+ cores:
+ description: Number of cpu cores a server of this type will have
+ returned: always
+ type: int
+ sample: 1
+ memory:
+ description: Memory a server of this type will have in GB
+ returned: always
+ type: int
+ sample: 1
+ disk:
+ description: Disk size a server of this type will have in GB
+ returned: always
+ type: int
+ sample: 25
+ storage_type:
+ description: Type of server boot drive
+ returned: always
+ type: str
+ sample: local
+ cpu_type:
+ description: Type of cpu
+ returned: always
+ type: str
+ sample: shared
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudServerTypeInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_server_type_info")
+ self.hcloud_server_type_info = None
+
+ def _prepare_result(self):
+ 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)
+ })
+ return tmp
+
+ def get_server_types(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_server_type_info = [self.client.server_types.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_server_type_info = [self.client.server_types.get_by_name(
+ self.module.params.get("name")
+ )]
+ else:
+ self.hcloud_server_type_info = self.client.server_types.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudServerTypeInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_server_type_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_server_type_info' module has been renamed to 'hcloud_server_type_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudServerTypeInfo(module)
+ hcloud.get_server_types()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_server_type_info': result['hcloud_server_type_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_server_type_info': result['hcloud_server_type_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py
new file mode 100644
index 00000000..31c9625e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key.py
@@ -0,0 +1,245 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_ssh_key
+
+short_description: Create and manage ssh keys on the Hetzner Cloud.
+
+
+description:
+ - Create, update and manage ssh keys on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud ssh_key to manage.
+ - Only required if no ssh_key I(name) is given
+ type: int
+ name:
+ description:
+ - The Name of the Hetzner Cloud ssh_key to manage.
+ - Only required if no ssh_key I(id) is given or a ssh_key does not exists.
+ type: str
+ fingerprint:
+ description:
+ - The Fingerprint of the Hetzner Cloud ssh_key to manage.
+ - Only required if no ssh_key I(id) or I(name) is given.
+ type: str
+ labels:
+ description:
+ - User-defined labels (key-value pairs)
+ type: dict
+ public_key:
+ description:
+ - The Public Key to add.
+ - Required if ssh_key does not exists.
+ type: str
+ state:
+ description:
+ - State of the ssh_key.
+ default: present
+ choices: [ absent, present ]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic ssh_key
+ hcloud_ssh_key:
+ name: my-ssh_key
+ public_key: "ssh-rsa AAAjjk76kgf...Xt"
+ state: present
+
+- name: Create a ssh_key with labels
+ hcloud_ssh_key:
+ name: my-ssh_key
+ public_key: "ssh-rsa AAAjjk76kgf...Xt"
+ labels:
+ key: value
+ mylabel: 123
+ state: present
+
+- name: Ensure the ssh_key is absent (remove if needed)
+ hcloud_ssh_key:
+ name: my-ssh_key
+ state: absent
+"""
+
+RETURN = """
+hcloud_ssh_key:
+ description: The ssh_key instance
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: ID of the ssh_key
+ type: int
+ returned: Always
+ sample: 12345
+ name:
+ description: Name of the ssh_key
+ type: str
+ returned: Always
+ sample: my-ssh-key
+ fingerprint:
+ description: Fingerprint of the ssh_key
+ type: str
+ returned: Always
+ sample: b7:2f:30:a0:2f:6c:58:6c:21:04:58:61:ba:06:3b:2f
+ public_key:
+ description: Public key of the ssh_key
+ type: str
+ returned: Always
+ sample: "ssh-rsa AAAjjk76kgf...Xt"
+ labels:
+ description: User-defined labels (key-value pairs)
+ type: dict
+ returned: Always
+ sample:
+ key: value
+ mylabel: 123
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud.volumes.domain import Volume
+ from hcloud.ssh_keys.domain import SSHKey
+ from hcloud.ssh_keys.domain import Server
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudSSHKey(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_ssh_key")
+ self.hcloud_ssh_key = None
+
+ 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),
+ "labels": self.hcloud_ssh_key.labels,
+ }
+
+ def _get_ssh_key(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_ssh_key = self.client.ssh_keys.get_by_id(
+ self.module.params.get("id")
+ )
+ elif self.module.params.get("fingerprint") is not None:
+ self.hcloud_ssh_key = self.client.ssh_keys.get_by_fingerprint(
+ self.module.params.get("fingerprint")
+ )
+ elif self.module.params.get("name") is not None:
+ self.hcloud_ssh_key = self.client.ssh_keys.get_by_name(
+ self.module.params.get("name")
+ )
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_ssh_key(self):
+ self.module.fail_on_missing_params(
+ required_params=["name", "public_key"]
+ )
+ params = {
+ "name": self.module.params.get("name"),
+ "public_key": self.module.params.get("public_key"),
+ "labels": self.module.params.get("labels")
+ }
+
+ if not self.module.check_mode:
+ self.client.ssh_keys.create(**params)
+ self._mark_as_changed()
+ self._get_ssh_key()
+
+ def _update_ssh_key(self):
+ name = self.module.params.get("name")
+ if name is not None and self.hcloud_ssh_key.name != name:
+ self.module.fail_on_missing_params(
+ required_params=["id"]
+ )
+ if not self.module.check_mode:
+ self.hcloud_ssh_key.update(name=name)
+ self._mark_as_changed()
+
+ labels = self.module.params.get("labels")
+ if labels is not None and self.hcloud_ssh_key.labels != labels:
+ if not self.module.check_mode:
+ self.hcloud_ssh_key.update(labels=labels)
+ self._mark_as_changed()
+
+ self._get_ssh_key()
+
+ def present_ssh_key(self):
+ self._get_ssh_key()
+ if self.hcloud_ssh_key is None:
+ self._create_ssh_key()
+ else:
+ self._update_ssh_key()
+
+ def delete_ssh_key(self):
+ self._get_ssh_key()
+ if self.hcloud_ssh_key is not None:
+ if not self.module.check_mode:
+ self.client.ssh_keys.delete(self.hcloud_ssh_key)
+ self._mark_as_changed()
+ self.hcloud_ssh_key = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ public_key={"type": "str"},
+ fingerprint={"type": "str"},
+ labels={"type": "dict"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name', 'fingerprint']],
+ required_if=[['state', 'present', ['name']]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudSSHKey.define_module()
+
+ hcloud = AnsibleHcloudSSHKey(module)
+ state = module.params.get("state")
+ if state == "absent":
+ hcloud.delete_ssh_key()
+ elif state == "present":
+ hcloud.present_ssh_key()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py
new file mode 100644
index 00000000..ad2b4fda
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_facts.py
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_ssh_key_info
+short_description: Gather infos about your Hetzner Cloud ssh_keys.
+description:
+ - Gather facts about your Hetzner Cloud ssh_keys.
+ - This module was called C(hcloud_ssh_key_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_ssh_key_facts).
+ Note that the M(hetzner.hcloud.hcloud_ssh_key_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_ssh_key_info)!
+author:
+ - Christopher Schmitt (@cschmitt-hcloud)
+options:
+ id:
+ description:
+ - The ID of the ssh key you want to get.
+ type: int
+ name:
+ description:
+ - The name of the ssh key you want to get.
+ type: str
+ fingerprint:
+ description:
+ - The fingerprint of the ssh key you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the ssh key you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud sshkey infos
+ hcloud_ssh_key_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_ssh_key_info
+"""
+
+RETURN = """
+hcloud_ssh_key_info:
+ description: The ssh key instances
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the ssh_key
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the ssh_key
+ returned: always
+ type: str
+ sample: my-ssh-key
+ fingerprint:
+ description: Fingerprint of the ssh key
+ returned: always
+ type: str
+ sample: 0e:e0:bd:c7:2d:1f:69:49:94:44:91:f1:19:fd:35:f3
+ public_key:
+ description: The actual public key
+ returned: always
+ type: str
+ sample: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGpl/tnk74nnQJxxLAtutUApUZMRJxryKh7VXkNbd4g9 john@example.com"
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudSSHKeyInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_ssh_key_info")
+ self.hcloud_ssh_key_info = None
+
+ def _prepare_result(self):
+ ssh_keys = []
+
+ 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
+
+ def get_ssh_keys(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("fingerprint") is not None:
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_fingerprint(
+ self.module.params.get("fingerprint")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_ssh_key_info = self.client.ssh_keys.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_ssh_key_info = self.client.ssh_keys.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ fingerprint={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudSSHKeyInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_ssh_key_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_ssh_key_facts' module has been renamed to 'hcloud_ssh_key_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudSSHKeyInfo(module)
+ hcloud.get_ssh_keys()
+ result = hcloud.get_result()
+
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_ssh_key_facts': result['hcloud_ssh_key_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_ssh_key_info': result['hcloud_ssh_key_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py
new file mode 100644
index 00000000..ad2b4fda
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_ssh_key_info.py
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_ssh_key_info
+short_description: Gather infos about your Hetzner Cloud ssh_keys.
+description:
+ - Gather facts about your Hetzner Cloud ssh_keys.
+ - This module was called C(hcloud_ssh_key_facts) before Ansible 2.9, returning C(ansible_facts) and C(hcloud_ssh_key_facts).
+ Note that the M(hetzner.hcloud.hcloud_ssh_key_info) module no longer returns C(ansible_facts) and the value was renamed to C(hcloud_ssh_key_info)!
+author:
+ - Christopher Schmitt (@cschmitt-hcloud)
+options:
+ id:
+ description:
+ - The ID of the ssh key you want to get.
+ type: int
+ name:
+ description:
+ - The name of the ssh key you want to get.
+ type: str
+ fingerprint:
+ description:
+ - The fingerprint of the ssh key you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the ssh key you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud sshkey infos
+ hcloud_ssh_key_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_ssh_key_info
+"""
+
+RETURN = """
+hcloud_ssh_key_info:
+ description: The ssh key instances
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the ssh_key
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the ssh_key
+ returned: always
+ type: str
+ sample: my-ssh-key
+ fingerprint:
+ description: Fingerprint of the ssh key
+ returned: always
+ type: str
+ sample: 0e:e0:bd:c7:2d:1f:69:49:94:44:91:f1:19:fd:35:f3
+ public_key:
+ description: The actual public key
+ returned: always
+ type: str
+ sample: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGpl/tnk74nnQJxxLAtutUApUZMRJxryKh7VXkNbd4g9 john@example.com"
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudSSHKeyInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_ssh_key_info")
+ self.hcloud_ssh_key_info = None
+
+ def _prepare_result(self):
+ ssh_keys = []
+
+ 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
+
+ def get_ssh_keys(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("fingerprint") is not None:
+ self.hcloud_ssh_key_info = [self.client.ssh_keys.get_by_fingerprint(
+ self.module.params.get("fingerprint")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_ssh_key_info = self.client.ssh_keys.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_ssh_key_info = self.client.ssh_keys.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ fingerprint={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudSSHKeyInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_ssh_key_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_ssh_key_facts' module has been renamed to 'hcloud_ssh_key_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudSSHKeyInfo(module)
+ hcloud.get_ssh_keys()
+ result = hcloud.get_result()
+
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_ssh_key_facts': result['hcloud_ssh_key_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_ssh_key_info': result['hcloud_ssh_key_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py
new file mode 100644
index 00000000..fd199804
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_subnetwork.py
@@ -0,0 +1,246 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_subnetwork
+
+short_description: Manage cloud subnetworks on the Hetzner Cloud.
+
+
+description:
+ - Create, update and delete cloud subnetworks on the Hetzner Cloud.
+
+author:
+ - Lukas Kaemmerling (@lkaemmerling)
+
+options:
+ network:
+ description:
+ - The ID or Name of the Hetzner Cloud Networks.
+ type: str
+ required: true
+ ip_range:
+ description:
+ - IP range of the subnetwork.
+ type: str
+ required: true
+ type:
+ description:
+ - Type of subnetwork.
+ type: str
+ choices: [ server, cloud, vswitch ]
+ required: true
+ network_zone:
+ description:
+ - Name of network zone.
+ type: str
+ required: true
+ vswitch_id:
+ description:
+ - ID of the vSwitch you want to couple with your Network.
+ - Required if type == vswitch
+ type: int
+ state:
+ description:
+ - State of the subnetwork.
+ default: present
+ choices: [ absent, present ]
+ type: str
+
+requirements:
+ - hcloud-python >= 1.10.0
+
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a basic subnetwork
+ hcloud_subnetwork:
+ network: my-network
+ ip_range: 10.0.0.0/16
+ network_zone: eu-central
+ type: cloud
+ state: present
+
+- name: Create a basic subnetwork
+ hcloud_subnetwork:
+ network: my-vswitch-network
+ ip_range: 10.0.0.0/24
+ network_zone: eu-central
+ type: vswitch
+ vswitch_id: 123
+ state: present
+
+- name: Ensure the subnetwork is absent (remove if needed)
+ hcloud_subnetwork:
+ network: my-network
+ ip_range: 10.0.0.0/8
+ network_zone: eu-central
+ type: cloud
+ state: absent
+"""
+
+RETURN = """
+hcloud_subnetwork:
+ description: One Subnet of a Network
+ returned: always
+ type: complex
+ contains:
+ network:
+ description: Name of the Network
+ type: str
+ returned: always
+ sample: my-network
+ ip_range:
+ description: IP range of the Network
+ type: str
+ returned: always
+ sample: 10.0.0.0/8
+ type:
+ description: Type of subnetwork
+ type: str
+ returned: always
+ sample: server
+ network_zone:
+ description: Name of network zone
+ type: str
+ returned: always
+ sample: eu-central
+ vswitch_id:
+ description: ID of the vswitch, null if not type vswitch
+ type: int
+ returned: always
+ sample: 123
+ gateway:
+ description: Gateway of the subnetwork
+ type: str
+ returned: always
+ sample: 10.0.0.1
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+ from hcloud.networks.domain import NetworkSubnet
+except ImportError:
+ APIException = None
+ NetworkSubnet = None
+
+
+class AnsibleHcloudSubnetwork(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_subnetwork")
+ self.hcloud_network = None
+ self.hcloud_subnetwork = None
+
+ 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),
+ "gateway": self.hcloud_subnetwork.gateway,
+ "vswitch_id": self.hcloud_subnetwork.vswitch_id,
+ }
+
+ def _get_network(self):
+ try:
+ self.hcloud_network = self.client.networks.get_by_name(self.module.params.get("network"))
+ self.hcloud_subnetwork = None
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _get_subnetwork(self):
+ subnet_ip_range = self.module.params.get("ip_range")
+ for subnetwork in self.hcloud_network.subnets:
+ if subnetwork.ip_range == subnet_ip_range:
+ self.hcloud_subnetwork = subnetwork
+
+ def _create_subnetwork(self):
+ params = {
+ "ip_range": self.module.params.get("ip_range"),
+ "type": self.module.params.get('type'),
+ "network_zone": self.module.params.get('network_zone')
+ }
+ if self.module.params.get('type') == NetworkSubnet.TYPE_VSWITCH:
+ self.module.fail_on_missing_params(
+ required_params=["vswitch_id"]
+ )
+ params["vswitch_id"] = self.module.params.get('vswitch_id')
+
+ if not self.module.check_mode:
+ try:
+ self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)).wait_until_finished()
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ self._mark_as_changed()
+ self._get_network()
+ self._get_subnetwork()
+
+ def present_subnetwork(self):
+ self._get_network()
+ self._get_subnetwork()
+ if self.hcloud_subnetwork is None:
+ self._create_subnetwork()
+
+ def delete_subnetwork(self):
+ self._get_network()
+ self._get_subnetwork()
+ if self.hcloud_subnetwork is not None and self.hcloud_network is not None:
+ if not self.module.check_mode:
+ self.hcloud_network.delete_subnet(self.hcloud_subnetwork).wait_until_finished()
+ self._mark_as_changed()
+ self.hcloud_subnetwork = None
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ network={"type": "str", "required": True},
+ network_zone={"type": "str", "required": True},
+ type={
+ "type": "str",
+ "required": True,
+ "choices": ["server", "cloud", "vswitch"]
+ },
+ ip_range={"type": "str", "required": True},
+ vswitch_id={"type": "int"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudSubnetwork.define_module()
+
+ hcloud = AnsibleHcloudSubnetwork(module)
+ state = module.params["state"]
+ if state == "absent":
+ hcloud.delete_subnetwork()
+ elif state == "present":
+ hcloud.present_subnetwork()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py
new file mode 100644
index 00000000..28359373
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume.py
@@ -0,0 +1,345 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_volume
+
+short_description: Create and manage block Volume on the Hetzner Cloud.
+
+
+description:
+ - Create, update and attach/detach block Volume on the Hetzner Cloud.
+
+author:
+ - Christopher Schmitt (@cschmitt-hcloud)
+
+options:
+ id:
+ description:
+ - The ID of the Hetzner Cloud Block Volume to manage.
+ - Only required if no volume I(name) is given
+ type: int
+ name:
+ description:
+ - The Name of the Hetzner Cloud Block Volume to manage.
+ - Only required if no volume I(id) is given or a volume does not exists.
+ type: str
+ size:
+ description:
+ - The size of the Block Volume in GB.
+ - Required if volume does not yet exists.
+ type: int
+ automount:
+ description:
+ - Automatically mount the Volume.
+ type: bool
+ default: False
+ format:
+ description:
+ - Automatically Format the volume on creation
+ - Can only be used in case the Volume does not exists.
+ type: str
+ choices: [xfs, ext4]
+ location:
+ description:
+ - Location of the Hetzner Cloud Volume.
+ - Required if no I(server) is given and Volume does not exists.
+ type: str
+ server:
+ description:
+ - Server Name the Volume should be assigned to.
+ - Required if no I(location) is given and Volume does not exists.
+ type: str
+ delete_protection:
+ description:
+ - Protect the Volume for deletion.
+ type: bool
+ labels:
+ description:
+ - User-defined key-value pairs.
+ type: dict
+ state:
+ description:
+ - State of the Volume.
+ default: present
+ choices: [absent, present]
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Create a Volume
+ hcloud_volume:
+ name: my-volume
+ location: fsn1
+ size: 100
+ state: present
+- name: Create a Volume and format it with ext4
+ hcloud_volume:
+ name: my-volume
+ location: fsn
+ format: ext4
+ size: 100
+ state: present
+- name: Mount a existing Volume and automount
+ hcloud_volume:
+ name: my-volume
+ server: my-server
+ automount: yes
+ state: present
+- name: Mount a existing Volume and automount
+ hcloud_volume:
+ name: my-volume
+ server: my-server
+ automount: yes
+ state: present
+- name: Ensure the Volume is absent (remove if needed)
+ hcloud_volume:
+ name: my-volume
+ state: absent
+"""
+
+RETURN = """
+hcloud_volume:
+ description: The block Volume
+ returned: Always
+ type: complex
+ contains:
+ id:
+ description: ID of the Volume
+ type: int
+ returned: Always
+ sample: 12345
+ name:
+ description: Name of the Volume
+ type: str
+ returned: Always
+ sample: my-volume
+ size:
+ description: Size in GB of the Volume
+ type: int
+ returned: Always
+ sample: 1337
+ linux_device:
+ description: Path to the device that contains the Volume.
+ returned: always
+ type: str
+ sample: /dev/disk/by-id/scsi-0HC_Volume_12345
+ version_added: "0.1.0"
+ location:
+ description: Location name where the Volume is located at
+ type: str
+ returned: Always
+ sample: "fsn1"
+ labels:
+ description: User-defined labels (key-value pairs)
+ type: dict
+ returned: Always
+ sample:
+ key: value
+ mylabel: 123
+ server:
+ description: Server name where the Volume is attached to
+ type: str
+ returned: Always
+ sample: "my-server"
+ delete_protection:
+ description: True if Volume is protected for deletion
+ type: bool
+ returned: always
+ sample: false
+ version_added: "0.1.0"
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud.volumes.domain import Volume
+ from hcloud.servers.domain import Server
+ import hcloud
+except ImportError:
+ APIException = None
+ Volume = None
+ Server = None
+
+
+class AnsibleHcloudVolume(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_volume")
+ self.hcloud_volume = None
+
+ def _prepare_result(self):
+ server_name = None
+ if self.hcloud_volume.server is not None:
+ server_name = self.hcloud_volume.server.name
+
+ return {
+ "id": to_native(self.hcloud_volume.id),
+ "name": to_native(self.hcloud_volume.name),
+ "size": self.hcloud_volume.size,
+ "location": to_native(self.hcloud_volume.location.name),
+ "labels": self.hcloud_volume.labels,
+ "server": to_native(server_name),
+ "linux_device": to_native(self.hcloud_volume.linux_device),
+ "delete_protection": self.hcloud_volume.protection["delete"],
+ }
+
+ def _get_volume(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_volume = self.client.volumes.get_by_id(
+ self.module.params.get("id")
+ )
+ else:
+ self.hcloud_volume = self.client.volumes.get_by_name(
+ self.module.params.get("name")
+ )
+ except hcloud.APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def _create_volume(self):
+ self.module.fail_on_missing_params(
+ required_params=["name", "size"]
+ )
+ params = {
+ "name": self.module.params.get("name"),
+ "size": self.module.params.get("size"),
+ "automount": self.module.params.get("automount"),
+ "format": self.module.params.get("format"),
+ "labels": self.module.params.get("labels")
+ }
+ if self.module.params.get("server") is not None:
+ params['server'] = self.client.servers.get_by_name(self.module.params.get("server"))
+ elif self.module.params.get("location") is not None:
+ params['location'] = self.client.locations.get_by_name(self.module.params.get("location"))
+ else:
+ self.module.fail_json(msg="server or location is required")
+
+ if not self.module.check_mode:
+ resp = self.client.volumes.create(**params)
+ resp.action.wait_until_finished()
+ [action.wait_until_finished() for action in resp.next_actions]
+ 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()
+
+ self._mark_as_changed()
+ self._get_volume()
+
+ def _update_volume(self):
+ try:
+ size = self.module.params.get("size")
+ if size:
+ if self.hcloud_volume.size < size:
+ if not self.module.check_mode:
+ self.hcloud_volume.resize(size).wait_until_finished()
+ self._mark_as_changed()
+ elif self.hcloud_volume.size > size:
+ self.module.warn("Shrinking of volumes is not supported")
+
+ server_name = self.module.params.get("server")
+ if server_name:
+ server = self.client.servers.get_by_name(server_name)
+ 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()
+ 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()
+ self._mark_as_changed()
+
+ labels = self.module.params.get("labels")
+ if labels is not None and labels != self.hcloud_volume.labels:
+ if not self.module.check_mode:
+ self.hcloud_volume.update(labels=labels)
+ self._mark_as_changed()
+
+ 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()
+ self._mark_as_changed()
+
+ self._get_volume()
+ except hcloud.APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ def present_volume(self):
+ self._get_volume()
+ if self.hcloud_volume is None:
+ self._create_volume()
+ else:
+ self._update_volume()
+
+ def delete_volume(self):
+ try:
+ self._get_volume()
+ if self.hcloud_volume is not None:
+ if not self.module.check_mode:
+ self.client.volumes.delete(self.hcloud_volume)
+ self._mark_as_changed()
+ self.hcloud_volume = None
+ except hcloud.APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ size={"type": "int"},
+ location={"type": "str"},
+ server={"type": "str"},
+ labels={"type": "dict"},
+ automount={"type": "bool", "default": False},
+ format={"type": "str",
+ "choices": ['xfs', 'ext4'],
+ },
+ delete_protection={"type": "bool"},
+ state={
+ "choices": ["absent", "present"],
+ "default": "present",
+ },
+ **Hcloud.base_module_arguments()
+ ),
+ required_one_of=[['id', 'name']],
+ mutually_exclusive=[["location", "server"]],
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudVolume.define_module()
+
+ hcloud = AnsibleHcloudVolume(module)
+ state = module.params.get("state")
+ if state == "absent":
+ module.fail_on_missing_params(
+ required_params=["name"]
+ )
+ hcloud.delete_volume()
+ else:
+ hcloud.present_volume()
+
+ module.exit_json(**hcloud.get_result())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py
new file mode 100644
index 00000000..3006ea5e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_facts.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_volume_info
+
+short_description: Gather infos about your Hetzner Cloud Volumes.
+
+description:
+ - Gather infos about your Hetzner Cloud Volumes.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Volume you want to get.
+ type: int
+ name:
+ description:
+ - The name of the Volume you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the Volume you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud Volume infos
+ hcloud_volume_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_volume_info
+"""
+
+RETURN = """
+hcloud_volume_info:
+ description: The Volume infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Volume
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Volume
+ returned: always
+ type: str
+ sample: my-volume
+ size:
+ description: Size of the Volume
+ returned: always
+ type: str
+ sample: 10
+ linux_device:
+ description: Path to the device that contains the Volume.
+ returned: always
+ type: str
+ sample: /dev/disk/by-id/scsi-0HC_Volume_12345
+ version_added: "0.1.0"
+ location:
+ description: Name of the location where the Volume resides in
+ returned: always
+ type: str
+ sample: fsn1
+ server:
+ description: Name of the server where the Volume is attached to
+ returned: always
+ type: str
+ sample: my-server
+ delete_protection:
+ description: True if the Volume is protected for deletion
+ returned: always
+ type: bool
+ version_added: "0.1.0"
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudVolumeInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_volume_info")
+ self.hcloud_volume_info = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for volume in self.hcloud_volume_info:
+ if volume is not None:
+ server_name = None
+ if volume.server is not None:
+ server_name = 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": to_native(server_name),
+ "linux_device": to_native(volume.linux_device),
+ "delete_protection": volume.protection["delete"],
+ })
+
+ return tmp
+
+ def get_volumes(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_volume_info = [self.client.volumes.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_volume_info = [self.client.volumes.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_volume_info = self.client.volumes.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_volume_info = self.client.volumes.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudVolumeInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_volume_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_volume_facts' module has been renamed to 'hcloud_volume_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudVolumeInfo(module)
+
+ hcloud.get_volumes()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_volume_facts': result['hcloud_volume_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_volume_info': result['hcloud_volume_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py
new file mode 100644
index 00000000..3006ea5e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/plugins/modules/hcloud_volume_info.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: hcloud_volume_info
+
+short_description: Gather infos about your Hetzner Cloud Volumes.
+
+description:
+ - Gather infos about your Hetzner Cloud Volumes.
+
+author:
+ - Lukas Kaemmerling (@LKaemmerling)
+
+options:
+ id:
+ description:
+ - The ID of the Volume you want to get.
+ type: int
+ name:
+ description:
+ - The name of the Volume you want to get.
+ type: str
+ label_selector:
+ description:
+ - The label selector for the Volume you want to get.
+ type: str
+extends_documentation_fragment:
+- hetzner.hcloud.hcloud
+
+'''
+
+EXAMPLES = """
+- name: Gather hcloud Volume infos
+ hcloud_volume_info:
+ register: output
+- name: Print the gathered infos
+ debug:
+ var: output.hcloud_volume_info
+"""
+
+RETURN = """
+hcloud_volume_info:
+ description: The Volume infos as list
+ returned: always
+ type: complex
+ contains:
+ id:
+ description: Numeric identifier of the Volume
+ returned: always
+ type: int
+ sample: 1937415
+ name:
+ description: Name of the Volume
+ returned: always
+ type: str
+ sample: my-volume
+ size:
+ description: Size of the Volume
+ returned: always
+ type: str
+ sample: 10
+ linux_device:
+ description: Path to the device that contains the Volume.
+ returned: always
+ type: str
+ sample: /dev/disk/by-id/scsi-0HC_Volume_12345
+ version_added: "0.1.0"
+ location:
+ description: Name of the location where the Volume resides in
+ returned: always
+ type: str
+ sample: fsn1
+ server:
+ description: Name of the server where the Volume is attached to
+ returned: always
+ type: str
+ sample: my-server
+ delete_protection:
+ description: True if the Volume is protected for deletion
+ returned: always
+ type: bool
+ version_added: "0.1.0"
+ labels:
+ description: User-defined labels (key-value pairs)
+ returned: always
+ type: dict
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils._text import to_native
+from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
+
+try:
+ from hcloud import APIException
+except ImportError:
+ APIException = None
+
+
+class AnsibleHcloudVolumeInfo(Hcloud):
+ def __init__(self, module):
+ Hcloud.__init__(self, module, "hcloud_volume_info")
+ self.hcloud_volume_info = None
+
+ def _prepare_result(self):
+ tmp = []
+
+ for volume in self.hcloud_volume_info:
+ if volume is not None:
+ server_name = None
+ if volume.server is not None:
+ server_name = 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": to_native(server_name),
+ "linux_device": to_native(volume.linux_device),
+ "delete_protection": volume.protection["delete"],
+ })
+
+ return tmp
+
+ def get_volumes(self):
+ try:
+ if self.module.params.get("id") is not None:
+ self.hcloud_volume_info = [self.client.volumes.get_by_id(
+ self.module.params.get("id")
+ )]
+ elif self.module.params.get("name") is not None:
+ self.hcloud_volume_info = [self.client.volumes.get_by_name(
+ self.module.params.get("name")
+ )]
+ elif self.module.params.get("label_selector") is not None:
+ self.hcloud_volume_info = self.client.volumes.get_all(
+ label_selector=self.module.params.get("label_selector"))
+ else:
+ self.hcloud_volume_info = self.client.volumes.get_all()
+
+ except APIException as e:
+ self.module.fail_json(msg=e.message)
+
+ @staticmethod
+ def define_module():
+ return AnsibleModule(
+ argument_spec=dict(
+ id={"type": "int"},
+ name={"type": "str"},
+ label_selector={"type": "str"},
+ **Hcloud.base_module_arguments()
+ ),
+ supports_check_mode=True,
+ )
+
+
+def main():
+ module = AnsibleHcloudVolumeInfo.define_module()
+
+ is_old_facts = module._name == 'hcloud_volume_facts'
+ if is_old_facts:
+ module.deprecate("The 'hcloud_volume_facts' module has been renamed to 'hcloud_volume_info', "
+ "and the renamed one no longer returns ansible_facts", version='2.0.0', collection_name="hetzner.hcloud")
+
+ hcloud = AnsibleHcloudVolumeInfo(module)
+
+ hcloud.get_volumes()
+ result = hcloud.get_result()
+ if is_old_facts:
+ ansible_info = {
+ 'hcloud_volume_facts': result['hcloud_volume_info']
+ }
+ module.exit_json(ansible_facts=ansible_info)
+ else:
+ ansible_info = {
+ 'hcloud_volume_info': result['hcloud_volume_info']
+ }
+ module.exit_json(**ansible_info)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/shippable.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/shippable.yml
new file mode 100644
index 00000000..885c3817
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/shippable.yml
@@ -0,0 +1,56 @@
+language: python
+
+python: 3.7
+env:
+ matrix:
+ - T=none
+
+matrix:
+ exclude:
+ - env: T=none
+ include:
+ - env: T=devel/sanity/1
+ python: 3.7
+ - env: T=devel/sanity/2
+ python: 3.7
+ - env: T=devel/sanity/3
+ python: 3.7
+ - env: T=devel/sanity/4
+ python: 3.7
+
+ - env: T=devel/hcloud/3.8/1
+ - env: T=devel/hcloud/3.8/2
+
+
+ - env: T=2.10/sanity/1
+ - env: T=2.10/sanity/2
+ - env: T=2.10/sanity/3
+ - env: T=2.10/sanity/4
+
+ - env: T=2.10/hcloud/3.8/1
+ - env: T=2.10/hcloud/3.8/2
+ - env: T=2.10/hcloud/3.8/3
+
+
+ - env: T=2.9/sanity/1
+ - env: T=2.9/sanity/2
+ - env: T=2.9/sanity/3
+ - env: T=2.9/sanity/4
+
+branches:
+ except:
+ - "*-patch-*"
+ - "revert-*-*"
+
+build:
+ ci:
+ - tests/utils/shippable/timing.sh tests/utils/shippable/shippable.sh $T
+
+integrations:
+ notifications:
+ - integrationName: email
+ type: email
+ on_success: never
+ on_failure: never
+ on_start: never
+ on_pull_request: never
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/.gitignore b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/.gitignore
new file mode 100644
index 00000000..ea1472ec
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/.gitignore
@@ -0,0 +1 @@
+output/
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/requirements.txt b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/requirements.txt
new file mode 100644
index 00000000..d3249def
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/requirements.txt
@@ -0,0 +1,2 @@
+netaddr
+hcloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/defaults/main.yml
new file mode 100644
index 00000000..49b6c6fb
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_certificate_name: "{{hcloud_prefix}}-integration"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/meta/main.yml
new file mode 100644
index 00000000..e531064c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/meta/main.yml
@@ -0,0 +1,5 @@
+dependencies:
+ - setup_selfsigned_certificate
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/tasks/main.yml
new file mode 100644
index 00000000..5f6376e9
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate/tasks/main.yml
@@ -0,0 +1,123 @@
+# Copyright: (c) 2020, 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: test missing required parameters on create certificate
+ hcloud_certificate:
+ name: "{{ hcloud_certificate_name }}"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create certificate
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: certificate, private_key"'
+
+- name: test create certificate with check mode
+ hcloud_certificate:
+ name: "{{ hcloud_certificate_name }}"
+ certificate: "{{ certificate_example_com }}"
+ private_key: "{{ certificate_example_com_key }}"
+ register: result
+ check_mode: yes
+- name: test create certificate with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test create certificate
+ hcloud_certificate:
+ name: "{{ hcloud_certificate_name }}"
+ certificate: "{{ certificate_example_com }}"
+ private_key: "{{ certificate_example_com_key }}"
+ labels:
+ key: value
+ my-label: label
+ register: certificate
+- name: verify create certificate
+ assert:
+ that:
+ - certificate is changed
+ - certificate.hcloud_certificate.name == "{{ hcloud_certificate_name }}"
+ - certificate.hcloud_certificate.domain_names[0] == "www.example.com"
+ - certificate.hcloud_certificate.labels.key == "value"
+
+- name: test create certificate idempotence
+ hcloud_certificate:
+ name: "{{ hcloud_certificate_name }}"
+ certificate: "{{ certificate_example_com }}"
+ private_key: "{{ certificate_example_com_key }}"
+ register: result
+- name: verify create certificate idempotence
+ assert:
+ that:
+ - result is not changed
+
+- name: test update certificate with check mode
+ hcloud_certificate:
+ id: "{{ certificate.hcloud_certificate.id }}"
+ name: "changed-{{ hcloud_certificate_name }}"
+ register: result
+ check_mode: yes
+- name: test create certificate with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test update certificate
+ hcloud_certificate:
+ id: "{{ certificate.hcloud_certificate.id }}"
+ name: "changed-{{ hcloud_certificate_name }}"
+ labels:
+ key: value
+ register: result
+- name: test update certificate
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_certificate.name == "changed-{{ hcloud_certificate_name }}"
+
+- name: test update certificate with same labels
+ hcloud_certificate:
+ id: "{{ certificate.hcloud_certificate.id }}"
+ name: "changed-{{ hcloud_certificate_name }}"
+ labels:
+ key: value
+ register: result
+- name: test update certificate with same labels
+ assert:
+ that:
+ - result is not changed
+
+- name: test update certificate with other labels
+ hcloud_certificate:
+ id: "{{ certificate.hcloud_certificate.id }}"
+ name: "changed-{{ hcloud_certificate_name }}"
+ labels:
+ key: value
+ test: "val123"
+ register: result
+- name: test update certificate with other labels
+ assert:
+ that:
+ - result is changed
+
+- name: test rename certificate
+ hcloud_certificate:
+ id: "{{ certificate.hcloud_certificate.id }}"
+ name: "{{ hcloud_certificate_name }}"
+ register: result
+- name: test rename certificate
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_certificate.name == "{{ hcloud_certificate_name }}"
+
+- name: absent certificate
+ hcloud_certificate:
+ id: "{{ certificate.hcloud_certificate.id }}"
+ state: absent
+ register: result
+- name: verify absent server
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/defaults/main.yml
new file mode 100644
index 00000000..6205b19b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_certificate_name: "always-there-cert"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/meta/main.yml
new file mode 100644
index 00000000..f830a9da
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/meta/main.yml
@@ -0,0 +1,2 @@
+collections:
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/tasks/main.yml
new file mode 100644
index 00000000..7dc4eb72
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_certificate_info/tasks/main.yml
@@ -0,0 +1,39 @@
+# 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: test gather hcloud certificate infos in check mode
+ hcloud_certificate_info:
+ register: hcloud_certificate
+ check_mode: yes
+- name: verify test gather hcloud certificate infos in check mode
+ assert:
+ that:
+ - hcloud_certificate.hcloud_certificate_info| list | count >= 1
+
+- name: test gather hcloud certificate infos
+ hcloud_certificate_info:
+ register: hcloud_certificate
+ check_mode: yes
+- name: verify test gather hcloud certificate infos
+ assert:
+ that:
+ - hcloud_certificate.hcloud_certificate_info| list | count >= 1
+
+- name: test gather hcloud certificate infos with correct label selector
+ hcloud_certificate_info:
+ label_selector: "key=value"
+ register: hcloud_certificate
+- name: verify test gather hcloud certificate infos with correct label selector
+ assert:
+ that:
+ - hcloud_certificate.hcloud_certificate_info|selectattr('name','equalto','{{ hcloud_certificate_name }}') | list | count == 1
+
+- name: test gather hcloud certificate infos with wrong label selector
+ hcloud_certificate_info:
+ label_selector: "key!=value"
+ register: hcloud_certificate
+- name: verify test gather hcloud certificate infos with wrong label selector
+ assert:
+ that:
+ - hcloud_certificate.hcloud_certificate_info | list | count == 0
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/defaults/main.yml
new file mode 100644
index 00000000..b9e045f4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_datacenter_name: "fsn1-dc14"
+hcloud_datacenter_id: 4
+hcloud_location_name: "fsn1"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/tasks/main.yml
new file mode 100644
index 00000000..7f49b040
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_datacenter_info/tasks/main.yml
@@ -0,0 +1,40 @@
+# 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: test gather hcloud datacenter infos
+ hcloud_datacenter_info:
+ register: hcloud_datacenters
+
+- name: verify test gather hcloud datacenter infos
+ assert:
+ that:
+ - hcloud_datacenters.hcloud_datacenter_info| list | count == 3
+
+- name: test gather hcloud datacenter infos in check mode
+ hcloud_datacenter_info:
+ register: hcloud_datacenters
+ check_mode: yes
+
+- name: verify test gather hcloud datacenter infos in check mode
+ assert:
+ that:
+ - hcloud_datacenters.hcloud_datacenter_info| list | count == 3
+
+
+- name: test gather hcloud datacenter infos with correct name
+ hcloud_datacenter_info:
+ name: "{{hcloud_datacenter_name}}"
+ register: hcloud_datacenter
+- name: verify test gather hcloud datacenter with correct name
+ assert:
+ that:
+ - hcloud_datacenter.hcloud_datacenter_info|selectattr('name','equalto','{{ hcloud_datacenter_name }}') |selectattr('location','equalto','{{ hcloud_location_name }}') | list | count == 1
+
+- name: test gather hcloud datacenter infos with correct id
+ hcloud_datacenter_info:
+ id: "{{hcloud_datacenter_id}}"
+ register: hcloud_datacenter
+- name: verify test gather hcloud datacenter with correct id
+ assert:
+ that:
+ - hcloud_datacenter.hcloud_datacenter_info|selectattr('name','equalto','{{ hcloud_datacenter_name }}') | list | count == 1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/defaults/main.yml
new file mode 100644
index 00000000..fc60d281
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_floating_ip_name: "{{hcloud_prefix}}-integration"
+hcloud_server_name: "{{hcloud_prefix}}-fip-tests" \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/tasks/main.yml
new file mode 100644
index 00000000..70f23e33
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip/tasks/main.yml
@@ -0,0 +1,443 @@
+# 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 server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: started
+ location: "fsn1"
+ register: main_server
+- name: verify setup server
+ assert:
+ that:
+ - main_server is changed
+
+- name: setup another server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}2"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: started
+ register: main_server2
+- name: verify setup another server
+ assert:
+ that:
+ - main_server2 is changed
+
+- name: test missing type parameter on create Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing type parameter on create Floating IP
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: type"'
+
+- name: test missing required parameters on create Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create Floating IP
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "one of the following is required: home_location, server"'
+
+- name: test missing type parameter on delete Floating IP
+ hcloud_floating_ip:
+ type: ipv4
+ home_location: "fsn1"
+ state: "absent"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing type parameter on delete Floating IP
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "one of the following is required: id, name"'
+
+- name: test create Floating IP with check mode
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "Web Server"
+ type: ipv4
+ home_location: "fsn1"
+ register: floatingIP
+ check_mode: yes
+- name: verify test create Floating IP with check mode
+ assert:
+ that:
+ - floatingIP is changed
+
+- name: test create Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "Web Server"
+ type: ipv4
+ home_location: "fsn1"
+ register: floatingIP
+- name: verify test create Floating IP
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.name ==hcloud_floating_ip_name
+ - floatingIP.hcloud_floating_ip.description == "Web Server"
+ - floatingIP.hcloud_floating_ip.home_location == "fsn1"
+
+- name: test create Floating IP idempotency
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "Web Server"
+ type: ipv4
+ home_location: "fsn1"
+ register: floatingIP
+- name: verify test create Floating IP idempotency
+ assert:
+ that:
+ - floatingIP is not changed
+
+- name: test update Floating IP with check mode
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "changed-description"
+ type: ipv4
+ home_location: "fsn1"
+ check_mode: yes
+ register: floatingIP
+- name: verify test create Floating IP with check mode
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.description == "Web Server"
+
+- name: test update Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "changed-description"
+ type: ipv4
+ home_location: "fsn1"
+ labels:
+ key: value
+ register: floatingIP
+- name: verify test update Floating IP
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.description == "changed-description"
+
+- name: test update Floating IP idempotency
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "changed-description"
+ type: ipv4
+ home_location: "fsn1"
+ labels:
+ key: value
+ register: floatingIP
+- name: verify test update Floating IP idempotency
+ assert:
+ that:
+ - floatingIP is not changed
+
+- name: test update Floating IP with same labels
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: "fsn1"
+ labels:
+ key: value
+ register: floatingIP
+- name: verify test update Floating IP with same labels
+ assert:
+ that:
+ - floatingIP is not changed
+
+- name: test update Floating IP with other labels
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: "fsn1"
+ labels:
+ key: value
+ other: label
+ register: floatingIP
+- name: verify test update Floating IP with other labels
+ assert:
+ that:
+ - floatingIP is changed
+
+- name: test update Floating IP with other labels in different order
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: "fsn1"
+ labels:
+ other: label
+ key: value
+ register: floatingIP
+- name: verify test update Floating IP with other labels in different order
+ assert:
+ that:
+ - floatingIP is not changed
+
+- name: test assign Floating IP with checkmode
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "changed-description"
+ type: ipv4
+ server: "{{ main_server.hcloud_server.name }}"
+ check_mode: yes
+ register: floatingIP
+- name: verify test assign Floating IP with checkmode
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.server != "{{ main_server.hcloud_server.name }}"
+
+- name: test assign Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "changed-description"
+ type: ipv4
+ server: "{{ main_server.hcloud_server.name }}"
+ register: floatingIP
+- name: verify test assign Floating IP
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.server == "{{ main_server.hcloud_server.name }}"
+
+- name: test assign Floating IP idempotency
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ description: "changed-description"
+ type: ipv4
+ server: "{{ main_server.hcloud_server.name }}"
+ register: floatingIP
+- name: verify test unassign Floating IPidempotency
+ assert:
+ that:
+ - floatingIP is not changed
+
+- name: test unassign Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: "fsn1"
+ register: floatingIP
+- name: verify test unassign Floating IP
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.server != "{{ main_server.hcloud_server.name }}"
+
+- name: test unassign Floating IP idempotency
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: "fsn1"
+ register: floatingIP
+- name: verify test unassign Floating IPidempotency
+ assert:
+ that:
+ - floatingIP is not changed
+
+- name: test assign Floating IP again
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ server: "{{ main_server.hcloud_server.name }}"
+ register: floatingIP
+- name: verify test assign Floating IP again
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.server == "{{ main_server.hcloud_server.name }}"
+
+- name: test already assigned Floating IP assign without force
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ server: "{{ main_server2.hcloud_server.name }}"
+ register: floatingIP
+- name: verify test already assigned Floating IP assign without force
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.server == "{{ main_server.hcloud_server.name }}"
+
+- name: test already assigned Floating IP assign with force
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ force: yes
+ server: "{{ main_server2.hcloud_server.name }}"
+ register: floatingIP
+- name: verify test already assigned Floating IP assign with force
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.server == "{{ main_server2.hcloud_server.name }}"
+
+- name: test update Floating IP delete protection
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ delete_protection: true
+ register: floatingIP
+- name: verify update Floating IP delete protection
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.delete_protection is sameas true
+
+- name: test update Floating IP delete protection idempotency
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ delete_protection: true
+ register: floatingIP
+- name: verify update Floating IP delete protection idempotency
+ assert:
+ that:
+ - floatingIP is not changed
+ - floatingIP.hcloud_floating_ip.delete_protection is sameas true
+
+- name: test Floating IP without delete protection set to be idempotent
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ register: floatingIP
+- name: verify Floating IP without delete protection set to be idempotent
+ assert:
+ that:
+ - floatingIP is not changed
+ - floatingIP.hcloud_floating_ip.delete_protection is sameas true
+
+- name: test delete Floating IP fails if it is protected
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: "absent"
+ register: result
+ ignore_errors: yes
+- name: verify test delete floating ip
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "Floating IP deletion is protected"'
+
+- name: test update Floating IP delete protection
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ delete_protection: false
+ register: floatingIP
+- name: verify update Floating IP delete protection
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.delete_protection is sameas false
+
+- name: test delete floating ip
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: "absent"
+ register: result
+- name: verify test delete floating ip
+ assert:
+ that:
+ - result is changed
+
+- name: test create ipv6 floating ip
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv6
+ home_location: "fsn1"
+ state: "present"
+ register: result
+- name: verify test create ipv6 floating ip
+ assert:
+ that:
+ - result is changed
+
+- name: test delete ipv6 floating ip
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: "absent"
+ register: result
+- name: verify test delete ipv6 floating ip
+ assert:
+ that:
+ - result is changed
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is changed
+- name: cleanup another server
+ hcloud_server:
+ name: "{{ main_server2.hcloud_server.name }}"
+ state: absent
+ register: result
+- name: verify cleanup another server
+ assert:
+ that:
+ - result is changed
+
+- name: test create Floating IP with delete protection
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: fsn1
+ delete_protection: true
+ register: floatingIP
+- name: verify create Floating IP with delete protection
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.delete_protection is sameas true
+
+- name: test delete Floating IP fails if it is protected
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: "absent"
+ register: result
+ ignore_errors: yes
+- name: verify test delete floating ip
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "Floating IP deletion is protected"'
+
+- name: test update Floating IP delete protection
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ delete_protection: false
+ register: floatingIP
+- name: verify update Floating IP delete protection
+ assert:
+ that:
+ - floatingIP is changed
+ - floatingIP.hcloud_floating_ip.delete_protection is sameas false
+
+- name: test delete floating ip
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: "absent"
+ register: result
+- name: verify test delete floating ip
+ assert:
+ that:
+ - result is changed
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/defaults/main.yml
new file mode 100644
index 00000000..2a21de73
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_floating_ip_name: "{{hcloud_prefix}}-integration"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/tasks/main.yml
new file mode 100644
index 00000000..9ca1c2a4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_floating_ip_info/tasks/main.yml
@@ -0,0 +1,87 @@
+# 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 floating ip is absent
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: absent
+
+- name: setup floating ip
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ home_location: "fsn1"
+ type: ipv4
+ labels:
+ key: value
+ register: test_floating_ip
+
+- name: verify setup floating ip
+ assert:
+ that:
+ - test_floating_ip is changed
+
+- name: test gather hcloud floating ip infos
+ hcloud_floating_ip_info:
+ register: hcloud_floating_ips
+- name: verify test gather hcloud floating ip infos
+ assert:
+ that:
+ - hcloud_floating_ips.hcloud_floating_ip_info| list | count >= 1
+
+- name: test gather hcloud floating ip infos in check mode
+ hcloud_floating_ip_info:
+ check_mode: yes
+ register: hcloud_floating_ips
+
+- name: verify test gather hcloud floating ip infos in check mode
+ assert:
+ that:
+ - hcloud_floating_ips.hcloud_floating_ip_info| list | count >= 1
+
+
+- name: test gather hcloud floating ip infos with correct label selector
+ hcloud_floating_ip_info:
+ label_selector: "key=value"
+ register: hcloud_floating_ips
+- name: verify test gather hcloud floating ip with correct label selector
+ assert:
+ that:
+ - hcloud_floating_ips.hcloud_floating_ip_info|selectattr('name','equalto','{{ test_floating_ip.hcloud_floating_ip.name }}') | list | count == 1
+
+- name: test gather hcloud floating ip infos with wrong label selector
+ hcloud_floating_ip_info:
+ label_selector: "key!=value"
+ register: hcloud_floating_ips
+- name: verify test gather hcloud floating ip with wrong label selector
+ assert:
+ that:
+ - hcloud_floating_ips.hcloud_floating_ip_info | list | count == 0
+
+- name: test gather hcloud floating ip infos with correct id
+ hcloud_floating_ip_info:
+ id: "{{test_floating_ip.hcloud_floating_ip.id}}"
+ register: hcloud_floating_ips
+- name: verify test gather hcloud floating ip with correct id
+ assert:
+ that:
+ - hcloud_floating_ips.hcloud_floating_ip_info|selectattr('name','equalto','{{ test_floating_ip.hcloud_floating_ip.name }}') | list | count == 1
+
+- name: test gather hcloud floating ip infos with wrong id
+ hcloud_floating_ip_info:
+ id: "{{test_floating_ip.hcloud_floating_ip.id}}1"
+ register: result
+ ignore_errors: yes
+- name: verify test gather hcloud floating ip with wrong id
+ assert:
+ that:
+ - result is failed
+
+- name: cleanup
+ hcloud_floating_ip:
+ id: "{{ test_floating_ip.hcloud_floating_ip.id }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/defaults/main.yml
new file mode 100644
index 00000000..ddca3328
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_test_image_name: "always-there-snapshot"
+hcloud_test_image_id: 10164049
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/tasks/main.yml
new file mode 100644
index 00000000..503d5b78
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_image_info/tasks/main.yml
@@ -0,0 +1,62 @@
+# 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: test gather hcloud image infos with type system
+ hcloud_image_info:
+ register: hcloud_images
+- name: verify test gather hcloud image infos in check mode
+ assert:
+ that:
+ - hcloud_images.hcloud_image_info| list | count > 2
+
+- name: test gather hcloud image infos in check mode
+ hcloud_image_info:
+ check_mode: yes
+ register: hcloud_images
+
+- name: verify test gather hcloud image infos in check mode
+ assert:
+ that:
+ - hcloud_images.hcloud_image_info| list | count > 2
+
+
+- name: test gather hcloud image infos with correct label selector
+ hcloud_image_info:
+ label_selector: "key=value"
+ type: snapshot
+ register: hcloud_images
+- name: verify test gather hcloud image with correct label selector
+ assert:
+ that:
+ - hcloud_images.hcloud_image_info|selectattr('description','equalto','{{ hcloud_test_image_name }}') | list | count == 1
+
+- name: test gather hcloud image infos with wrong label selector
+ hcloud_image_info:
+ label_selector: "key!=value"
+ type: snapshot
+ register: hcloud_images
+- name: verify test gather hcloud image with wrong label selector
+ assert:
+ that:
+ - hcloud_images.hcloud_image_info | list | count == 0
+
+- name: test gather hcloud image infos with correct id
+ hcloud_image_info:
+ id: "{{hcloud_test_image_id}}"
+ type: snapshot
+ register: hcloud_images
+- name: verify test gather hcloud image with correct id
+ assert:
+ that:
+ - hcloud_images.hcloud_image_info|selectattr('description','equalto','{{ hcloud_test_image_name }}') | list | count == 1
+
+- name: test gather hcloud image infos with wrong id
+ hcloud_image_info:
+ id: "{{hcloud_test_image_id}}1"
+ type: snapshot
+ ignore_errors: yes
+ register: result
+- name: verify test gather hcloud image with wrong id
+ assert:
+ that:
+ - result is failed
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/defaults/main.yml
new file mode 100644
index 00000000..38e96f6d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/defaults/main.yml
@@ -0,0 +1,5 @@
+# Copyright: (c) 2020, 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)
+---
+hcloud_prefix: "tests"
+hcloud_load_balancer_name: "{{hcloud_prefix}}-integration"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/tasks/main.yml
new file mode 100644
index 00000000..a25e550d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer/tasks/main.yml
@@ -0,0 +1,247 @@
+# Copyright: (c) 2020, 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
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+ register: result
+- name: verify setup
+ assert:
+ that:
+ - result is success
+- name: test missing required parameters on create Load Balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create Load Balancer
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: load_balancer_type"'
+
+- name: test create Load Balancer with check mode
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ state: present
+ register: result
+ check_mode: yes
+- name: test create Load Balancer with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test create Load Balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ state: present
+ register: main_load_balancer
+- name: verify create Load Balancer
+ assert:
+ that:
+ - main_load_balancer is changed
+ - main_load_balancer.hcloud_load_balancer.name == "{{ hcloud_load_balancer_name }}"
+ - main_load_balancer.hcloud_load_balancer.load_balancer_type == "lb11"
+
+- name: test create Load Balancer idempotence
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ state: present
+ register: result
+- name: verify create Load Balancer idempotence
+ assert:
+ that:
+ - result is not changed
+
+- name: test change Load Balancer type
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ load_balancer_type: lb21
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify change Load Balancer type
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_load_balancer.load_balancer_type == "lb21"
+
+- name: test Load Balancer without type set to be idempotent
+ hcloud_load_balancer:
+ name: "{{hcloud_load_balancer_name}}"
+ register: result_after_test
+- name: verify test Load Balancer without type set to be idempotent
+ assert:
+ that:
+ - result_after_test is not changed
+ - result_after_test.hcloud_load_balancer.load_balancer_type == "lb21"
+
+- name: test update Load Balancer protection
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ delete_protection: true
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify update Load Balancer protection
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_load_balancer.delete_protection is sameas true
+
+- name: test Load Balancer without protection set to be idempotent
+ hcloud_load_balancer:
+ name: "{{hcloud_load_balancer_name}}"
+ register: result_after_test
+- name: verify test Load Balancer without protection set to be idempotent
+ assert:
+ that:
+ - result_after_test is not changed
+ - result_after_test.hcloud_load_balancer.delete_protection is sameas true
+
+- name: test delete Load Balancer fails if it is protected
+ hcloud_load_balancer:
+ name: "{{hcloud_load_balancer_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete Load Balancer fails if it is protected
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "load balancer deletion is protected"'
+
+- name: test remove Load Balancer protection
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ delete_protection: false
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify remove Load Balancer protection
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_load_balancer.delete_protection is sameas false
+
+- name: absent Load Balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+ register: result
+- name: verify absent Load Balancer
+ assert:
+ that:
+ - result is success
+
+- name: test create Load Balancer with labels
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ labels:
+ key: value
+ mylabel: "val123"
+ state: present
+ register: main_load_balancer
+- name: verify create Load Balancer with labels
+ assert:
+ that:
+ - main_load_balancer is changed
+ - main_load_balancer.hcloud_load_balancer.labels.key == "value"
+ - main_load_balancer.hcloud_load_balancer.labels.mylabel == "val123"
+
+- name: test update Load Balancer with labels
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ labels:
+ key: other
+ mylabel: "val123"
+ state: present
+ register: main_load_balancer
+- name: verify update Load Balancer with labels
+ assert:
+ that:
+ - main_load_balancer is changed
+ - main_load_balancer.hcloud_load_balancer.labels.key == "other"
+ - main_load_balancer.hcloud_load_balancer.labels.mylabel == "val123"
+
+- name: test update Load Balancer with labels in other order
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ labels:
+ mylabel: "val123"
+ key: other
+ state: present
+ register: main_load_balancer
+- name: verify update Load Balancer with labels in other order
+ assert:
+ that:
+ - main_load_balancer is not changed
+
+- name: cleanup with labels
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
+
+- name: test create Load Balancer with delete protection
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ delete_protection: true
+ register: main_load_balancer
+- name: verify create Load Balancer with delete protection
+ assert:
+ that:
+ - main_load_balancer is changed
+ - main_load_balancer.hcloud_load_balancer.delete_protection is sameas true
+
+- name: test delete Load Balancer fails if it is protected
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: "absent"
+ register: result
+ ignore_errors: yes
+- name: verify test delete Load Balancer
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "load balancer deletion is protected"'
+
+- name: test update Load Balancer delete protection
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ delete_protection: false
+ register: main_load_balancer
+- name: verify update Load Balancer delete protection
+ assert:
+ that:
+ - main_load_balancer is changed
+ - main_load_balancer.hcloud_load_balancer.delete_protection is sameas false
+
+- name: test delete Load Balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: "absent"
+ register: result
+- name: verify test delete Load Balancer
+ assert:
+ that:
+ - result is changed
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/defaults/main.yml
new file mode 100644
index 00000000..b5e53281
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_load_balancer_name: "{{hcloud_prefix}}-integration"
+hcloud_server_name: "{{hcloud_prefix}}-lb-info"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/tasks/main.yml
new file mode 100644
index 00000000..9e652885
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_info/tasks/main.yml
@@ -0,0 +1,128 @@
+# 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 Load Balancer is absent
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+- name: setup server
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ server_type: cx11
+ image: ubuntu-20.04
+ state: started
+ register: server
+- name: verify setup server
+ assert:
+ that:
+ - server is success
+- name: setup Load Balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ load_balancer_type: lb11
+ network_zone: eu-central
+ labels:
+ key: value
+ register: test_load_balancer
+
+- name: verify setup Load Balancer
+ assert:
+ that:
+ - test_load_balancer is changed
+
+- name: test create load_balancer target
+ hcloud_load_balancer_target:
+ type: "server"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: load_balancer_target
+- name: verify create load_balancer target
+ assert:
+ that:
+ - load_balancer_target is success
+- name: test create load_balancer service
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "http"
+ listen_port: 80
+ state: present
+ register: load_balancer_service
+- name: verify create load_balancer service
+ assert:
+ that:
+ - load_balancer_service is success
+
+- name: test gather hcloud Load Balancer infos
+ hcloud_load_balancer_info:
+ id: "{{test_load_balancer.hcloud_load_balancer.id}}"
+ register: hcloud_load_balancers
+- name: verify test gather hcloud Load Balancer infos
+ assert:
+ that:
+ - hcloud_load_balancers.hcloud_load_balancer_info| list | count >= 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].targets | list | count == 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].targets | selectattr('type','equalto','server') | list | count == 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].targets | selectattr('server','equalto','{{ hcloud_server_name }}') | list | count == 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].services | list | count == 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].services | selectattr('protocol','equalto','http') | list | count == 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].services | selectattr('listen_port','equalto',80) | list | count == 1
+ - hcloud_load_balancers.hcloud_load_balancer_info[0].services | selectattr('destination_port','equalto',80) | list | count == 1
+
+- name: test gather hcloud Load Balancer infos in check mode
+ hcloud_load_balancer_info:
+ check_mode: yes
+ register: hcloud_load_balancers
+
+- name: verify test gather hcloud Load Balancer infos in check mode
+ assert:
+ that:
+ - hcloud_load_balancers.hcloud_load_balancer_info| list | count >= 1
+
+
+- name: test gather hcloud Load Balancer infos with correct label selector
+ hcloud_load_balancer_info:
+ label_selector: "key=value"
+ register: hcloud_load_balancers
+- name: verify test gather hcloud Load Balancer with correct label selector
+ assert:
+ that:
+ - hcloud_load_balancers.hcloud_load_balancer_info|selectattr('name','equalto','{{ test_load_balancer.hcloud_load_balancer.name }}') | list | count == 1
+
+- name: test gather hcloud Load Balancer infos with wrong label selector
+ hcloud_load_balancer_info:
+ label_selector: "key!=value"
+ register: hcloud_load_balancers
+- name: verify test gather hcloud Load Balancer with wrong label selector
+ assert:
+ that:
+ - hcloud_load_balancers.hcloud_load_balancer_info | list | count == 0
+
+- name: test gather hcloud Load Balancer infos with correct id
+ hcloud_load_balancer_info:
+ id: "{{test_load_balancer.hcloud_load_balancer.id}}"
+ register: hcloud_load_balancers
+- name: verify test gather hcloud Load Balancer with correct id
+ assert:
+ that:
+ - hcloud_load_balancers.hcloud_load_balancer_info|selectattr('name','equalto','{{ test_load_balancer.hcloud_load_balancer.name }}') | list | count == 1
+
+- name: test gather hcloud Load Balancer infos with wrong id
+ hcloud_load_balancer_info:
+ id: "{{test_load_balancer.hcloud_load_balancer.id}}1"
+ register: result
+ ignore_errors: yes
+- name: verify test gather hcloud Load Balancer with wrong id
+ assert:
+ that:
+ - result is failed
+
+- name: cleanup
+ hcloud_load_balancer:
+ id: "{{ test_load_balancer.hcloud_load_balancer.id }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/defaults/main.yml
new file mode 100644
index 00000000..8747bff4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_network_name: "{{hcloud_prefix}}-load_balancer-network"
+hcloud_load_balancer_name: "{{hcloud_prefix}}-load_balancer-network"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/tasks/main.yml
new file mode 100644
index 00000000..76788ed8
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_network/tasks/main.yml
@@ -0,0 +1,155 @@
+# 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
+ 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
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "cloud"
+ network_zone: "eu-central"
+ state: present
+ register: subnetwork
+- name: verify subnetwork
+ assert:
+ that:
+ - subnetwork is success
+
+- name: setup load_balancer
+ hcloud_load_balancer:
+ name: "{{hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ state: present
+ location: "fsn1"
+ register: load_balancer
+- name: verify setup load_balancer
+ assert:
+ that:
+ - load_balancer is success
+
+- name: test missing required parameters on create load_balancer network
+ hcloud_load_balancer_network:
+ state: present
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create load_balancer network
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: load_balancer, network"'
+
+- name: test create load_balancer network with checkmode
+ hcloud_load_balancer_network:
+ network: "{{ hcloud_network_name }}"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ state: present
+ register: result
+ check_mode: yes
+- name: verify test create load_balancer network with checkmode
+ assert:
+ that:
+ - result is changed
+
+- name: test create load_balancer network
+ hcloud_load_balancer_network:
+ network: "{{ hcloud_network_name }}"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ state: present
+ register: load_balancerNetwork
+- name: verify create load_balancer network
+ assert:
+ that:
+ - load_balancerNetwork is changed
+ - load_balancerNetwork.hcloud_load_balancer_network.network == hcloud_network_name
+ - load_balancerNetwork.hcloud_load_balancer_network.load_balancer == hcloud_load_balancer_name
+
+- name: test create load_balancer network idempotency
+ hcloud_load_balancer_network:
+ network: "{{ hcloud_network_name }}"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ state: present
+ register: load_balancerNetwork
+- name: verify create load_balancer network idempotency
+ assert:
+ that:
+ - load_balancerNetwork is not changed
+
+- name: test absent load_balancer network
+ hcloud_load_balancer_network:
+ network: "{{ hcloud_network_name }}"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ state: absent
+ register: result
+- name: verify test absent load_balancer network
+ assert:
+ that:
+ - result is changed
+
+- name: test create load_balancer network with specified ip
+ hcloud_load_balancer_network:
+ network: "{{ hcloud_network_name }}"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ ip: "10.0.0.2"
+ state: present
+ register: load_balancerNetwork
+- name: verify create load_balancer network with specified ip
+ assert:
+ that:
+ - load_balancerNetwork is changed
+ - load_balancerNetwork.hcloud_load_balancer_network.network == hcloud_network_name
+ - load_balancerNetwork.hcloud_load_balancer_network.load_balancer == hcloud_load_balancer_name
+ - load_balancerNetwork.hcloud_load_balancer_network.ip == "10.0.0.2"
+
+- name: cleanup create load_balancer network with specified ip
+ hcloud_load_balancer_network:
+ network: "{{ hcloud_network_name }}"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ state: absent
+ register: result
+- name: verify cleanup create load_balancer network with specified ip
+ assert:
+ that:
+ - result is changed
+
+- name: cleanup load_balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+ register: result
+- name: verify cleanup load_balancer
+ assert:
+ that:
+ - result is success
+
+- name: cleanup subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "cloud"
+ network_zone: "eu-central"
+ state: absent
+ register: result
+- name: verify cleanup subnetwork
+ assert:
+ that:
+ - result is changed
+
+- name: cleanup
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/defaults/main.yml
new file mode 100644
index 00000000..0876695b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_load_balancer_name: "{{hcloud_prefix}}-load_balancer-target"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/tasks/main.yml
new file mode 100644
index 00000000..101effc0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_service/tasks/main.yml
@@ -0,0 +1,112 @@
+# 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 load_balancer
+ hcloud_load_balancer:
+ name: "{{hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ state: present
+ location: "fsn1"
+ register: load_balancer
+- name: verify setup load_balancer
+ assert:
+ that:
+ - load_balancer is success
+
+- name: test create load_balancer service with checkmode
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "http"
+ listen_port: 80
+ state: present
+ register: result
+ check_mode: yes
+- name: verify test create load_balancer service with checkmode
+ assert:
+ that:
+ - result is changed
+
+- name: test create load_balancer service
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "http"
+ listen_port: 80
+ state: present
+ register: load_balancer_service
+- name: verify create load_balancer service
+ assert:
+ that:
+ - load_balancer_service is changed
+ - load_balancer_service.hcloud_load_balancer_service.protocol == "http"
+ - load_balancer_service.hcloud_load_balancer_service.listen_port == 80
+ - load_balancer_service.hcloud_load_balancer_service.destination_port == 80
+ - load_balancer_service.hcloud_load_balancer_service.proxyprotocol is sameas false
+
+- name: test create load_balancer service idempotency
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "http"
+ listen_port: 80
+ state: present
+ register: load_balancer_service
+- name: verify create load_balancer service idempotency
+ assert:
+ that:
+ - load_balancer_service is not changed
+
+- name: test update load_balancer service
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "tcp"
+ listen_port: 80
+ state: present
+ register: load_balancer_service
+- name: verify create load_balancer service
+ assert:
+ that:
+ - load_balancer_service is changed
+ - load_balancer_service.hcloud_load_balancer_service.protocol == "tcp"
+ - load_balancer_service.hcloud_load_balancer_service.listen_port == 80
+ - load_balancer_service.hcloud_load_balancer_service.destination_port == 80
+ - load_balancer_service.hcloud_load_balancer_service.proxyprotocol is sameas false
+
+- name: test absent load_balancer service
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "http"
+ listen_port: 80
+ state: absent
+ register: result
+- name: verify test absent load_balancer service
+ assert:
+ that:
+ - result is changed
+
+- name: test create load_balancer service with http
+ hcloud_load_balancer_service:
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ protocol: "http"
+ listen_port: 80
+ http:
+ cookie_name: "Test"
+ sticky_sessions: yes
+ state: present
+ register: load_balancer_service
+- name: verify create load_balancer service
+ assert:
+ that:
+ - load_balancer_service is changed
+ - load_balancer_service.hcloud_load_balancer_service.protocol == "http"
+ - load_balancer_service.hcloud_load_balancer_service.listen_port == 80
+ - load_balancer_service.hcloud_load_balancer_service.destination_port == 80
+ - load_balancer_service.hcloud_load_balancer_service.proxyprotocol is sameas false
+
+- name: cleanup load_balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+ register: result
+- name: verify cleanup load_balancer
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/defaults/main.yml
new file mode 100644
index 00000000..bb38666b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/defaults/main.yml
@@ -0,0 +1,7 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_server_name: "{{hcloud_prefix}}-lb-target"
+hcloud_load_balancer_name: "{{hcloud_prefix}}-load_balancer-target"
+hcloud_testing_ip: "176.9.59.39"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/tasks/main.yml
new file mode 100644
index 00000000..33756688
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_target/tasks/main.yml
@@ -0,0 +1,129 @@
+# 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 server
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ server_type: cx11
+ image: ubuntu-20.04
+ state: started
+ location: "fsn1"
+ register: server
+- name: verify setup server
+ assert:
+ that:
+ - server is success
+
+- name: setup load_balancer
+ hcloud_load_balancer:
+ name: "{{hcloud_load_balancer_name}}"
+ load_balancer_type: lb11
+ state: present
+ location: "fsn1"
+ register: load_balancer
+- name: verify setup load_balancer
+ assert:
+ that:
+ - load_balancer is success
+
+- name: test create load_balancer target with checkmode
+ hcloud_load_balancer_target:
+ type: "server"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: result
+ check_mode: yes
+- name: verify test create load_balancer target with checkmode
+ assert:
+ that:
+ - result is changed
+
+- name: test create load_balancer target
+ hcloud_load_balancer_target:
+ type: "server"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: load_balancer_target
+- name: verify create load_balancer target
+ assert:
+ that:
+ - load_balancer_target is changed
+ - load_balancer_target.hcloud_load_balancer_target.type == "server"
+ - load_balancer_target.hcloud_load_balancer_target.server == hcloud_server_name
+ - load_balancer_target.hcloud_load_balancer_target.load_balancer == hcloud_load_balancer_name
+
+- name: test create load_balancer target idempotency
+ hcloud_load_balancer_target:
+ type: "server"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: load_balancer_target
+- name: verify create load_balancer target idempotency
+ assert:
+ that:
+ - load_balancer_target is not changed
+
+- name: test absent load_balancer target
+ hcloud_load_balancer_target:
+ type: "server"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ server: "{{hcloud_server_name}}"
+ state: absent
+ register: result
+- name: verify test absent load_balancer target
+ assert:
+ that:
+ - result is changed
+
+- name: test create label_selector target
+ hcloud_load_balancer_target:
+ type: "label_selector"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ label_selector: "application=backend"
+ state: present
+ register: load_balancer_target
+- name: verify create label_selector target
+ assert:
+ that:
+ - load_balancer_target is changed
+ - load_balancer_target.hcloud_load_balancer_target.type == "label_selector"
+ - load_balancer_target.hcloud_load_balancer_target.label_selector == "application=backend"
+ - load_balancer_target.hcloud_load_balancer_target.load_balancer == hcloud_load_balancer_name
+
+- name: test create ip target
+ hcloud_load_balancer_target:
+ type: "ip"
+ load_balancer: "{{hcloud_load_balancer_name}}"
+ ip: "{{hcloud_testing_ip}}"
+ state: present
+ register: load_balancer_target
+- name: verify create ip target
+ assert:
+ that:
+ - load_balancer_target is changed
+ - load_balancer_target.hcloud_load_balancer_target.type == "ip"
+ - load_balancer_target.hcloud_load_balancer_target.ip == hcloud_testing_ip
+ - load_balancer_target.hcloud_load_balancer_target.load_balancer == hcloud_load_balancer_name
+
+- name: cleanup load_balancer
+ hcloud_load_balancer:
+ name: "{{ hcloud_load_balancer_name }}"
+ state: absent
+ register: result
+- name: verify cleanup load_balancer
+ assert:
+ that:
+ - result is success
+
+- name: cleanup
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/defaults/main.yml
new file mode 100644
index 00000000..b7fd8631
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# Copyright: (c) 2020, 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)
+---
+hcloud_load_balancer_type_name: "lb11"
+hcloud_load_balancer_type_id: 1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/tasks/main.yml
new file mode 100644
index 00000000..bcd805a8
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_load_balancer_type_info/tasks/main.yml
@@ -0,0 +1,38 @@
+# Copyright: (c) 2020, 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: test gather hcloud Load Balancer type infos
+ hcloud_load_balancer_type_info:
+ register: hcloud_load_balancer_types
+- name: verify test gather hcloud Load Balancer type infos
+ assert:
+ that:
+ - hcloud_load_balancer_types.hcloud_load_balancer_type_info| list | count >= 1
+
+- name: test gather hcloud Load Balancer type infos in check mode
+ hcloud_load_balancer_type_info:
+ check_mode: yes
+ register: hcloud_load_balancer_types
+
+- name: verify test gather hcloud Load Balancer type infos in check mode
+ assert:
+ that:
+ - hcloud_load_balancer_types.hcloud_load_balancer_type_info| list | count >= 1
+
+- name: test gather hcloud Load Balancer type infos with name
+ hcloud_load_balancer_type_info:
+ name: "{{hcloud_load_balancer_type_name}}"
+ register: hcloud_load_balancer_types
+- name: verify test gather hcloud Load Balancer type with name
+ assert:
+ that:
+ - hcloud_load_balancer_types.hcloud_load_balancer_type_info|selectattr('name','equalto','{{ hcloud_load_balancer_type_name }}') | list | count == 1
+
+- name: test gather hcloud Load Balancer type infos with correct id
+ hcloud_load_balancer_type_info:
+ id: "{{hcloud_load_balancer_type_id}}"
+ register: hcloud_load_balancer_types
+- name: verify test gather hcloud Load Balancer type with correct id
+ assert:
+ that:
+ - hcloud_load_balancer_types.hcloud_load_balancer_type_info|selectattr('name','equalto','{{ hcloud_load_balancer_type_name }}') | list | count == 1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/defaults/main.yml
new file mode 100644
index 00000000..0d72a75c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_location_name: "fsn1"
+hcloud_location_id: 1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/tasks/main.yml
new file mode 100644
index 00000000..e0ae5f17
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_location_info/tasks/main.yml
@@ -0,0 +1,57 @@
+# 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: test gather hcloud location infos
+ hcloud_location_info:
+ register: hcloud_location
+
+- name: verify test gather hcloud location infos
+ assert:
+ that:
+ - hcloud_location.hcloud_location_info | list | count == 3
+
+- name: test gather hcloud location infos in check mode
+ hcloud_location_info:
+ check_mode: yes
+ register: hcloud_location
+
+- name: verify test gather hcloud location infos in check mode
+ assert:
+ that:
+ - hcloud_location.hcloud_location_info | list | count == 3
+
+- name: test gather hcloud location infos with correct name
+ hcloud_location_info:
+ name: "{{hcloud_location_name}}"
+ register: hcloud_location
+- name: verify test gather hcloud location with correct name
+ assert:
+ that:
+ - hcloud_location.hcloud_location_info|selectattr('name','equalto','{{ hcloud_location_name }}') | list | count == 1
+
+- name: test gather hcloud location infos with wrong name
+ hcloud_location_info:
+ name: "{{hcloud_location_name}}1"
+ register: hcloud_location
+- name: verify test gather hcloud location with wrong name
+ assert:
+ that:
+ - hcloud_location.hcloud_location_info | list | count == 0
+
+- name: test gather hcloud location infos with correct id
+ hcloud_location_info:
+ id: "{{hcloud_location_id}}"
+ register: hcloud_location
+- name: verify test gather hcloud location with correct id
+ assert:
+ that:
+ - hcloud_location.hcloud_location_info|selectattr('name','equalto','{{ hcloud_location_name }}') | list | count == 1
+
+- name: test gather hcloud location infos with wrong id
+ hcloud_location_info:
+ name: "4711"
+ register: hcloud_location
+- name: verify test gather hcloud location with wrong id
+ assert:
+ that:
+ - hcloud_location.hcloud_location_info | list | count == 0
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/aliases
new file mode 100644
index 00000000..4b3a9b36
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/aliases
@@ -0,0 +1,3 @@
+cloud/hcloud
+shippable/hcloud/group1
+disabled
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/defaults/main.yml
new file mode 100644
index 00000000..ecfa6a73
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_network_name: "{{hcloud_prefix}}-integ"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/tasks/main.yml
new file mode 100644
index 00000000..6c40e4e0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network/tasks/main.yml
@@ -0,0 +1,215 @@
+# 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
+ hcloud_network:
+ name: "{{ hcloud_network_name }}"
+ state: absent
+ register: result
+- name: verify setup
+ assert:
+ that:
+ - result is success
+
+- name: test missing ip_range parameter on create Network
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ register: result
+ ignore_errors: yes
+- name: verify fail missing ip_range parameter on create Network result
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: ip_range"'
+
+- name: test create Network with check mode
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ ip_range: "10.0.0.0/16"
+ register: result
+ check_mode: yes
+- name: verify create Network with check mode result
+ assert:
+ that:
+ - result is changed
+
+- name: test create Network
+ 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
+ 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 update Network label
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ labels:
+ key: value
+ register: network
+- name: verify test update Network label
+ assert:
+ that:
+ - network is changed
+ - network.hcloud_network.labels.key == "value"
+
+- name: test update Network label idempotency
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ labels:
+ key: value
+ register: network
+- name: verify test update Network label idempotency
+ assert:
+ that:
+ - network is not changed
+
+- name: test update Network ip range
+ 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
+ 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 delete protection
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ ip_range: "10.0.0.0/8"
+ delete_protection: true
+ register: network
+- name: verify test update Network delete protection
+ assert:
+ that:
+ - network is changed
+ - network.hcloud_network.delete_protection is sameas true
+
+- name: test update Network delete protection idempotency
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ ip_range: "10.0.0.0/8"
+ 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
+ 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:
+ that:
+ - network is not changed
+ - network.hcloud_network.delete_protection is sameas true
+
+- name: test delete Network fails if it is protected
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete Network
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "network deletion is protected"'
+
+- name: test update Network delete protection
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ ip_range: "10.0.0.0/8"
+ delete_protection: false
+ register: network
+- name: verify test update Network delete protection
+ assert:
+ that:
+ - network is changed
+ - network.hcloud_network.delete_protection is sameas false
+
+- name: test delete Network
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ register: result
+- name: verify delete Network
+ assert:
+ that:
+ - result is success
+
+
+- name: test create Network with delete protection
+ 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:
+ that:
+ - network is changed
+ - network.hcloud_network.delete_protection is sameas true
+
+- name: test delete Network fails if it is protected
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete Network
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "network deletion is protected"'
+
+- name: test update Network delete protection
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ delete_protection: false
+ register: network
+- name: verify test update Network delete protection
+ assert:
+ that:
+ - network is changed
+ - network.hcloud_network.delete_protection is sameas false
+
+- name: test delete Network
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ register: result
+- name: verify delete Network
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/defaults/main.yml
new file mode 100644
index 00000000..f8a5279f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_network_name: "{{hcloud_prefix}}-integration"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/tasks/main.yml
new file mode 100644
index 00000000..e7924a8d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_network_info/tasks/main.yml
@@ -0,0 +1,117 @@
+# 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
+ hcloud_network:
+ name: "{{ hcloud_network_name }}"
+ state: absent
+ register: result
+
+- name: create network
+ hcloud_network:
+ name: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ labels:
+ key: value
+ register: main_network
+- name: verify create network
+ assert:
+ that:
+ - main_network is changed
+ - main_network.hcloud_network.name == "{{ hcloud_network_name }}"
+ - main_network.hcloud_network.ip_range == "10.0.0.0/16"
+- name: create subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ type: server
+ network_zone: eu-central
+ ip_range: "10.0.1.0/24"
+ register: main_subnetwork
+- name: verify create subnetwork
+ assert:
+ that:
+ - main_subnetwork is changed
+ - main_subnetwork.hcloud_subnetwork.network == "{{ hcloud_network_name }}"
+- name: create route
+ hcloud_route:
+ network: "{{ hcloud_network_name }}"
+ destination: "10.0.3.0/24"
+ gateway: "10.0.2.1"
+ register: main_route
+- name: verify create route
+ assert:
+ that:
+ - main_route is changed
+ - main_route.hcloud_route.network == "{{ hcloud_network_name }}"
+
+- name: test gather hcloud network info in check mode
+ hcloud_network_info:
+ check_mode: yes
+ register: hcloud_network
+- name: verify test gather hcloud network info in check mode
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | selectattr('name','equalto','{{ hcloud_network_name }}') | list | count >= 1
+
+
+- name: test gather hcloud network info with correct label selector
+ hcloud_network_info:
+ label_selector: "key=value"
+ register: hcloud_network
+- name: verify test gather hcloud network with correct label selector
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | selectattr('name','equalto','{{ hcloud_network_name }}') | list | count >= 1
+
+- name: test gather hcloud network info with wrong label selector
+ hcloud_network_info:
+ label_selector: "key!=value"
+ register: hcloud_network
+- name: verify test gather hcloud network with wrong label selector
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | list | count == 0
+
+- name: test gather hcloud network info with correct name
+ hcloud_network_info:
+ name: "{{hcloud_network_name}}"
+ register: hcloud_network
+- name: verify test gather hcloud network with correct name
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | selectattr('name','equalto','{{ hcloud_network_name }}') | list | count == 1
+ - hcloud_network.hcloud_network_info[0].subnetworks | list | count >= 1
+ - hcloud_network.hcloud_network_info[0].routes | list | count >= 1
+
+- name: test gather hcloud network info with wrong name
+ hcloud_network_info:
+ name: "{{hcloud_network_name}}1"
+ register: hcloud_network
+- name: verify test gather hcloud network with wrong name
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | list | count == 0
+
+- name: test gather hcloud network info with correct id
+ hcloud_network_info:
+ id: "{{main_network.hcloud_network.id}}"
+ register: hcloud_network
+- name: verify test gather hcloud network with correct id
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | selectattr('name','equalto','{{ hcloud_network_name }}') | list | count == 1
+
+- name: test gather hcloud network info with wrong id
+ hcloud_network_info:
+ name: "4711"
+ register: hcloud_network
+- name: verify test gather hcloud network with wrong id
+ assert:
+ that:
+ - hcloud_network.hcloud_network_info | list | count == 0
+
+- name: cleanup
+ hcloud_network:
+ name: "{{ hcloud_network_name }}"
+ state: absent
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/defaults/main.yml
new file mode 100644
index 00000000..fb46d1e1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_server_name: "{{hcloud_prefix}}-rdns"
+hcloud_floating_ip_name: "{{hcloud_prefix}}-rdns"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/meta/main.yml
new file mode 100644
index 00000000..67d54d73
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - ansible.netcommon
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/tasks/main.yml
new file mode 100644
index 00000000..f34f1047
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_rdns/tasks/main.yml
@@ -0,0 +1,140 @@
+# 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
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: present
+ register: setup
+- name: verify setup
+ assert:
+ that:
+ - setup is success
+
+- name: test create Floating IP
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ type: ipv4
+ home_location: "fsn1"
+ register: floatingIP
+- name: verify test create Floating IP
+ assert:
+ that:
+ - floatingIP is success
+
+- name: test missing required parameter
+ hcloud_rdns:
+ state: present
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: ip_address"'
+
+- name: test create rdns
+ hcloud_rdns:
+ server: "{{ hcloud_server_name }}"
+ ip_address: "{{ setup.hcloud_server.ipv6 | ansible.netcommon.ipaddr('next_usable') }}"
+ dns_ptr: "example.com"
+ state: present
+ register: rdns
+- name: verify create rdns
+ assert:
+ that:
+ - rdns is changed
+ - rdns.hcloud_rdns.server == "{{ hcloud_server_name }}"
+ - rdns.hcloud_rdns.ip_address == "{{ setup.hcloud_server.ipv6 | ansible.netcommon.ipaddr('next_usable') }}"
+ - rdns.hcloud_rdns.dns_ptr == "example.com"
+
+- name: test create rdns idempotency
+ hcloud_rdns:
+ server: "{{ hcloud_server_name }}"
+ ip_address: "{{ setup.hcloud_server.ipv6 | ansible.netcommon.ipaddr('next_usable') }}"
+ dns_ptr: "example.com"
+ state: present
+ register: result
+- name: verify create rdns idempotency
+ assert:
+ that:
+ - result is not changed
+
+- name: test absent rdns
+ hcloud_rdns:
+ server: "{{ hcloud_server_name }}"
+ ip_address: "{{ setup.hcloud_server.ipv6 | ansible.netcommon.ipaddr('next_usable') }}"
+ state: absent
+ register: result
+- name: verify test absent rdns
+ assert:
+ that:
+ - result is changed
+
+- name: test update rdns
+ hcloud_rdns:
+ server: "{{ hcloud_server_name }}"
+ ip_address: "{{ setup.hcloud_server.ipv4_address }}"
+ dns_ptr: "example.com"
+ state: present
+ register: rdns
+- name: verify update rdns
+ assert:
+ that:
+ - rdns is changed
+ - rdns.hcloud_rdns.server == "{{ hcloud_server_name }}"
+ - rdns.hcloud_rdns.ip_address == "{{ setup.hcloud_server.ipv4_address }}"
+ - rdns.hcloud_rdns.dns_ptr == "example.com"
+
+- name: test reset rdns
+ hcloud_rdns:
+ server: "{{ hcloud_server_name }}"
+ ip_address: "{{ setup.hcloud_server.ipv4_address }}"
+ state: present
+ register: rdns
+- name: verify reset rdns
+ assert:
+ that:
+ - rdns is changed
+ - rdns.hcloud_rdns.server == "{{ hcloud_server_name }}"
+ - rdns.hcloud_rdns.ip_address == "{{ setup.hcloud_server.ipv4_address }}"
+ - rdns.hcloud_rdns.dns_ptr != "example.com"
+
+- name: test create rdns with floating IP
+ hcloud_rdns:
+ floating_ip: "{{ hcloud_floating_ip_name }}"
+ ip_address: "{{ floatingIP.hcloud_floating_ip.ip}}"
+ dns_ptr: "example.com"
+ state: present
+ register: rdns
+- name: verify create rdns
+ assert:
+ that:
+ - rdns is changed
+ - rdns.hcloud_rdns.floating_ip == "{{ hcloud_floating_ip_name }}"
+ - rdns.hcloud_rdns.ip_address == "{{ floatingIP.hcloud_floating_ip.ip}}"
+ - rdns.hcloud_rdns.dns_ptr == "example.com"
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
+
+- name: cleanup
+ hcloud_floating_ip:
+ name: "{{ hcloud_floating_ip_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/defaults/main.yml
new file mode 100644
index 00000000..62156272
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_network_name: "{{hcloud_prefix}}-routes"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/meta/main.yml
new file mode 100644
index 00000000..67d54d73
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - ansible.netcommon
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/tasks/main.yml
new file mode 100644
index 00000000..7d816bf5
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_route/tasks/main.yml
@@ -0,0 +1,99 @@
+# 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
+ hcloud_network:
+ name: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/8"
+ state: present
+ register: network
+- name: verify setup
+ assert:
+ that:
+ - network is success
+
+- name: test missing required parameters on create route
+ hcloud_route:
+ state: present
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create route
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: destination, gateway, network"'
+
+- name: test create route with checkmode
+ hcloud_route:
+ network: "{{ hcloud_network_name }}"
+ destination: "10.100.1.0/24"
+ gateway: "10.0.1.1"
+ state: present
+ register: result
+ check_mode: yes
+- name: verify test create route with checkmode
+ assert:
+ that:
+ - result is changed
+
+- name: test create route
+ hcloud_route:
+ network: "{{ hcloud_network_name }}"
+ destination: "10.100.1.0/24"
+ gateway: "10.0.1.1"
+ state: present
+ register: route
+- name: verify create route
+ assert:
+ that:
+ - route is changed
+ - route.hcloud_route.network == "{{ hcloud_network_name }}"
+ - route.hcloud_route.destination == "10.100.1.0/24"
+ - route.hcloud_route.gateway == "10.0.1.1"
+
+- name: test create route idempotency
+ hcloud_route:
+ network: "{{ hcloud_network_name }}"
+ destination: "10.100.1.0/24"
+ gateway: "10.0.1.1"
+ state: present
+ register: result
+- name: verify create route idempotency
+ assert:
+ that:
+ - result is not changed
+
+- name: test fail create route with wrong gateway
+ hcloud_route:
+ network: "{{ hcloud_network_name }}"
+ destination: "10.100.1.0/24"
+ gateway: "10.0.1.2"
+ state: present
+ register: route
+ ignore_errors: yes
+- name: verfiy fail create route with wrong gateway
+ assert:
+ that:
+ - route is failed
+
+- name: test absent route
+ hcloud_route:
+ network: "{{ hcloud_network_name }}"
+ destination: "10.100.1.0/24"
+ gateway: "10.0.1.1"
+ state: absent
+ register: result
+- name: verify test absent route
+ assert:
+ that:
+ - result is changed
+
+- name: cleanup
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/aliases
new file mode 100644
index 00000000..18dc30b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/defaults/main.yml
new file mode 100644
index 00000000..b9a9a8df
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_server_name: "{{hcloud_prefix}}-integration"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/tasks/main.yml
new file mode 100644
index 00000000..f4464f18
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server/tasks/main.yml
@@ -0,0 +1,648 @@
+# 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
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify setup
+ assert:
+ that:
+ - result is success
+- name: test missing required parameters on create server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create server
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: server_type, image"'
+
+- name: test create server with check mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: present
+ register: result
+ check_mode: yes
+- name: test create server server
+ assert:
+ that:
+ - result is changed
+
+- name: test create server
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: started
+ register: main_server
+- name: verify create server
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.name == "{{ hcloud_server_name }}"
+ - main_server.hcloud_server.server_type == "cx11"
+ - main_server.hcloud_server.status == "running"
+ - main_server.root_password != ""
+
+- name: test create server idempotence
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: started
+ register: result
+- name: verify create server idempotence
+ assert:
+ that:
+ - result is not changed
+
+- name: test stop server with check mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: stopped
+ register: result
+ check_mode: yes
+- name: verify stop server with check mode
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.status == "running"
+
+- name: test stop server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: stopped
+ register: result
+- name: verify stop server
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.status == "off"
+
+- name: test start server with check mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: started
+ register: result
+ check_mode: true
+- name: verify start server with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test start server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: started
+ register: result
+- name: verify start server
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.status == "running"
+
+- name: test start server idempotence
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: started
+ register: result
+- name: verify start server idempotence
+ assert:
+ that:
+ - result is not changed
+ - result.hcloud_server.status == "running"
+
+- name: test stop server by its id
+ hcloud_server:
+ id: "{{ main_server.hcloud_server.id }}"
+ state: stopped
+ register: result
+- name: verify stop server by its id
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.status == "off"
+
+- name: test resize server running without force
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: "cx21"
+ state: present
+ register: result
+ check_mode: true
+- name: verify test resize server running without force
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.server_type == "cx11"
+
+- name: test resize server with check mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: "cx21"
+ state: stopped
+ register: result
+ check_mode: true
+- name: verify resize server with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test resize server without disk
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: "cx21"
+ state: stopped
+ register: result
+- name: verify resize server without disk
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.server_type == "cx21"
+
+- name: test resize server idempotence
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: "cx21"
+ state: stopped
+ register: result
+- name: verify resize server idempotence
+ assert:
+ that:
+ - result is not changed
+
+- name: test resize server to smaller plan
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: "cx11"
+ state: stopped
+ register: result
+- name: verify resize server to smaller plan
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.server_type == "cx11"
+
+- name: test resize server with disk
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: "cx21"
+ upgrade_disk: true
+ state: stopped
+ register: result
+- name: verify resize server with disk
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.server_type == "cx21"
+
+- name: test enable backups with check mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ backups: true
+ state: stopped
+ register: result
+ check_mode: true
+- name: verify enable backups with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test enable backups
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ backups: true
+ state: stopped
+ register: result
+- name: verify enable backups
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.backup_window != ""
+
+- name: test enable backups idempotence
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ backups: true
+ state: stopped
+ register: result
+- name: verify enable backups idempotence
+ assert:
+ that:
+ - result is not changed
+ - result.hcloud_server.backup_window != ""
+
+- name: test rebuild server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ image: ubuntu-18.04
+ state: rebuild
+ register: result_after_test
+- name: verify rebuild server
+ assert:
+ that:
+ - result_after_test is changed
+ - result.hcloud_server.id == result_after_test.hcloud_server.id
+
+- name: test rebuild server with check mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ image: ubuntu-18.04
+ state: rebuild
+ register: result_after_test
+ check_mode: true
+- name: verify rebuild server with check mode
+ assert:
+ that:
+ - result_after_test is changed
+
+- name: test update server protection booth protection arguments are required
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ delete_protection: true
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify update server protection booth protection arguments are required
+ assert:
+ that:
+ - result_after_test is failed
+ - 'result_after_test.msg == "parameters are required together: delete_protection, rebuild_protection"'
+
+- name: test update server protection fails if they are not the same
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ delete_protection: true
+ rebuild_protection: false
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify update server protection fails if they are not the same
+ assert:
+ that:
+ - result_after_test is failed
+
+- name: test update server protection
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ delete_protection: true
+ rebuild_protection: true
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify update server protection
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_server.delete_protection is sameas true
+ - result_after_test.hcloud_server.rebuild_protection is sameas true
+
+- name: test server without protection set to be idempotent
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ register: result_after_test
+- name: verify test server without protection set to be idempotent
+ assert:
+ that:
+ - result_after_test is not changed
+ - result_after_test.hcloud_server.delete_protection is sameas true
+ - result_after_test.hcloud_server.rebuild_protection is sameas true
+
+- name: test delete server fails if it is protected
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete server fails if it is protected
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "server deletion is protected"'
+
+- name: test rebuild server fails if it is protected
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ image: ubuntu-18.04
+ state: rebuild
+ ignore_errors: yes
+ register: result
+- name: verify rebuild server fails if it is protected
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "server rebuild is protected"'
+
+- name: test remove server protection
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ delete_protection: false
+ rebuild_protection: false
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify remove server protection
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_server.delete_protection is sameas false
+ - result_after_test.hcloud_server.rebuild_protection is sameas false
+
+- name: absent server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify absent server
+ assert:
+ that:
+ - result is success
+
+- name: test create server with ssh key
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: started
+ register: main_server
+- name: verify create server with ssh key
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.name == "{{ hcloud_server_name }}"
+ - main_server.hcloud_server.server_type == "cx11"
+ - main_server.hcloud_server.status == "running"
+ - main_server.root_password != ""
+
+- name: absent server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify absent server
+ assert:
+ that:
+ - result is success
+
+- name: test create server with rescue_mode
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ rescue_mode: "linux64"
+ state: started
+ register: main_server
+- name: verify create server with rescue_mode
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.name == "{{ hcloud_server_name }}"
+ - main_server.hcloud_server.server_type == "cx11"
+ - main_server.hcloud_server.status == "running"
+ - main_server.root_password != ""
+ - main_server.hcloud_server.rescue_enabled is sameas true
+
+- name: absent server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify absent server
+ assert:
+ that:
+ - result is success
+
+- name: setup server
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: started
+ register: main_server
+- name: verify setup server
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.name == "{{ hcloud_server_name }}"
+ - main_server.hcloud_server.server_type == "cx11"
+ - main_server.hcloud_server.status == "running"
+ - main_server.root_password != ""
+
+- name: test activate rescue mode with check_mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ rescue_mode: "linux64"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: present
+ register: main_server
+ check_mode: true
+- name: verify activate rescue mode
+ assert:
+ that:
+ - main_server is changed
+
+- name: test activate rescue mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ rescue_mode: "linux64"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: present
+ register: main_server
+- name: verify activate rescue mode
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.rescue_enabled is sameas true
+
+- name: test disable rescue mode
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: present
+ register: main_server
+- name: verify activate rescue mode
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.rescue_enabled is sameas false
+
+- name: test activate rescue mode without ssh keys
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ rescue_mode: "linux64"
+ state: present
+ register: main_server
+- name: verify activate rescue mode without ssh keys
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.rescue_enabled is sameas true
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
+
+- name: test create server with labels
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ labels:
+ key: value
+ mylabel: "val123"
+ state: started
+ register: main_server
+- name: verify create server with labels
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.labels.key == "value"
+ - main_server.hcloud_server.labels.mylabel == "val123"
+
+- name: test update server with labels
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ labels:
+ key: other
+ mylabel: "val123"
+ state: started
+ register: main_server
+- name: verify update server with labels
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.labels.key == "other"
+ - main_server.hcloud_server.labels.mylabel == "val123"
+
+- name: test update server with labels in other order
+ hcloud_server:
+ name: "{{ hcloud_server_name}}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ labels:
+ mylabel: "val123"
+ key: other
+ state: started
+ register: main_server
+- name: verify update server with labels in other order
+ assert:
+ that:
+ - main_server is not changed
+
+- name: cleanup with labels
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
+
+- name: test create server with enabled backups
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: cpx11
+ backups: true
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: present
+ register: result
+- name: verify enable backups
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_server.backup_window != ""
+
+- name: test create server with enabled backups
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
+
+- name: test create server with protection
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ delete_protection: true
+ rebuild_protection: true
+ server_type: cpx11
+ image: "ubuntu-20.04"
+ ssh_keys:
+ - ci@ansible.hetzner.cloud
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify create server with protection
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_server.delete_protection is sameas true
+ - result_after_test.hcloud_server.rebuild_protection is sameas true
+
+
+- name: test delete server fails if it is protected
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete server fails if it is protected
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "server deletion is protected"'
+
+- name: remove protection from server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ delete_protection: false
+ rebuild_protection: false
+ state: present
+ register: result_after_test
+ ignore_errors: true
+- name: verify update server protection
+ assert:
+ that:
+ - result_after_test is changed
+ - result_after_test.hcloud_server.delete_protection is sameas false
+ - result_after_test.hcloud_server.rebuild_protection is sameas false
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/defaults/main.yml
new file mode 100644
index 00000000..b9a9a8df
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_server_name: "{{hcloud_prefix}}-integration"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/tasks/main.yml
new file mode 100644
index 00000000..92eac5cc
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_info/tasks/main.yml
@@ -0,0 +1,97 @@
+# 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 server is absent
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+
+- name: create server
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: started
+ labels:
+ key: value
+ register: main_server
+- name: verify create server
+ assert:
+ that:
+ - main_server is changed
+ - main_server.hcloud_server.name == "{{ hcloud_server_name }}"
+ - main_server.hcloud_server.server_type == "cx11"
+ - main_server.hcloud_server.status == "running"
+ - main_server.root_password != ""
+
+
+- name: test gather hcloud server infos in check mode
+ hcloud_server_info:
+ register: hcloud_server
+ check_mode: yes
+
+- name: verify test gather hcloud server infos in check mode
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info|selectattr('name','equalto','{{ hcloud_server_name }}') | list | count == 1
+
+
+- name: test gather hcloud server infos with correct label selector
+ hcloud_server_info:
+ label_selector: "key=value"
+ register: hcloud_server
+- name: verify test gather hcloud server infos with correct label selector
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info|selectattr('name','equalto','{{ hcloud_server_name }}') | list | count == 1
+
+- name: test gather hcloud server infos with wrong label selector
+ hcloud_server_info:
+ label_selector: "key!=value"
+ register: hcloud_server
+- name: verify test gather hcloud server infos with wrong label selector
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info | list | count == 0
+
+- name: test gather hcloud server infos with correct name
+ hcloud_server_info:
+ name: "{{hcloud_server_name}}"
+ register: hcloud_server
+- name: verify test gather hcloud server infos with correct name
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info|selectattr('name','equalto','{{ hcloud_server_name }}') | list | count == 1
+
+- name: test gather hcloud server infos with wrong name
+ hcloud_server_info:
+ name: "{{hcloud_server_name}}1"
+ register: hcloud_server
+- name: verify test gather hcloud server infos with wrong name
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info | list | count == 0
+
+- name: test gather hcloud server infos with correct id
+ hcloud_server_info:
+ id: "{{main_server.hcloud_server.id}}"
+ register: hcloud_server
+- name: verify test gather hcloud server infos with correct id
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info|selectattr('name','equalto','{{ hcloud_server_name }}') | list | count == 1
+
+- name: test gather hcloud server infos with wrong id
+ hcloud_server_info:
+ name: "4711"
+ register: hcloud_server
+- name: verify test gather hcloud server infos with wrong id
+ assert:
+ that:
+ - hcloud_server.hcloud_server_info | list | count == 0
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/aliases
new file mode 100644
index 00000000..7f17468b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/aliases
@@ -0,0 +1,3 @@
+cloud/hcloud
+shippable/hcloud/group2
+disabled
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/defaults/main.yml
new file mode 100644
index 00000000..1d62e5dc
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_network_name: "{{hcloud_prefix}}-server-network"
+hcloud_server_name: "{{hcloud_prefix}}-server-network"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/tasks/main.yml
new file mode 100644
index 00000000..754018a6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_network/tasks/main.yml
@@ -0,0 +1,222 @@
+# 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
+ 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
+ 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
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ server_type: cx11
+ image: ubuntu-18.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
+ hcloud_server_network:
+ state: present
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create server network
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: network, server"'
+
+- name: test create server network with checkmode
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: result
+ check_mode: yes
+- name: verify test create server network with checkmode
+ assert:
+ that:
+ - result is changed
+
+- name: test create server network
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: serverNetwork
+- name: verify create server network
+ assert:
+ that:
+ - serverNetwork is changed
+ - serverNetwork.hcloud_server_network.network == hcloud_network_name
+ - serverNetwork.hcloud_server_network.server == hcloud_server_name
+
+- name: test create server network idempotency
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ state: present
+ register: serverNetwork
+- name: verify create server network idempotency
+ assert:
+ that:
+ - serverNetwork is not changed
+
+- name: test absent server network
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ state: absent
+ register: result
+- name: verify test absent server network
+ assert:
+ that:
+ - result is changed
+
+- name: test create server network with specified ip
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ ip: "10.0.0.2"
+ state: present
+ register: serverNetwork
+- name: verify create server network with specified ip
+ 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"
+
+- name: cleanup create server network with specified ip
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ state: absent
+ register: result
+- name: verify cleanup create server network with specified ip
+ assert:
+ that:
+ - result is changed
+
+- name: test create server network with alias ips
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ ip: "10.0.0.2"
+ alias_ips:
+ - "10.0.1.2"
+ - "10.0.2.3"
+ state: present
+ register: serverNetwork
+- name: verify create server network with alias ips
+ 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"'
+
+- name: test update server network with alias ips
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ ip: "10.0.0.2"
+ alias_ips:
+ - "10.0.2.3"
+ - "10.0.3.1"
+ state: present
+ register: serverNetwork
+- name: verify create server network with alias ips
+ 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"'
+
+- name: test update server network with alias ips idempotency
+ hcloud_server_network:
+ network: "{{ hcloud_network_name }}"
+ server: "{{hcloud_server_name}}"
+ ip: "10.0.0.2"
+ alias_ips:
+ - "10.0.2.3"
+ - "10.0.3.1"
+ 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
+ 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
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup server
+ assert:
+ that:
+ - result is success
+
+- name: cleanup subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "server"
+ network_zone: "eu-central"
+ state: absent
+ register: result
+- name: verify cleanup subnetwork
+ assert:
+ that:
+ - result is changed
+
+- name: cleanup
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/defaults/main.yml
new file mode 100644
index 00000000..05502aa9
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_server_type_name: "cx11"
+hcloud_server_type_id: 1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/tasks/main.yml
new file mode 100644
index 00000000..3c1fce8c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_server_type_info/tasks/main.yml
@@ -0,0 +1,38 @@
+# 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: test gather hcloud server type infos
+ hcloud_server_type_info:
+ register: hcloud_server_types
+- name: verify test gather hcloud server type infos
+ assert:
+ that:
+ - hcloud_server_types.hcloud_server_type_info| list | count > 2
+
+- name: test gather hcloud server type infos in check mode
+ hcloud_server_type_info:
+ check_mode: yes
+ register: hcloud_server_types
+
+- name: verify test gather hcloud server type infos in check mode
+ assert:
+ that:
+ - hcloud_server_types.hcloud_server_type_info| list | count > 2
+
+- name: test gather hcloud server type infos with name
+ hcloud_server_type_info:
+ name: "{{hcloud_server_type_name}}"
+ register: hcloud_server_types
+- name: verify test gather hcloud server type with name
+ assert:
+ that:
+ - hcloud_server_types.hcloud_server_type_info|selectattr('name','equalto','{{ hcloud_server_type_name }}') | list | count == 1
+
+- name: test gather hcloud server type infos with correct id
+ hcloud_server_type_info:
+ id: "{{hcloud_server_type_id}}"
+ register: hcloud_server_types
+- name: verify test gather hcloud server type with correct id
+ assert:
+ that:
+ - hcloud_server_types.hcloud_server_type_info|selectattr('name','equalto','{{ hcloud_server_type_name }}') | list | count == 1
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/defaults/main.yml
new file mode 100644
index 00000000..666d3346
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/defaults/main.yml
@@ -0,0 +1,8 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_server_name: "{{hcloud_prefix}}-integration"
+hcloud_ssh_key_name: "{{hcloud_prefix}}-integration"
+hcloud_ssh_key_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnaTPfKaX1QKcRLOfr34buVLh5FhJAThI9NYB0xNdXsMd4Y0zLyyCQzHbx4eWCVZxym/s6csWSeLaAhO1GOHeAw3hQFMqf1oTBx6Y8g0pKpeotKPa/PDSUzdZF9Lc+DadtpQd8kFVHAu1Kd3zoEUnk1u6kP7I4qu4Z/6F9qBDF+M3aobiPVxdS7GwaVRW3nZu+FcQDLiBiNOjuRDyjHcDfEUkoh2SOu25RrFtGPzFu5mGmBJwotKpWAocLGfHzyn/fAHxgw3jKZVH/t+XWQFnl82Ie8yE3Z1EZ7oDkNRqFQT9AdXEQOLycTTYTQMJZpgeFTv3sAo6lPRCusiFmmLcf ci@ansible.hetzner.cloud"
+hcloud_ssh_key_fingerprint: "56:89:c4:d6:a7:4a:79:82:f4:c2:58:9c:e1:d2:2d:4e"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/meta/main.yml
new file mode 100644
index 00000000..5dcc0725
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/meta/main.yml
@@ -0,0 +1,5 @@
+dependencies:
+ - setup_sshkey
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/tasks/main.yml
new file mode 100644
index 00000000..baaadd4d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key/tasks/main.yml
@@ -0,0 +1,144 @@
+# 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: test missing required parameters on create ssh_key
+ hcloud_ssh_key:
+ name: "{{ hcloud_ssh_key_name }}"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create ssh_key
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: public_key"'
+
+- name: test create ssh key with check mode
+ hcloud_ssh_key:
+ name: "{{ hcloud_ssh_key_name }}"
+ public_key: "{{ key_material }}"
+ register: result
+ check_mode: yes
+- name: test create ssh key with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test create ssh key
+ hcloud_ssh_key:
+ name: "{{ hcloud_ssh_key_name }}"
+ public_key: "{{ key_material }}"
+ labels:
+ key: value
+ my-label: label
+ register: sshKey
+- name: verify create ssh key
+ assert:
+ that:
+ - sshKey is changed
+ - sshKey.hcloud_ssh_key.name == "{{ hcloud_ssh_key_name }}"
+ - sshKey.hcloud_ssh_key.public_key == "{{ key_material }}"
+ - sshKey.hcloud_ssh_key.labels.key == "value"
+
+- name: test create ssh key idempotence
+ hcloud_ssh_key:
+ name: "{{ hcloud_ssh_key_name }}"
+ public_key: "{{ key_material }}"
+ register: result
+- name: verify create ssh key idempotence
+ assert:
+ that:
+ - result is not changed
+
+- name: test update ssh key with check mode
+ hcloud_ssh_key:
+ id: "{{ sshKey.hcloud_ssh_key.id }}"
+ name: "changed-{{ hcloud_ssh_key_name }}"
+ register: result
+ check_mode: yes
+- name: test create ssh key with check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test update ssh key
+ hcloud_ssh_key:
+ id: "{{ sshKey.hcloud_ssh_key.id }}"
+ name: "changed-{{ hcloud_ssh_key_name }}"
+ labels:
+ key: value
+ register: result
+- name: test update ssh key
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_ssh_key.name == "changed-{{ hcloud_ssh_key_name }}"
+
+- name: test update ssh key with same labels
+ hcloud_ssh_key:
+ id: "{{ sshKey.hcloud_ssh_key.id }}"
+ name: "changed-{{ hcloud_ssh_key_name }}"
+ labels:
+ key: value
+ register: result
+- name: test update ssh key with same labels
+ assert:
+ that:
+ - result is not changed
+
+- name: test update ssh key with other labels
+ hcloud_ssh_key:
+ id: "{{ sshKey.hcloud_ssh_key.id }}"
+ name: "changed-{{ hcloud_ssh_key_name }}"
+ labels:
+ key: value
+ test: "val123"
+ register: result
+- name: test update ssh key with other labels
+ assert:
+ that:
+ - result is changed
+
+- name: test rename ssh key
+ hcloud_ssh_key:
+ id: "{{ sshKey.hcloud_ssh_key.id }}"
+ name: "{{ hcloud_ssh_key_name }}"
+ register: result
+- name: test rename ssh key
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_ssh_key.name == "{{ hcloud_ssh_key_name }}"
+
+- name: test create server with ssh key
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ server_type: cx11
+ image: "ubuntu-18.04"
+ ssh_keys:
+ - "{{ hcloud_ssh_key_name }}"
+ state: started
+ register: main_server
+- name: verify create server with ssh key
+ assert:
+ that:
+ - main_server is changed
+
+- name: absent ssh key
+ hcloud_ssh_key:
+ id: "{{ sshKey.hcloud_ssh_key.id }}"
+ state: absent
+ register: result
+- name: verify absent server
+ assert:
+ that:
+ - result is success
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/defaults/main.yml
new file mode 100644
index 00000000..06c1471a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_ssh_key_name: "{{hcloud_prefix}}-ssh_key_facts"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/meta/main.yml
new file mode 100644
index 00000000..5dcc0725
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/meta/main.yml
@@ -0,0 +1,5 @@
+dependencies:
+ - setup_sshkey
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/tasks/main.yml
new file mode 100644
index 00000000..87cbd262
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_ssh_key_info/tasks/main.yml
@@ -0,0 +1,68 @@
+# 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 ssh key is absent
+ hcloud_ssh_key:
+ name: "{{ hcloud_ssh_key_name }}"
+ state: absent
+ register: result
+
+- name: setup test ssh_key
+ hcloud_ssh_key:
+ name: "{{hcloud_ssh_key_name}}"
+ public_key: "{{ key_material }}"
+ labels:
+ key: value
+ register: result
+- name: verify create test ssh_key
+ assert:
+ that:
+ - result is changed
+ - result.hcloud_ssh_key.public_key == "{{ key_material }}"
+
+- name: test gather hcloud ssh key infos in check mode
+ hcloud_ssh_key_info:
+ register: hcloud_ssh_key
+ check_mode: yes
+- name: verify test gather hcloud ssh key infos in check mode
+ assert:
+ that:
+ - hcloud_ssh_key.hcloud_ssh_key_info| list | count >= 1
+
+- name: test gather hcloud ssh key infos
+ hcloud_ssh_key_info:
+ register: hcloud_ssh_key
+ check_mode: yes
+- name: verify test gather hcloud ssh key infos
+ assert:
+ that:
+ - hcloud_ssh_key.hcloud_ssh_key_info| list | count >= 1
+
+- name: test gather hcloud ssh key infos with correct label selector
+ hcloud_ssh_key_info:
+ label_selector: "key=value"
+ register: hcloud_ssh_key
+- name: verify test gather hcloud ssh key infos with correct label selector
+ assert:
+ that:
+ - hcloud_ssh_key.hcloud_ssh_key_info|selectattr('name','equalto','{{ hcloud_ssh_key_name }}') | list | count == 1
+
+- name: test gather hcloud ssh key infos with wrong label selector
+ hcloud_ssh_key_info:
+ label_selector: "key!=value"
+ register: hcloud_ssh_key
+- name: verify test gather hcloud ssh key infos with wrong label selector
+ assert:
+ that:
+ - hcloud_ssh_key.hcloud_ssh_key_info | list | count == 0
+
+- name: cleanup
+ hcloud_ssh_key:
+ name: "{{hcloud_ssh_key_name}}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/aliases
new file mode 100644
index 00000000..af1d98c3
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group3
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/defaults/main.yml
new file mode 100644
index 00000000..51a123db
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_network_name: "{{hcloud_prefix}}-subnet"
+hetzner_vswitch_id: 15311
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/tasks/main.yml
new file mode 100644
index 00000000..0453f9d1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_subnetwork/tasks/main.yml
@@ -0,0 +1,125 @@
+# 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
+ hcloud_network:
+ name: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/8"
+ state: present
+ register: network
+- name: verify setup
+ assert:
+ that:
+ - network is success
+
+- name: test missing required parameters on create route
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ state: present
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing required parameters on create route
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: ip_range, network_zone, type"'
+
+- name: test create subnetwork with checkmode
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "server"
+ network_zone: "eu-central"
+ state: present
+ register: result
+ check_mode: yes
+- name: verify test create subnetwork with checkmode
+ assert:
+ that:
+ - result is changed
+
+- name: test create subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "cloud"
+ network_zone: "eu-central"
+ state: present
+ register: subnet
+- name: verify create subnetwork
+ assert:
+ that:
+ - subnet is changed
+ - subnet.hcloud_subnetwork.network == "{{ hcloud_network_name }}"
+ - subnet.hcloud_subnetwork.ip_range == "10.0.0.0/16"
+ - subnet.hcloud_subnetwork.type == "cloud"
+ - subnet.hcloud_subnetwork.network_zone == "eu-central"
+
+- name: test create subnetwork idempotency
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "cloud"
+ network_zone: "eu-central"
+ state: present
+ register: result
+- name: verify create subnetwork idempotency
+ assert:
+ that:
+ - result is not changed
+
+- name: test absent subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "cloud"
+ network_zone: "eu-central"
+ state: absent
+ register: result
+- name: verify test absent subnetwork
+ assert:
+ that:
+ - result is changed
+
+- name: test vswitch subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "vswitch"
+ network_zone: "eu-central"
+ vswitch_id: "{{ hetzner_vswitch_id }}"
+ state: present
+ register: subnet
+- name: verify test vswitch subnetwork
+ assert:
+ that:
+ - subnet is changed
+ - subnet.hcloud_subnetwork.network == "{{ hcloud_network_name }}"
+ - subnet.hcloud_subnetwork.ip_range == "10.0.0.0/16"
+ - subnet.hcloud_subnetwork.type == "vswitch"
+ - subnet.hcloud_subnetwork.network_zone == "eu-central"
+ - subnet.hcloud_subnetwork.vswitch_id == hetzner_vswitch_id
+
+- name: test absent subnetwork
+ hcloud_subnetwork:
+ network: "{{ hcloud_network_name }}"
+ ip_range: "10.0.0.0/16"
+ type: "vswitch"
+ network_zone: "eu-central"
+ vswitch_id: "{{ hetzner_vswitch_id }}"
+ state: absent
+ register: subnet
+- name: verify test absent subnetwork
+ assert:
+ that:
+ - result is changed
+
+- name: cleanup
+ hcloud_network:
+ name: "{{hcloud_network_name}}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/defaults/main.yml
new file mode 100644
index 00000000..a8f03b4e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/defaults/main.yml
@@ -0,0 +1,6 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_volume_name: "{{hcloud_prefix}}-integ"
+hcloud_server_name: "{{hcloud_prefix}}-volume-server"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/tasks/main.yml
new file mode 100644
index 00000000..f763a52f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume/tasks/main.yml
@@ -0,0 +1,289 @@
+# 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 server
+ hcloud_server:
+ name: "{{hcloud_server_name}}"
+ server_type: cx11
+ image: ubuntu-18.04
+ state: started
+ location: "fsn1"
+ register: vol_server
+- name: verify setup server
+ assert:
+ that:
+ - vol_server is changed
+
+- name: test missing size parameter on create Volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ server: "{{hcloud_server_name}}"
+ register: result
+ ignore_errors: yes
+- name: verify fail test missing size parameter on create Volume
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "missing required arguments: size"'
+
+- name: test create Volume with check mode
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 10
+ location: "fsn1"
+ register: result
+ check_mode: yes
+- name: verify create Volume with check mode result
+ assert:
+ that:
+ - result is changed
+
+- name: test create Volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 10
+ location: "fsn1"
+ register: volume
+- name: verify test create Volume
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.name == "{{hcloud_volume_name}}"
+ - volume.hcloud_volume.location == "fsn1"
+ - volume.hcloud_volume.size == 10
+ - volume.hcloud_volume.server != "{{hcloud_server_name}}"
+ - volume.hcloud_volume.linux_device is defined
+
+- name: test create Volume idempotence
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 10
+ location: "fsn1"
+ register: volume
+- name: verify test create Volume
+ assert:
+ that:
+ - volume is not changed
+
+- name: test attach Volume with checkmode
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ server: "{{hcloud_server_name}}"
+ check_mode: yes
+ register: volume
+- name: verify test attach Volume with checkmode
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.server != "{{hcloud_server_name}}"
+
+- name: test attach Volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ server: "{{hcloud_server_name}}"
+ register: volume
+- name: verify attach volume
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.server == "{{hcloud_server_name}}"
+
+- name: test attach Volume idempotence
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ server: "{{hcloud_server_name}}"
+ register: volume
+- name: verify attach Volume idempotence
+ assert:
+ that:
+ - volume is not changed
+ - volume.hcloud_volume.server == "{{hcloud_server_name}}"
+
+- name: test detach Volume with checkmode
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ check_mode: yes
+ register: volume
+- name: verify detach Volume with checkmode
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.server == "{{hcloud_server_name}}"
+
+- name: test detach Volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ register: volume
+- name: verify detach volume
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.location == "fsn1"
+ - volume.hcloud_volume.server != "{{hcloud_server_name}}"
+
+- name: test update Volume label
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ labels:
+ key: value
+ register: volume
+- name: verify test update Volume label
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.labels.key == "value"
+
+- name: test update Volume label with the same label
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ labels:
+ key: value
+ register: volume
+- name: verify test update Volume lable with the same label
+ assert:
+ that:
+ - volume is not changed
+
+- name: test increase Volume size
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 11
+ register: volume
+- name: verify test increase Volume size
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.size == 11
+
+- name: test decreace Volume size
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 10
+ register: volume
+- name: verify test decreace Volume size
+ assert:
+ that:
+ - volume is not changed
+ - volume.hcloud_volume.size == 11
+
+- name: test update Volume delete protection
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ delete_protection: true
+ register: volume
+- name: verify test update Volume delete protection
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.delete_protection is sameas true
+
+- name: test update Volume delete protection idempotency
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ delete_protection: true
+ register: volume
+- name: verify test update Volume delete protection idempotency
+ assert:
+ that:
+ - volume is not changed
+ - volume.hcloud_volume.delete_protection is sameas true
+
+- name: test Volume without delete protection set to be idempotent
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ register: volume
+- name: verify test Volume without delete protection set to be idempotent
+ assert:
+ that:
+ - volume is not changed
+ - volume.hcloud_volume.delete_protection is sameas true
+
+- name: test delete Volume fails if it is protected
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete Volume fails if it is protected
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "volume deletion is protected"'
+
+- name: test update Volume delete protection
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ delete_protection: false
+ register: volume
+- name: verify test update Volume delete protection
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.delete_protection is sameas false
+
+- name: test delete Volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ state: absent
+ register: result
+- name: verify delete Volume
+ assert:
+ that:
+ - result is success
+
+
+- name: test create Volume with delete protection
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 10
+ location: "fsn1"
+ delete_protection: true
+ register: volume
+- name: verify create Volume with delete protection
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.delete_protection is sameas true
+
+- name: test delete Volume fails if it is protected
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ state: absent
+ ignore_errors: yes
+ register: result
+- name: verify delete Volume fails if it is protected
+ assert:
+ that:
+ - result is failed
+ - 'result.msg == "volume deletion is protected"'
+
+- name: test update Volume delete protection
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ delete_protection: false
+ register: volume
+- name: verify test update Volume delete protection
+ assert:
+ that:
+ - volume is changed
+ - volume.hcloud_volume.delete_protection is sameas false
+
+- name: test delete Volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ state: absent
+ register: result
+- name: verify delete Volume
+ assert:
+ that:
+ - result is success
+
+- name: cleanup
+ hcloud_server:
+ name: "{{ hcloud_server_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/aliases b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/aliases
new file mode 100644
index 00000000..55ec821a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/aliases
@@ -0,0 +1,2 @@
+cloud/hcloud
+shippable/hcloud/group2
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/defaults/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/defaults/main.yml
new file mode 100644
index 00000000..d308c950
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/defaults/main.yml
@@ -0,0 +1,5 @@
+# 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)
+---
+hcloud_prefix: "tests"
+hcloud_volume_name: "{{hcloud_prefix}}-facts"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/meta/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/meta/main.yml
new file mode 100644
index 00000000..407c9018
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/meta/main.yml
@@ -0,0 +1,3 @@
+collections:
+ - community.general.ipfilter
+ - hetzner.cloud
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/tasks/main.yml
new file mode 100644
index 00000000..ecea7ad3
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/hcloud_volume_info/tasks/main.yml
@@ -0,0 +1,101 @@
+# 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 volume is absent
+ hcloud_volume:
+ name: "{{ hcloud_volume_name }}"
+ state: absent
+ register: result
+
+- name: setup volume
+ hcloud_volume:
+ name: "{{hcloud_volume_name}}"
+ size: 10
+ location: "fsn1"
+ labels:
+ key: value
+ register: main_volume
+- name: verify setup volume
+ assert:
+ that:
+ - main_volume is changed
+
+- name: test gather hcloud volume infos in check mode
+ hcloud_volume_info:
+ register: hcloud_volume
+ check_mode: yes
+
+- name: verify test gather hcloud volume infos in check mode
+ vars:
+ volume: "{{ hcloud_volume.hcloud_volume_info|selectattr('name','equalto',hcloud_volume_name) | first }}"
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info|selectattr('name','equalto','{{ hcloud_volume_name }}') | list | count == 1
+ - volume.name == "{{hcloud_volume_name}}"
+ - volume.location == "fsn1"
+ - volume.size == 10
+ - volume.linux_device is defined
+
+- name: test gather hcloud volume infos with correct label selector
+ hcloud_volume_info:
+ label_selector: "key=value"
+ register: hcloud_volume
+- name: verify test gather hcloud volume infos with correct label selector
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info|selectattr('name','equalto','{{ hcloud_volume_name }}') | list | count == 1
+
+- name: test gather hcloud volume infos with wrong label selector
+ hcloud_volume_info:
+ label_selector: "key!=value"
+ register: hcloud_volume
+- name: verify test gather hcloud volume infos with wrong label selector
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info | list | count == 0
+
+- name: test gather hcloud volume infos with correct name
+ hcloud_volume_info:
+ name: "{{hcloud_volume_name}}"
+ register: hcloud_volume
+- name: verify test gather hcloud volume infos with correct name
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info|selectattr('name','equalto','{{ hcloud_volume_name }}') | list | count == 1
+
+- name: test gather hcloud volume infos with wrong name
+ hcloud_volume_info:
+ name: "{{hcloud_volume_name}}1"
+ register: hcloud_volume
+- name: verify test gather hcloud volume infos with wrong name
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info | list | count == 0
+
+- name: test gather hcloud volume facts with correct id
+ hcloud_volume_info:
+ id: "{{main_volume.hcloud_volume.id}}"
+ register: hcloud_volume
+- name: verify test gather hcloud volume with correct id
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info|selectattr('name','equalto','{{ hcloud_volume_name }}') | list | count == 1
+
+- name: test gather hcloud volume infos with wrong id
+ hcloud_volume_info:
+ name: "4711"
+ register: hcloud_volume
+- name: verify test gather hcloud volume infos with wrong id
+ assert:
+ that:
+ - hcloud_volume.hcloud_volume_info | list | count == 0
+
+- name: cleanup
+ hcloud_volume:
+ name: "{{ hcloud_volume_name }}"
+ state: absent
+ register: result
+- name: verify cleanup
+ assert:
+ that:
+ - result is success
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_selfsigned_certificate/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_selfsigned_certificate/tasks/main.yml
new file mode 100644
index 00000000..27defe44
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_selfsigned_certificate/tasks/main.yml
@@ -0,0 +1,27 @@
+# Copyright: (c) 2020, 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: create a cert temp file
+ tempfile:
+ state: file
+ register: certificate_example_com
+ tags:
+ - prepare
+- name: create a key temp file
+ tempfile:
+ state: file
+ register: certificate_example_com_key
+ tags:
+ - prepare
+ -
+- name: generate certificate
+ shell: openssl req -nodes -new -x509 -keyout {{ certificate_example_com_key.path }} -out {{ certificate_example_com.path }} -subj "/C=DE/ST=Munich/L=Bavaria/O=Dis/CN=www.example.com"
+ tags:
+ - prepare
+
+- name: set facts for future roles
+ set_fact:
+ certificate_example_com: "{{ lookup('file',certificate_example_com.path) }}"
+ certificate_example_com_key: "{{ lookup('file',certificate_example_com_key.path) }}"
+ tags:
+ - prepare
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_sshkey/tasks/main.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_sshkey/tasks/main.yml
new file mode 100644
index 00000000..18c571b6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/integration/targets/setup_sshkey/tasks/main.yml
@@ -0,0 +1,55 @@
+# (c) 2014, James Laska <jlaska@ansible.com>
+
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+- name: create a temp file
+ tempfile:
+ state: file
+ register: sshkey_file
+ tags:
+ - prepare
+
+- name: generate sshkey
+ shell: echo 'y' | ssh-keygen -P '' -f {{ sshkey_file.path }}
+ tags:
+ - prepare
+
+- name: create another temp file
+ tempfile:
+ state: file
+ register: another_sshkey_file
+ tags:
+ - prepare
+
+- name: generate another_sshkey
+ shell: echo 'y' | ssh-keygen -P '' -f {{ another_sshkey_file.path }}
+ tags:
+ - prepare
+
+- name: record fingerprint
+ shell: openssl rsa -in {{ sshkey_file.path }} -pubout -outform DER 2>/dev/null | openssl md5 -c
+ register: fingerprint
+ tags:
+ - prepare
+
+- name: set facts for future roles
+ set_fact:
+ sshkey: '{{ sshkey_file.path }}'
+ key_material: "{{ lookup('file', sshkey_file.path ~ '.pub') }}"
+ another_key_material: "{{ lookup('file', another_sshkey_file.path ~ '.pub') }}"
+ fingerprint: '{{ fingerprint.stdout.split()[1] }}'
+ tags:
+ - prepare
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/requirements.yml b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/requirements.yml
new file mode 100644
index 00000000..6c49d0d9
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/requirements.yml
@@ -0,0 +1,3 @@
+integration_tests_dependencies:
+- community.general
+- ansible.netcommon
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/sanity/requirements.txt b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/sanity/requirements.txt
new file mode 100644
index 00000000..3e3a9669
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/sanity/requirements.txt
@@ -0,0 +1,4 @@
+packaging # needed for update-bundled and changelog
+sphinx ; python_version >= '3.5' # docs build requires python 3+
+sphinx-notfound-page ; python_version >= '3.5' # docs build requires python 3+
+straight.plugin ; python_version >= '3.5' # needed for hacking/build-ansible.py which will host changelog generation and requires python 3+
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/gitlab.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/gitlab.sh
new file mode 100755
index 00000000..33c3af8e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/gitlab.sh
@@ -0,0 +1,96 @@
+#!/usr/bin/env bash
+
+set -o pipefail -eux
+
+declare -a args
+
+IFS='/:' read -ra args <<< "$1"
+
+ansible_version="${args[0]}"
+script="${args[1]}"
+
+function join {
+ local IFS="$1";
+ shift;
+ echo "$*";
+}
+
+test="$(join / "${args[@]:1}")"
+command -v python
+python -V
+
+function retry
+{
+ for repetition in 1 2 3; do
+ set +e
+ "$@"
+ result=$?
+ set -e
+ if [ ${result} == 0 ]; then
+ return ${result}
+ fi
+ echo "$@ -> ${result}"
+ done
+ echo "Command '$@' failed 3 times!"
+ exit -1
+}
+
+command -v pip
+pip --version
+pip list --disable-pip-version-check
+if [ "${ansible_version}" == "devel" ]; then
+ retry pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
+else
+ retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
+fi
+export ANSIBLE_COLLECTIONS_PATHS="${HOME}/.ansible"
+SHIPPABLE_RESULT_DIR="$(pwd)/shippable"
+TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/hetzner/hcloud"
+rm -rf "${TEST_DIR}"
+mkdir -p "${TEST_DIR}"
+cp -r "." "${TEST_DIR}"
+cd "${TEST_DIR}"
+
+# STAR: HACK install dependencies
+retry ansible-galaxy -vvv collection install community.general
+retry ansible-galaxy -vvv collection install ansible.netcommon
+retry ansible-galaxy -vvv collection install community.internal_test_tools
+retry pip install netaddr --disable-pip-version-check
+retry pip install hcloud
+retry pip install rstcheck
+# END: HACK
+
+export PYTHONIOENCODING='utf-8'
+
+if [ "${JOB_TRIGGERED_BY_NAME:-}" == "nightly-trigger" ]; then
+ COMPLETE=yes
+fi
+
+
+if [ -n "${COMPLETE:-}" ]; then
+ # disable change detection triggered by setting the COMPLETE environment variable to a non-empty value
+ export CHANGED=""
+elif [[ "${CI_COMMIT_MESSAGE}" =~ ci_complete ]]; then
+ # disable change detection triggered by having 'ci_complete' in the latest commit message
+ export CHANGED=""
+else
+ # enable change detection (default behavior)
+ export CHANGED=""
+fi
+
+
+export UNSTABLE="--allow-unstable-changed"
+
+# remove empty core/extras module directories from PRs created prior to the repo-merge
+find plugins -type d -empty -print -delete
+
+ansible-test env --dump --show --timeout "50" --color -v
+
+group="${args[1]}"
+echo $test
+if [[ "${test}" =~ hcloud ]]; then
+ group="${args[3]}"
+ bash tests/utils/gitlab/integration.sh "shippable/hcloud/group${group}/"
+else
+ bash tests/utils/gitlab/sanity.sh "sanity/${group}"
+fi
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/integration.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/integration.sh
new file mode 100755
index 00000000..2d660c88
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/integration.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+target="$1"
+
+HCLOUD_TOKEN=$(cat hcloud_token.txt)
+changed_all_target="shippable/${cloud}/smoketest/"
+
+echo "[default]
+hcloud_api_token=${HCLOUD_TOKEN}
+" >> $(pwd)/tests/integration/cloud-config-hcloud.ini
+# shellcheck disable=SC2086
+export SHIPPABLE="true"
+export SHIPPABLE_BUILD_NUMBER="gl-$(cat prefix.txt)"
+export SHIPPABLE_JOB_NUMBER="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 2 | head -n 1)"
+ansible-test integration --color --local -vv "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"}
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/sanity.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/sanity.sh
new file mode 100755
index 00000000..1418edc0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/gitlab/sanity.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+set -o pipefail -eux
+
+declare -a args
+IFS='/:' read -ra args <<< "$1"
+
+group="${args[1]}"
+
+if [ "${BASE_BRANCH:-}" ]; then
+ base_branch="origin/${BASE_BRANCH}"
+else
+ base_branch=""
+fi
+
+if [ "${group}" == "extra" ]; then
+ ../internal_test_tools/tools/run.py --color
+ exit
+fi
+
+case "${group}" in
+ 1) options=(--skip-test pylint --skip-test ansible-doc --skip-test validate-modules) ;;
+ 2) options=( --test ansible-doc --test validate-modules) ;;
+ 3) options=(--test pylint plugins/modules/) ;;
+ 4) options=(--test pylint --exclude plugins/modules/) ;;
+esac
+
+# allow collection migration sanity tests for groups 3 and 4 to pass without updating this script during migration
+network_path="lib/ansible/modules/network/"
+
+if [ -d "${network_path}" ]; then
+ if [ "${group}" -eq 3 ]; then
+ options+=(--exclude "${network_path}")
+ elif [ "${group}" -eq 4 ]; then
+ options+=("${network_path}")
+ fi
+fi
+
+pip install pycodestyle
+pip install yamllint
+pip install voluptuous
+pip install pylint
+# shellcheck disable=SC2086
+ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
+ --base-branch "${base_branch}" \
+ --exclude shippable.yml --exclude tests/utils/ \
+ "${options[@]}" --allow-disabled
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/check_matrix.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/check_matrix.py
new file mode 100755
index 00000000..dfcca3e6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/check_matrix.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+"""Verify the currently executing Shippable test matrix matches the one defined in the "shippable.yml" file."""
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import datetime
+import json
+import os
+import re
+import sys
+import time
+
+try:
+ from typing import NoReturn
+except ImportError:
+ NoReturn = None
+
+try:
+ # noinspection PyCompatibility
+ from urllib2 import urlopen # pylint: disable=ansible-bad-import-from
+except ImportError:
+ # noinspection PyCompatibility
+ from urllib.request import urlopen
+
+
+def main(): # type: () -> None
+ """Main entry point."""
+ repo_full_name = os.environ['REPO_FULL_NAME']
+ required_repo_full_name = 'ansible-collections/hetzner.hcloud'
+
+ if repo_full_name != required_repo_full_name:
+ sys.stderr.write('Skipping matrix check on repo "%s" which is not "%s".\n' % (repo_full_name, required_repo_full_name))
+ return
+
+ with open('shippable.yml', 'rb') as yaml_file:
+ yaml = yaml_file.read().decode('utf-8').splitlines()
+
+ defined_matrix = [match.group(1) for match in [re.search(r'^ *- env: T=(.*)$', line) for line in yaml] if match and match.group(1) != 'none']
+
+ if not defined_matrix:
+ fail('No matrix entries found in the "shippable.yml" file.',
+ 'Did you modify the "shippable.yml" file?')
+
+ run_id = os.environ['SHIPPABLE_BUILD_ID']
+ sleep = 1
+ jobs = []
+
+ for attempts_remaining in range(4, -1, -1):
+ try:
+ jobs = json.loads(urlopen('https://api.shippable.com/jobs?runIds=%s' % run_id).read())
+
+ if not isinstance(jobs, list):
+ raise Exception('Shippable run %s data is not a list.' % run_id)
+
+ break
+ except Exception as ex:
+ if not attempts_remaining:
+ fail('Unable to retrieve Shippable run %s matrix.' % run_id,
+ str(ex))
+
+ sys.stderr.write('Unable to retrieve Shippable run %s matrix: %s\n' % (run_id, ex))
+ sys.stderr.write('Trying again in %d seconds...\n' % sleep)
+ time.sleep(sleep)
+ sleep *= 2
+
+ if len(jobs) != len(defined_matrix):
+ if len(jobs) == 1:
+ hint = '\n\nMake sure you do not use the "Rebuild with SSH" option.'
+ else:
+ hint = ''
+
+ fail('Shippable run %s has %d jobs instead of the expected %d jobs.' % (run_id, len(jobs), len(defined_matrix)),
+ 'Try re-running the entire matrix.%s' % hint)
+
+ actual_matrix = dict((job.get('jobNumber'), dict(tuple(line.split('=', 1)) for line in job.get('env', [])).get('T', '')) for job in jobs)
+ errors = [(job_number, test, actual_matrix.get(job_number)) for job_number, test in enumerate(defined_matrix, 1) if actual_matrix.get(job_number) != test]
+
+ if len(errors):
+ error_summary = '\n'.join('Job %s expected "%s" but found "%s" instead.' % (job_number, expected, actual) for job_number, expected, actual in errors)
+
+ fail('Shippable run %s has a job matrix mismatch.' % run_id,
+ 'Try re-running the entire matrix.\n\n%s' % error_summary)
+
+
+def fail(message, output): # type: (str, str) -> NoReturn
+ # Include a leading newline to improve readability on Shippable "Tests" tab.
+ # Without this, the first line becomes indented.
+ output = '\n' + output.strip()
+
+ timestamp = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
+
+ # hack to avoid requiring junit-xml, which isn't pre-installed on Shippable outside our test containers
+ xml = '''
+<?xml version="1.0" encoding="utf-8"?>
+<testsuites disabled="0" errors="1" failures="0" tests="1" time="0.0">
+\t<testsuite disabled="0" errors="1" failures="0" file="None" log="None" name="ansible-test" skipped="0" tests="1" time="0" timestamp="%s" url="None">
+\t\t<testcase classname="timeout" name="timeout">
+\t\t\t<error message="%s" type="error">%s</error>
+\t\t</testcase>
+\t</testsuite>
+</testsuites>
+''' % (timestamp, message, output)
+
+ path = 'shippable/testresults/check-matrix.xml'
+ dir_path = os.path.dirname(path)
+
+ if not os.path.exists(dir_path):
+ os.makedirs(dir_path)
+
+ with open(path, 'w') as junit_fd:
+ junit_fd.write(xml.lstrip())
+
+ sys.stderr.write(message + '\n')
+ sys.stderr.write(output + '\n')
+
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/hcloud.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/hcloud.sh
new file mode 100755
index 00000000..da037e09
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/hcloud.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+set -o pipefail -eux
+
+declare -a args
+IFS='/:' read -ra args <<< "$1"
+
+cloud="${args[0]}"
+python="${args[1]}"
+group="${args[2]}"
+
+target="shippable/${cloud}/group${group}/"
+
+stage="${S:-prod}"
+
+changed_all_target="shippable/${cloud}/smoketest/"
+
+if ! ansible-test integration "${changed_all_target}" --list-targets > /dev/null 2>&1; then
+ # no smoketest tests are available for this cloud
+ changed_all_target="none"
+fi
+
+if [ "${group}" == "1" ]; then
+ # only run smoketest tests for group1
+ changed_all_mode="include"
+else
+ # smoketest tests already covered by group1
+ changed_all_mode="exclude"
+fi
+
+# shellcheck disable=SC2086
+ansible-test integration --color -v --retry-on-error "${target}" ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} ${UNSTABLE:+"$UNSTABLE"} \
+ --remote-terminate always --remote-stage "${stage}" \
+ --docker --python "${python}" --changed-all-target "${changed_all_target}" --changed-all-mode "${changed_all_mode}"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/sanity.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/sanity.sh
new file mode 100755
index 00000000..1c297c58
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/sanity.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+set -o pipefail -eux
+
+declare -a args
+IFS='/:' read -ra args <<< "$1"
+
+group="${args[1]}"
+
+if [ "${BASE_BRANCH:-}" ]; then
+ base_branch="origin/${BASE_BRANCH}"
+else
+ base_branch=""
+fi
+
+if [ "${group}" == "extra" ]; then
+ pip install antsibull-changelog
+ python ../../community/internal_test_tools/tools/run.py --color
+ exit
+fi
+
+case "${group}" in
+ 1) options=(--skip-test pylint --skip-test ansible-doc --skip-test validate-modules) ;;
+ 2) options=( --test ansible-doc --test validate-modules) ;;
+ 3) options=(--test pylint plugins/modules/) ;;
+ 4) options=(--test pylint --exclude plugins/modules/) ;;
+esac
+
+# allow collection migration sanity tests for groups 3 and 4 to pass without updating this script during migration
+network_path="lib/ansible/modules/network/"
+
+if [ -d "${network_path}" ]; then
+ if [ "${group}" -eq 3 ]; then
+ options+=(--exclude "${network_path}")
+ elif [ "${group}" -eq 4 ]; then
+ options+=("${network_path}")
+ fi
+fi
+
+# shellcheck disable=SC2086
+ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
+ --docker --base-branch "${base_branch}" \
+ --exclude shippable.yml --exclude tests/utils/ \
+ "${options[@]}" --allow-disabled
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/shippable.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/shippable.sh
new file mode 100755
index 00000000..9303277f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/shippable.sh
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+
+set -o pipefail -eux
+
+declare -a args
+IFS='/:' read -ra args <<< "$1"
+
+ansible_version="${args[0]}"
+script="${args[1]}"
+
+function join {
+ local IFS="$1";
+ shift;
+ echo "$*";
+}
+
+test="$(join / "${args[@]:1}")"
+
+docker images ansible/ansible
+docker images quay.io/ansible/*
+docker ps
+
+for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v '^drydock/' | sed 's/^.* //'); do
+ docker rm -f "${container}" || true # ignore errors
+done
+
+docker ps
+
+if [ -d /home/shippable/cache/ ]; then
+ ls -la /home/shippable/cache/
+fi
+
+command -v python
+python -V
+
+function retry
+{
+ for repetition in 1 2 3; do
+ set +e
+ "$@"
+ result=$?
+ set -e
+ if [ ${result} == 0 ]; then
+ return ${result}
+ fi
+ echo "$@ -> ${result}"
+ done
+ echo "Command '$@' failed 3 times!"
+ exit -1
+}
+
+command -v pip
+pip --version
+pip list --disable-pip-version-check
+if [ "${ansible_version}" == "devel" ]; then
+ retry pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
+else
+ retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
+fi
+export ANSIBLE_COLLECTIONS_PATHS="${HOME}/.ansible"
+SHIPPABLE_RESULT_DIR="$(pwd)/shippable"
+TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/hetzner/hcloud"
+mkdir -p "${TEST_DIR}"
+cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}"
+cd "${TEST_DIR}"
+
+# STAR: HACK install dependencies
+retry ansible-galaxy -vvv collection install community.general
+retry ansible-galaxy -vvv collection install ansible.netcommon
+
+retry pip install hcloud
+retry pip install netaddr --disable-pip-version-check
+retry ansible-galaxy -vvv collection install community.internal_test_tools
+# END: HACK
+
+export PYTHONIOENCODING='utf-8'
+
+if [ "${JOB_TRIGGERED_BY_NAME:-}" == "nightly-trigger" ]; then
+ COMPLETE=yes
+fi
+
+
+if [ -n "${COMPLETE:-}" ]; then
+ # disable change detection triggered by setting the COMPLETE environment variable to a non-empty value
+ export CHANGED=""
+elif [[ "${COMMIT_MESSAGE}" =~ ci_complete ]]; then
+ # disable change detection triggered by having 'ci_complete' in the latest commit message
+ export CHANGED=""
+else
+ # enable change detection (default behavior)
+ export CHANGED="--changed"
+fi
+
+if [ "${IS_PULL_REQUEST:-}" == "true" ]; then
+ # run unstable tests which are targeted by focused changes on PRs
+ export UNSTABLE="--allow-unstable-changed"
+else
+ # do not run unstable tests outside PRs
+ export UNSTABLE=""
+fi
+
+# remove empty core/extras module directories from PRs created prior to the repo-merge
+find plugins -type d -empty -print -delete
+
+function cleanup
+{
+ if [ -d tests/output/junit/ ]; then
+ cp -aT tests/output/junit/ "$SHIPPABLE_RESULT_DIR/testresults/"
+ fi
+
+ if [ -d tests/output/data/ ]; then
+ cp -a tests/output/data/ "$SHIPPABLE_RESULT_DIR/testresults/"
+ fi
+
+ if [ -d tests/output/bot/ ]; then
+ cp -aT tests/output/bot/ "$SHIPPABLE_RESULT_DIR/testresults/"
+ fi
+}
+
+trap cleanup EXIT
+
+ansible-test env --dump --show --timeout "50" --color -v
+
+"tests/utils/shippable/check_matrix.py"
+"tests/utils/shippable/${script}.sh" "${test}"
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.py b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.py
new file mode 100755
index 00000000..fb538271
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3.7
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import sys
+import time
+
+start = time.time()
+
+sys.stdin.reconfigure(errors='surrogateescape')
+sys.stdout.reconfigure(errors='surrogateescape')
+
+for line in sys.stdin:
+ seconds = time.time() - start
+ sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
+ sys.stdout.flush()
diff --git a/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.sh b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.sh
new file mode 100755
index 00000000..77e25783
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/hetzner/hcloud/tests/utils/shippable/timing.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -o pipefail -eu
+
+"$@" 2>&1 | "$(dirname "$0")/timing.py"