Skip to content

Commit 0a6b540

Browse files
authored
Fix host resolution with minified inventory (#2121)
ansible-inventory --list does not populate _meta.hostvars for hosts without variables. The minified inventory has no host variables, so _meta.hostvars is always empty, breaking --limit and host listing. Extract hosts from group listings as well via a new get_hosts_from_inventory() helper. AI-assisted: Claude Code Signed-off-by: Christian Berendt <berendt@osism.tech>
1 parent 822854f commit 0a6b540

5 files changed

Lines changed: 26 additions & 17 deletions

File tree

osism/api.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from osism.tasks import reconciler, openstack
2727
from osism import utils
28-
from osism.utils.inventory import get_inventory_path
28+
from osism.utils.inventory import get_hosts_from_inventory, get_inventory_path
2929
from osism.services.listener import BaremetalEvents
3030
from osism.services.websocket_manager import websocket_manager
3131
from osism.services.event_bridge import event_bridge
@@ -766,9 +766,8 @@ async def get_inventory_hosts(limit: Optional[str] = None) -> HostsResponse:
766766

767767
data = json.loads(result.stdout)
768768
logger.debug(f"Inventory data keys: {list(data.keys())}")
769-
hosts = list(data.get("_meta", {}).get("hostvars", {}).keys())
769+
hosts = get_hosts_from_inventory(data)
770770
logger.debug(f"Found {len(hosts)} hosts in inventory")
771-
hosts.sort()
772771

773772
return HostsResponse(hosts=hosts, count=len(hosts))
774773
except subprocess.TimeoutExpired:
@@ -1071,7 +1070,7 @@ async def search_inventory(
10711070
)
10721071

10731072
inventory_data = json.loads(result.stdout)
1074-
all_hosts = list(inventory_data.get("_meta", {}).get("hostvars", {}).keys())
1073+
all_hosts = get_hosts_from_inventory(inventory_data)
10751074

10761075
# Filter hosts by pattern
10771076
if host_regex:

osism/commands/get.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from osism.tasks import Config
1515
from osism.utils import redis
16-
from osism.utils.inventory import get_inventory_path
16+
from osism.utils.inventory import get_hosts_from_inventory, get_inventory_path
1717

1818

1919
class VersionsManager(Command):
@@ -249,7 +249,7 @@ def take_action(self, parsed_args):
249249
data = json.loads(result)
250250
table = []
251251

252-
for host in data["_meta"]["hostvars"]:
252+
for host in get_hosts_from_inventory(data):
253253
table.append([host])
254254

255255
if table:

osism/commands/report.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from osism import settings
1212
from osism.commands.console import resolve_host_with_fallback
13-
from osism.utils.inventory import get_inventory_path
13+
from osism.utils.inventory import get_hosts_from_inventory, get_inventory_path
1414
from osism.utils.ssh import ensure_known_hosts_file, KNOWN_HOSTS_PATH
1515

1616

@@ -56,7 +56,7 @@ def take_action(self, parsed_args):
5656
return
5757

5858
data = json.loads(result.stdout)
59-
hosts = sorted(data.get("_meta", {}).get("hostvars", {}).keys())
59+
hosts = get_hosts_from_inventory(data)
6060

6161
if not hosts:
6262
logger.error("No hosts found in inventory.")
@@ -194,7 +194,7 @@ def take_action(self, parsed_args):
194194
return
195195

196196
data = json.loads(result.stdout)
197-
hosts = sorted(data.get("_meta", {}).get("hostvars", {}).keys())
197+
hosts = get_hosts_from_inventory(data)
198198

199199
if not hosts:
200200
logger.error("No hosts found in inventory.")
@@ -341,7 +341,7 @@ def take_action(self, parsed_args):
341341
return
342342

343343
data = json.loads(result.stdout)
344-
hosts = sorted(data.get("_meta", {}).get("hostvars", {}).keys())
344+
hosts = get_hosts_from_inventory(data)
345345

346346
if not hosts:
347347
logger.error("No hosts found in inventory.")

osism/utils/inventory.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,18 @@ def get_inventory_path(base_path: str, prefer_minified: bool = True) -> str:
2727
logger.debug(f"Using minified inventory: {minified_path}")
2828
return minified_path
2929
return base_path
30+
31+
32+
def get_hosts_from_inventory(data: dict) -> list:
33+
"""Extract host names from ansible-inventory --list JSON output.
34+
35+
The minified inventory does not populate _meta.hostvars (since hosts
36+
have no variables), so we also collect hosts from group listings.
37+
"""
38+
hosts = set(data.get("_meta", {}).get("hostvars", {}).keys())
39+
for key, value in data.items():
40+
if key == "_meta":
41+
continue
42+
if isinstance(value, dict) and "hosts" in value:
43+
hosts.update(value["hosts"])
44+
return sorted(hosts)

osism/utils/rabbitmq.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from osism.tasks.conductor.utils import get_vault
1212
from osism.utils import redis
13-
from osism.utils.inventory import get_inventory_path
13+
from osism.utils.inventory import get_hosts_from_inventory, get_inventory_path
1414

1515

1616
def get_rabbitmq_node_addresses():
@@ -30,12 +30,7 @@ def get_rabbitmq_node_addresses():
3030
)
3131
inventory = json.loads(result)
3232

33-
# Get hosts from _meta.hostvars (contains all hosts matching the limit)
34-
if "_meta" not in inventory or "hostvars" not in inventory["_meta"]:
35-
logger.error("Invalid inventory format: _meta.hostvars not found")
36-
return None
37-
38-
rabbitmq_hosts = list(inventory["_meta"]["hostvars"].keys())
33+
rabbitmq_hosts = get_hosts_from_inventory(inventory)
3934
if not rabbitmq_hosts:
4035
logger.error("No hosts found in rabbitmq group")
4136
return None

0 commit comments

Comments
 (0)