Add inventory role for Linode
This commit is contained in:
82
custom_scripts/linode_inventory.py
Executable file
82
custom_scripts/linode_inventory.py
Executable file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/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()
|
9
playbooks/inventory/linode.yaml
Normal file
9
playbooks/inventory/linode.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
- name: Generate Linode inventory file
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
roles:
|
||||||
|
- role: inventory/linode
|
||||||
|
vars:
|
||||||
|
linode_token: "{{ lookup('env', 'LINODE_TOKEN') }}"
|
||||||
|
|
19
roles/inventory/linode/tasks/main.yaml
Normal file
19
roles/inventory/linode/tasks/main.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch Linode instances
|
||||||
|
linode.cloud.linode_instance_info:
|
||||||
|
api_token: "{{ linode_token }}"
|
||||||
|
register: linodes
|
||||||
|
|
||||||
|
- name: Build inventory lines
|
||||||
|
set_fact:
|
||||||
|
linode_inventory: |
|
||||||
|
{% for linode in linodes.data %}
|
||||||
|
{{ linode.label }} ansible_host={{ linode.ipv4[0] }} {% for tag in linode.tags %}group_{{ tag }}=true {% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- name: Write dynamic inventory to file
|
||||||
|
copy:
|
||||||
|
dest: /tmp/linode_inventory.ini
|
||||||
|
content: |
|
||||||
|
[all]
|
||||||
|
{{ linode_inventory }}
|
Reference in New Issue
Block a user