Files
ansible-inventories/claude_rhel_inventory.yml
2025-08-17 17:30:41 +02:00

249 lines
9.7 KiB
YAML

---
- name: Gather Red Hat Insights Inventory
hosts: localhost
gather_facts: false
vars:
# Red Hat Insights API configuration
insights_base_url: "https://console.redhat.com/api"
insights_username: "{{ vault_insights_username | default('') }}"
insights_password: "{{ vault_insights_password | default('') }}"
# Alternative: Use offline token instead of username/password
insights_offline_token: "{{ vault_insights_offline_token | default('') }}"
# Output configuration
output_dir: "./insights_inventory"
output_format: "json" # Options: json, yaml, csv
# API endpoints
inventory_endpoint: "/inventory/v1/hosts"
system_profile_endpoint: "/inventory/v1/hosts/{host_id}/system_profile"
# Filters (optional)
insights_filters:
# Display name contains filter
# display_name: "prod"
# Operating system filter
# operating_system: "RHEL"
# Tags filter (format: namespace/key=value)
# tags: "environment/prod"
# Staleness filter (fresh, stale, stale_warning, unknown)
# staleness: "fresh"
tasks:
- name: Create output directory
file:
path: "{{ output_dir }}"
state: directory
mode: '0755'
- name: Get access token using offline token
uri:
url: "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token"
method: POST
body_format: form-urlencoded
body:
grant_type: "refresh_token"
client_id: "rhsm-api"
refresh_token: "{{ insights_offline_token }}"
headers:
Content-Type: "application/x-www-form-urlencoded"
register: token_response
when: insights_offline_token | length > 0
no_log: true
- name: Set access token from offline token response
set_fact:
access_token: "{{ token_response.json.access_token }}"
when: insights_offline_token | length > 0
- name: Get access token using username/password
uri:
url: "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token"
method: POST
body_format: form-urlencoded
body:
grant_type: "password"
client_id: "rhsm-api"
username: "{{ insights_username }}"
password: "{{ insights_password }}"
headers:
Content-Type: "application/x-www-form-urlencoded"
register: token_response_pwd
when:
- insights_offline_token | length == 0
- insights_username | length > 0
- insights_password | length > 0
no_log: true
- name: Set access token from username/password response
set_fact:
access_token: "{{ token_response_pwd.json.access_token }}"
when:
- insights_offline_token | length == 0
- insights_username | length > 0
- insights_password | length > 0
- name: Fail if no authentication method provided
fail:
msg: "Please provide either insights_offline_token or both insights_username and insights_password"
when: access_token is not defined
- name: Build query parameters for API request
set_fact:
query_params: "{{ query_params | default({}) | combine({item.key: item.value}) }}"
loop: "{{ insights_filters | dict2items }}"
when: insights_filters is defined
- name: Get initial inventory page
uri:
url: "{{ insights_base_url }}{{ inventory_endpoint }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
Content-Type: "application/json"
body_format: json
body: "{{ query_params | default({}) }}"
register: initial_inventory_response
- name: Initialize inventory collection
set_fact:
all_hosts: "{{ initial_inventory_response.json.results }}"
total_hosts: "{{ initial_inventory_response.json.total }}"
current_page: 1
per_page: "{{ initial_inventory_response.json.per_page | default(50) }}"
- name: Display initial inventory stats
debug:
msg: "Found {{ total_hosts }} total hosts. Retrieved {{ all_hosts | length }} hosts on first page."
- name: Get remaining inventory pages
uri:
url: "{{ insights_base_url }}{{ inventory_endpoint }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
Content-Type: "application/json"
body_format: json
body: "{{ (query_params | default({})) | combine({'page': item, 'per_page': per_page}) }}"
register: inventory_page_response
loop: "{{ range(2, ((total_hosts | int / per_page | int) | round(0, 'ceil') | int) + 1) }}"
when: (total_hosts | int) > per_page
- name: Combine all inventory pages
set_fact:
all_hosts: "{{ all_hosts + item.json.results }}"
loop: "{{ inventory_page_response.results | default([]) }}"
when: inventory_page_response.results is defined
- name: Get detailed system profiles for each host
uri:
url: "{{ insights_base_url }}/inventory/v1/hosts/{{ item.id }}/system_profile"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
Content-Type: "application/json"
register: system_profiles
loop: "{{ all_hosts }}"
loop_control:
label: "{{ item.display_name | default(item.id) }}"
- name: Combine host data with system profiles
set_fact:
enriched_hosts: "{{ enriched_hosts | default([]) + [item.0 | combine({'system_profile': item.1.json.results})] }}"
loop: "{{ all_hosts | zip(system_profiles.results) | list }}"
loop_control:
label: "{{ item.0.display_name | default(item.0.id) }}"
- name: Create summary statistics
set_fact:
inventory_summary:
total_hosts: "{{ enriched_hosts | length }}"
collection_timestamp: "{{ ansible_date_time.iso8601 }}"
operating_systems: "{{ enriched_hosts | map(attribute='system_profile') | map(attribute='operating_system') | flatten | map(attribute='name') | unique | list }}"
architectures: "{{ enriched_hosts | map(attribute='system_profile') | map(attribute='arch') | flatten | unique | list }}"
insights_client_versions: "{{ enriched_hosts | map(attribute='insights_id') | select | list | length }}"
- name: Save inventory as JSON
copy:
content: "{{ {'summary': inventory_summary, 'hosts': enriched_hosts} | to_nice_json }}"
dest: "{{ output_dir }}/insights_inventory.json"
when: output_format == "json"
- name: Save inventory as YAML
copy:
content: "{{ {'summary': inventory_summary, 'hosts': enriched_hosts} | to_nice_yaml }}"
dest: "{{ output_dir }}/insights_inventory.yml"
when: output_format == "yaml"
- name: Create CSV headers
set_fact:
csv_headers: "id,display_name,fqdn,account,org_id,subscription_manager_id,insights_id,satellite_id,updated,created,stale_timestamp,operating_system,arch,kernel_version,cpu_count,memory,network_interfaces,tags"
when: output_format == "csv"
- name: Generate CSV content
set_fact:
csv_content: "{{ csv_content | default(csv_headers + '\n') +
item.id + ',' +
(item.display_name | default('') | string) + ',' +
(item.fqdn | default('') | string) + ',' +
(item.account | string) + ',' +
(item.org_id | string) + ',' +
(item.subscription_manager_id | default('') | string) + ',' +
(item.insights_id | default('') | string) + ',' +
(item.satellite_id | default('') | string) + ',' +
(item.updated | string) + ',' +
(item.created | string) + ',' +
(item.stale_timestamp | default('') | string) + ',' +
((item.system_profile.operating_system.name | default('')) | string) + ',' +
(item.system_profile.arch | default('') | string) + ',' +
(item.system_profile.kernel_version | default('') | string) + ',' +
(item.system_profile.cpu_count | default('') | string) + ',' +
(item.system_profile.system_memory_bytes | default('') | string) + ',' +
(item.system_profile.network_interfaces | length | default('') | string) + ',' +
(item.tags | map(attribute='key') | join(';') | default('')) + '\n' }}"
loop: "{{ enriched_hosts }}"
when: output_format == "csv"
- name: Save inventory as CSV
copy:
content: "{{ csv_content }}"
dest: "{{ output_dir }}/insights_inventory.csv"
when: output_format == "csv"
- name: Save individual host files
copy:
content: "{{ item | to_nice_json }}"
dest: "{{ output_dir }}/hosts/{{ item.display_name | default(item.id) }}.json"
loop: "{{ enriched_hosts }}"
loop_control:
label: "{{ item.display_name | default(item.id) }}"
- name: Create host directory
file:
path: "{{ output_dir }}/hosts"
state: directory
mode: '0755'
- name: Display collection summary
debug:
var: inventory_summary
- name: Display completion message
debug:
msg: |
Insights inventory collection completed successfully!
Summary:
- Total hosts collected: {{ inventory_summary.total_hosts }}
- Output directory: {{ output_dir }}
- Output format: {{ output_format }}
- Collection timestamp: {{ inventory_summary.collection_timestamp }}
Files created:
- Main inventory: {{ output_dir }}/insights_inventory.{{ output_format }}
- Individual host files: {{ output_dir }}/hosts/
Operating Systems found: {{ inventory_summary.operating_systems | join(', ') }}
Architectures found: {{ inventory_summary.architectures | join(', ') }}