diff --git a/awx/plugins/inventory/foreman.ini.example b/awx/plugins/inventory/foreman.ini.example index 055c82cdb4..e3946daf02 100644 --- a/awx/plugins/inventory/foreman.ini.example +++ b/awx/plugins/inventory/foreman.ini.example @@ -152,6 +152,12 @@ want_hostcollections = False # Disabled by default as the change would else not be backward compatible. rich_params = False +# Whether to populate the ansible_ssh_host variable to explicitly specify the +# connection target. Only tested with Katello (Red Hat Satellite). +# If the foreman 'ip' fact exists then the ansible_ssh_host varibale is populated +# to permit connections where DNS resolution fails. +want_ansible_ssh_host = False + [cache] path = . max_age = 60 diff --git a/awx/plugins/inventory/foreman.py b/awx/plugins/inventory/foreman.py index e1ca8787d6..f51d073b17 100755 --- a/awx/plugins/inventory/foreman.py +++ b/awx/plugins/inventory/foreman.py @@ -46,6 +46,8 @@ if LooseVersion(requests.__version__) < LooseVersion('1.1.0'): from requests.auth import HTTPBasicAuth +from ansible.module_utils._text import to_text + def json_format_dict(data, pretty=False): """Converts a dict to a JSON object and dumps it as a formatted string""" @@ -113,6 +115,11 @@ class ForemanInventory(object): except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): self.want_hostcollections = False + try: + self.want_ansible_ssh_host = config.getboolean('ansible', 'want_ansible_ssh_host') + except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): + self.want_ansible_ssh_host = False + # Do we want parameters to be interpreted if possible as JSON? (no by default) try: self.rich_params = config.getboolean('ansible', 'rich_params') @@ -229,10 +236,6 @@ class ForemanInventory(object): return params - def _get_facts_by_id(self, hid): - url = "%s/api/v2/hosts/%s/facts" % (self.foreman_url, hid) - return self._get_json(url) - def _get_facts(self, host): """Fetch all host facts of the host""" if not self.want_facts: @@ -289,20 +292,32 @@ class ForemanInventory(object): group = 'hostgroup' val = host.get('%s_title' % group) or host.get('%s_name' % group) if val: - safe_key = self.to_safe('%s%s_%s' % (self.group_prefix, group, val.lower())) + safe_key = self.to_safe('%s%s_%s' % ( + to_text(self.group_prefix), + group, + to_text(val).lower() + )) self.inventory[safe_key].append(dns_name) # Create ansible groups for environment, location and organization for group in ['environment', 'location', 'organization']: val = host.get('%s_name' % group) if val: - safe_key = self.to_safe('%s%s_%s' % (self.group_prefix, group, val.lower())) + safe_key = self.to_safe('%s%s_%s' % ( + to_text(self.group_prefix), + group, + to_text(val).lower() + )) self.inventory[safe_key].append(dns_name) for group in ['lifecycle_environment', 'content_view']: val = host.get('content_facet_attributes', {}).get('%s_name' % group) if val: - safe_key = self.to_safe('%s%s_%s' % (self.group_prefix, group, val.lower())) + safe_key = self.to_safe('%s%s_%s' % ( + to_text(self.group_prefix), + group, + to_text(val).lower() + )) self.inventory[safe_key].append(dns_name) params = self._resolve_params(host_params) @@ -311,7 +326,7 @@ class ForemanInventory(object): # attributes. groupby = dict() for k, v in params.items(): - groupby[k] = self.to_safe(str(v)) + groupby[k] = self.to_safe(to_text(v)) # The name of the ansible groups is given by group_patterns: for pattern in self.group_patterns: @@ -424,6 +439,8 @@ class ForemanInventory(object): 'foreman': self.cache[hostname], 'foreman_params': self.params[hostname], } + if self.want_ansible_ssh_host and 'ip' in self.cache[hostname]: + self.inventory['_meta']['hostvars'][hostname]['ansible_ssh_host'] = self.cache[hostname]['ip'] if self.want_facts: self.inventory['_meta']['hostvars'][hostname]['foreman_facts'] = self.facts[hostname] @@ -440,5 +457,6 @@ class ForemanInventory(object): self._print_data() return True + if __name__ == '__main__': sys.exit(not ForemanInventory().run())