diff --git a/changelogs/fragments/inventory-connect-via-ipv6.yml b/changelogs/fragments/inventory-connect-via-ipv6.yml new file mode 100644 index 0000000..3276c4b --- /dev/null +++ b/changelogs/fragments/inventory-connect-via-ipv6.yml @@ -0,0 +1,4 @@ +minor_changes: + - inventory plugin - Add new connect_with setting public_ipv6 to connect to discovered servers via public IPv6 address. +breaking_changes: + - inventory plugin - Python v3.5+ is now required. diff --git a/plugins/inventory/hcloud.py b/plugins/inventory/hcloud.py index a802e1f..7f7063f 100644 --- a/plugins/inventory/hcloud.py +++ b/plugins/inventory/hcloud.py @@ -11,7 +11,7 @@ DOCUMENTATION = r''' - Lukas Kaemmerling (@lkaemmerling) short_description: Ansible dynamic inventory plugin for the Hetzner Cloud. requirements: - - python >= 2.7 + - python >= 3.5 - hcloud-python >= 1.0.0 description: - Reads inventories from the Hetzner Cloud API. @@ -42,6 +42,7 @@ DOCUMENTATION = r''' type: str choices: - public_ipv4 + - public_ipv6 - hostname - ipv4_dns_ptr - private_ipv4 @@ -113,6 +114,7 @@ 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__ +from ipaddress import IPv6Network try: from hcloud import hcloud @@ -222,6 +224,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable): if self.get_option("connect_with") == "public_ipv4": self.inventory.set_variable(server.name, "ansible_host", to_native(server.public_net.ipv4.ip)) + if self.get_option("connect_with") == "public_ipv6": + self.inventory.set_variable(server.name, "ansible_host", to_native(self._first_ipv6_address(server.public_net.ipv6.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": @@ -259,6 +263,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable): # Labels self.inventory.set_variable(server.name, "labels", dict(server.labels)) + def _first_ipv6_address(self, network): + return next(IPv6Network(network).hosts()) + def verify_file(self, path): """Return the possibly of a file being consumable by this plugin.""" return (