--- # Main tasks for linode_inventory role - name: Set API token (AWX credential injection takes precedence) ansible.builtin.set_fact: linode_api_token: "{{ linode_api_token | default(lookup('env', 'LINODE_API_TOKEN')) | default('') }}" - name: Validate required variables ansible.builtin.assert: that: - linode_api_token is defined - linode_api_token | length > 0 fail_msg: | Linode API token not found. For AWX: Attach a Linode API Token credential to your job template For local: Set LINODE_API_TOKEN environment variable or pass linode_api_token variable quiet: true - name: Ensure output directory exists ansible.builtin.file: path: "{{ linode_inventory_output_dir }}" state: directory mode: '0755' delegate_to: localhost - name: Copy Linode inventory script ansible.builtin.copy: src: linode_inventory.py dest: "{{ linode_inventory_output_dir }}/linode_inventory.py" mode: '0755' delegate_to: localhost - name: Execute Linode inventory script ansible.builtin.command: cmd: python3 {{ linode_inventory_output_dir }}/linode_inventory.py --list environment: LINODE_API_TOKEN: "{{ linode_api_token }}" register: linode_inventory_result delegate_to: localhost changed_when: true - name: Show script execution details ansible.builtin.debug: msg: | Script execution results: Return code: {{ linode_inventory_result.rc }} Stdout length: {{ linode_inventory_result.stdout | length }} Stderr length: {{ linode_inventory_result.stderr | length }} - name: Show stderr if present ansible.builtin.debug: msg: "Script stderr: {{ linode_inventory_result.stderr }}" when: linode_inventory_result.stderr | length > 0 - name: Show stdout if present ansible.builtin.debug: msg: "Script stdout: {{ linode_inventory_result.stdout }}" when: linode_inventory_result.stdout | length > 0 - name: Test API token directly ansible.builtin.uri: url: "https://api.linode.com/v4/linode/instances" method: GET headers: Authorization: "Bearer {{ linode_api_token }}" Content-Type: "application/json" return_content: yes status_code: [200, 401, 403] register: direct_api_test delegate_to: localhost - name: Display direct API test results ansible.builtin.debug: msg: | Direct API test results: Status: {{ direct_api_test.status }} Response: {{ direct_api_test.json | default('No JSON response') }} - name: Parse inventory JSON (only if stdout exists) ansible.builtin.set_fact: linode_inventory_data: "{{ linode_inventory_result.stdout | from_json }}" when: - linode_inventory_result.stdout | length > 0 - linode_inventory_result.rc == 0 - name: Set empty inventory if script failed ansible.builtin.set_fact: linode_inventory_data: _meta: hostvars: {} all: children: ['ungrouped'] ungrouped: hosts: [] when: linode_inventory_data is not defined - name: Save inventory to file ansible.builtin.copy: content: "{{ linode_inventory_data | to_nice_json }}" dest: "{{ temp_inventory_path }}" mode: '0644' delegate_to: localhost - name: Display inventory summary ansible.builtin.debug: msg: | Linode Dynamic Inventory Summary: Total hosts discovered: {{ linode_inventory_data._meta.hostvars | length }} Groups created: {{ linode_inventory_data.keys() | reject('equalto', '_meta') | list | length }} Inventory saved to: {{ temp_inventory_path }} API Token status: {{ 'Set (' + (linode_api_token[:8] + '...' if linode_api_token | length > 8 else linode_api_token) + ')' if linode_api_token is defined else 'NOT SET' }} - name: Show raw script output for debugging ansible.builtin.debug: var: linode_inventory_result.stdout when: linode_inventory_result.stdout | length > 0 - name: Show discovered hosts ansible.builtin.debug: msg: "Host: {{ item.key }} ({{ item.value.ansible_host }}) - Region: {{ item.value.linode_region }} - Status: {{ item.value.linode_status }}" loop: "{{ linode_inventory_data._meta.hostvars | dict2items }}" loop_control: label: "{{ item.key }}" when: linode_inventory_data._meta.hostvars | length > 0 - name: Create JSON inventory file for AWX ansible.builtin.template: src: linode_hosts.json.j2 dest: "{{ linode_inventory_output_dir }}/linode_hosts.json" mode: '0644' delegate_to: localhost when: linode_inventory_data is defined - name: Clean up temporary script ansible.builtin.file: path: "{{ linode_inventory_output_dir }}/linode_inventory.py" state: absent delegate_to: localhost when: cleanup_temp_files | default(true)