From b3d2abb3c9d249b70118f9ed42da48f08c1c56f1 Mon Sep 17 00:00:00 2001 From: Jacob Callahan Date: Thu, 2 Mar 2023 14:28:55 -0500 Subject: [PATCH] Allow for additional arguments to be passed to provider help commands This change allows users to pass along additional arguments to provider help commands. Providers can then choose to use these arguments as they see fit. One newly possible example is to specify a tower_inventory when listing the available templates for AnsibleTower. I also added a couple of new logging statements to make it more clear what tower inventory is being used by Broker and when. --- broker/commands.py | 26 +++++++++++++++++++++----- broker/providers/ansible_tower.py | 13 ++++++++++++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/broker/commands.py b/broker/commands.py index 1b03313c..9e39606a 100644 --- a/broker/commands.py +++ b/broker/commands.py @@ -12,11 +12,13 @@ signal.signal(signal.SIGINT, helpers.handle_keyboardinterrupt) -def loggedcli(*cli_args, **cli_kwargs): - """Updates the cli.command wrapper function in order to add logging""" +def loggedcli(group=None, *cli_args, **cli_kwargs): + """Updates the group command wrapper function in order to add logging""" + if not group: + group = cli # default to the main cli group def decorator(func): - @cli.command(*cli_args, **cli_kwargs) + @group.command(*cli_args, **cli_kwargs) @wraps(func) def wrapper(*args, **kwargs): logger.log(LOG_LEVEL.TRACE.value, f"Calling {func=}(*{args=} **{kwargs=}") @@ -72,9 +74,23 @@ def populate_providers(click_group): """ for prov, prov_class in (pairs for pairs in PROVIDERS.items()): - @click_group.command(name=prov, hidden=prov_class.hidden) - def provider_cmd(*args, **kwargs): # the actual subcommand + @loggedcli( + group=click_group, + name=prov, + hidden=prov_class.hidden, + context_settings={"allow_extra_args": True, "ignore_unknown_options": True}, + ) + @click.pass_context + def provider_cmd(ctx, *args, **kwargs): # the actual subcommand """Get information about a provider's actions""" + # if additional arguments were passed, include them in the broker args + # strip leading -- characters + kwargs.update( + { + (key[2:] if key.startswith("--") else key): val + for key, val in zip(ctx.args[::2], ctx.args[1::2]) + } + ) broker_inst = Broker(**kwargs) broker_inst.nick_help() diff --git a/broker/providers/ansible_tower.py b/broker/providers/ansible_tower.py index 8cc328ab..aae67c0e 100644 --- a/broker/providers/ansible_tower.py +++ b/broker/providers/ansible_tower.py @@ -348,10 +348,15 @@ def _get_expire_date(self, host_id): return None def _compile_host_info(self, host): + # attempt to get the hostname from the host variables and then facts + if not (hostname := host.variables.get("fqdn")): + if hasattr(host_facts := host.related.ansible_facts.get(), "results"): + hostname = host_facts.results[0].ansible_facts.get("ansible_fqdn") host_info = { "name": host.name, "type": host.type, - "hostname": host.variables.get("fqdn"), + "hostname": hostname, + "ip": host.variables.get("ansible_host"), "tower_inventory": self._translate_inventory(host.inventory), "_broker_provider": "AnsibleTower", "_broker_provider_instance": self.instance, @@ -480,8 +485,14 @@ def execute(self, **kwargs): payload = {} if inventory := kwargs.pop("inventory", None): payload["inventory"] = inventory + logger.info( + f"Using tower inventory: {self._translate_inventory(inventory)}" + ) elif self.inventory: payload["inventory"] = self.inventory + logger.info( + f"Using tower inventory: {self._translate_inventory(self.inventory)}" + ) else: logger.info("No inventory specified, Ansible Tower will use a default.") payload["extra_vars"] = str(kwargs)