Repository: ansible-collections/community.general

Issue:
Icinga2 inventory source: get API user credentials from variables
### Summary

In my inventory.icinga2.yaml, I don't want to save the Icinga API credentials (for security reasons). I tried using variables but I failed:
```
user: '{{ IcingaApiUser }}'
password: '{{ IcingaApiPass }}'
```

That way I could provide these credentials when calling ansible-playbook from the command line.

### Issue Type

Feature Idea

### Component Name

icinga2 inventory

### Additional Information

_No response_

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/inventory/icinga2.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/icinga2.py)

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @BongoEADGC6
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Right now only the linode inventory plugin (for `access_token`) and the proxmox inventory plugin (for `url`, `user`, `password`, `token_id`, and `token_secret`) template their inputs. Supporting templating of `user` and `password` in a similar way should be possible (and not that hard to implement) for the icinga2 inventory plugin.
> That way I could provide these credentials when calling ansible-playbook from the command line.

You could also load them with the hashivault or the sops lookup plugin, you could use ansible's unvault filter, or use some other random lookup/... plugin to obtain them. Then you don't have to pass them for every ansible-playbook invocation.

Resolving patch:
diff --git a/plugins/inventory/icinga2.py b/plugins/inventory/icinga2.py
--- a/plugins/inventory/icinga2.py
+++ b/plugins/inventory/icinga2.py
@@ -277,12 +277,22 @@ def parse(self, inventory, loader, path, cache=True):
         self._read_config_data(path)
 
         # Store the options from the YAML file
-        self.icinga2_url = self.get_option('url').rstrip('/') + '/v1'
+        self.icinga2_url = self.get_option('url')
         self.icinga2_user = self.get_option('user')
         self.icinga2_password = self.get_option('password')
         self.ssl_verify = self.get_option('validate_certs')
         self.host_filter = self.get_option('host_filter')
         self.inventory_attr = self.get_option('inventory_attr')
+
+        if self.templar.is_template(self.icinga2_url):
+            self.icinga2_url = self.templar.template(variable=self.icinga2_url, disable_lookups=False)
+        if self.templar.is_template(self.icinga2_user):
+            self.icinga2_user = self.templar.template(variable=self.icinga2_user, disable_lookups=False)
+        if self.templar.is_template(self.icinga2_password):
+            self.icinga2_password = self.templar.template(variable=self.icinga2_password, disable_lookups=False)
+
+        self.icinga2_url = self.icinga2_url.rstrip('/') + '/v1'
+
         # Not currently enabled
         # self.cache_key = self.get_cache_key(path)
         # self.use_cache = cache and self.get_option('cache')


Test patch: