#!/usr/bin/env python3 import os import sys import json import requests API_URL = "https://api.linode.com/v4/linode/instances" TOKEN = os.getenv("LINODE_TOKEN") if not TOKEN: print("ERROR: LINODE_TOKEN environment variable not set", file=sys.stderr) sys.exit(1) headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json" } def get_linode_instances(): instances = [] page = 1 while True: r = requests.get(API_URL, headers=headers, params={"page": page}) if r.status_code != 200: print(f"ERROR: Failed to fetch Linodes (status code {r.status_code})", file=sys.stderr) sys.exit(1) data = r.json() instances.extend(data["data"]) if not data["pages"] or page >= data["pages"]: break page += 1 return instances def build_inventory(): instances = get_linode_instances() inventory = { "_meta": { "hostvars": {} } } for linode in instances: label = linode["label"] ipv4 = linode["ipv4"][0] if linode["ipv4"] else None region = linode["region"] tags = linode.get("tags", []) if not ipv4: continue inventory["_meta"]["hostvars"][label] = { "ansible_host": ipv4, "linode_id": linode["id"], "region": region, "tags": tags, "type": linode["type"] } # Group by region region_group = f"region_{region}" inventory.setdefault(region_group, {"hosts": []})["hosts"].append(label) # Group by tag for tag in tags: tag_group = f"tag_{tag}" inventory.setdefault(tag_group, {"hosts": []})["hosts"].append(label) return inventory def main(): if len(sys.argv) == 2 and sys.argv[1] == "--list": print(json.dumps(build_inventory(), indent=2)) elif len(sys.argv) == 2 and sys.argv[1] == "--host": print(json.dumps({})) # Not used else: print("Usage: linode_inventory.py --list", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main()