249 lines
9.7 KiB
YAML
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(', ') }}
|
|
|