Skip to content

Commit

Permalink
Use hostnames instead of hostvar_expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
cognifloyd committed Jun 26, 2020
1 parent 72147af commit 9a30456
Showing 1 changed file with 45 additions and 15 deletions.
60 changes: 45 additions & 15 deletions plugins/inventory/azure_rm.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@
type: bool
default: False
version_added: '2.8'
hostnames:
description:
- A list of Jinja2 expressions in order of precedence to compose inventory_hostname.
- Ignores expression if result is an empty string or None value.
- By default, inventory_hostname is generated to be globally unique based on the VM host name.
See C(plain_host_names) for more details on the default.
- An expression of 'default' will force using the default hostname generator if no previous
hostname expression resulted in a valid hostname.
- Use ``default_inventory_hostname`` to access the default hostname generator's value in
any of the Jinja2 expressions.
type: list
default: [default]
'''

EXAMPLES = '''
Expand Down Expand Up @@ -138,9 +150,11 @@
# overrides the default ansible_host value with a custom Jinja2 expression, in this case, the first DNS hostname, or
# if none are found, the first public IP address.
ansible_host: (public_dns_hostnames + public_ipv4_addresses) | first
# overrides the default inventory_hostname value with a custom Jinja2 expression, in this case, a tag called vm_name.
# if the tag is not found, use the default_inventory_hostname (see plain_host_names).
inventory_hostname: tags.vm_name | default(default_inventory_hostname)
# change how inventory_hostname is generated. Each item is a jinja2 expression similar to hostvar_expressions.
hostnames:
- tags.vm_name
- default # special var that uses the default hashed name
# places hosts in dynamically-created groups based on a variable value.
keyed_groups:
Expand Down Expand Up @@ -184,7 +198,7 @@
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMAuth
from ansible.errors import AnsibleParserError, AnsibleError
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.module_utils._text import to_native, to_bytes
from ansible.module_utils._text import to_native, to_bytes, to_text
from itertools import chain
from msrest import ServiceClient, Serializer, Deserializer
from msrestazure import AzureConfiguration
Expand Down Expand Up @@ -329,13 +343,14 @@ def _get_hosts(self):

constructable_config_strict = boolean(self.get_option('fail_on_template_errors'))
constructable_config_compose = self.get_option('hostvar_expressions')
constructable_config_inventory_hostname = constructable_config_compose.pop('inventory_hostname')
constructable_config_groups = self.get_option('conditional_groups')
constructable_config_keyed_groups = self.get_option('keyed_groups')

constructable_hostnames = self.get_option('hostnames')

for h in self._hosts:
# FUTURE: track hostnames to warn if a hostname is repeated (can happen for legacy and for composed inventory_hostname)
inventory_hostname = self._get_hostname(h, compose=constructable_config_inventory_hostname, strict=constructable_config_strict)
inventory_hostname = self._get_hostname(h, hostnames=constructable_hostnames, strict=constructable_config_strict)
if self._filter_host(inventory_hostname, h.hostvars):
continue
self.inventory.add_host(inventory_hostname)
Expand Down Expand Up @@ -368,15 +383,30 @@ def _filter_host(self, inventory_hostname, hostvars):

return False

def _get_hostname(self, host, compose=None, strict=False):
if not compose:
return host.default_inventory_hostname
try:
return self._compose(compose, host.hostvars)
except Exception as e:
if strict:
raise AnsibleParserError("Error generating inventory_hostname with '{0}' (hostvar_expressions.inventory_hostname) for host {1}: {2}".format(compose, host.default_inventory_hostname, to_native(e))
return host.default_inventory_hostname
def _get_hostname(self, host, hostnames=None, strict=False):
hostname = None
errors = []

for preference in hostnames:
if preference == 'default':
return host.default_inventory_hostname
try:
hostname = self._compose(preference, host.hostvars)
except Exception as e: # pylint: disable=broad-except
if strict:
raise AnsibleError("Could not compose %s as hostnames - %s" % (preference, to_native(e)))
else:
errors.append(
(preference, str(e))
)
if hostname:
return to_text(hostname)

raise AnsibleError(
'Could not template any hostname for host, errors for each preference: %s' % (
', '.join(['%s: %s' % (pref, err) for pref, err in errors])
)
)

def _process_queue_serial(self):
try:
Expand Down

0 comments on commit 9a30456

Please sign in to comment.