Skip to content

Commit 604d10b

Browse files
chris1984claude
andcommitted
Add Ansible REX job template for virt-who deployment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c99db25 commit 604d10b

3 files changed

Lines changed: 399 additions & 0 deletions

File tree

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
<%#
2+
name: Deploy virt-who Config
3+
snippet: false
4+
template_inputs:
5+
- name: virt_who_hypervisor_type
6+
required: true
7+
input_type: user
8+
advanced: false
9+
value_type: plain
10+
hidden_value: false
11+
description: "Hypervisor type: esx, hyperv, libvirt, kubevirt, or ahv"
12+
- name: virt_who_hypervisor_server
13+
required: false
14+
input_type: user
15+
advanced: false
16+
value_type: plain
17+
hidden_value: false
18+
description: "Hypervisor server URL/hostname (required for all types except kubevirt)"
19+
- name: virt_who_hypervisor_username
20+
required: false
21+
input_type: user
22+
advanced: false
23+
value_type: plain
24+
hidden_value: false
25+
description: "Hypervisor username (required for all types except kubevirt)"
26+
- name: virt_who_hypervisor_password
27+
required: false
28+
input_type: user
29+
advanced: false
30+
value_type: plain
31+
hidden_value: true
32+
description: "Hypervisor password (required for esx, hyperv, ahv)"
33+
- name: virt_who_organization_label
34+
required: true
35+
input_type: user
36+
advanced: false
37+
value_type: plain
38+
hidden_value: false
39+
description: "Organization label (Candlepin owner)"
40+
- name: virt_who_service_user
41+
required: true
42+
input_type: user
43+
advanced: false
44+
value_type: plain
45+
hidden_value: false
46+
description: "RHSM service user username"
47+
- name: virt_who_service_user_password
48+
required: true
49+
input_type: user
50+
advanced: false
51+
value_type: plain
52+
hidden_value: true
53+
description: "RHSM service user password"
54+
- name: virt_who_identifier
55+
required: false
56+
input_type: user
57+
advanced: false
58+
value_type: plain
59+
hidden_value: false
60+
default: "virt-who-config"
61+
description: "Config identifier"
62+
- name: virt_who_hypervisor_id
63+
required: false
64+
input_type: user
65+
advanced: false
66+
value_type: plain
67+
hidden_value: false
68+
default: "hostname"
69+
description: "Hypervisor ID method: hostname, uuid, or hwuuid"
70+
- name: virt_who_interval
71+
required: false
72+
input_type: user
73+
advanced: true
74+
value_type: plain
75+
hidden_value: false
76+
default: "7200"
77+
description: "Reporting interval in seconds"
78+
- name: virt_who_debug
79+
required: false
80+
input_type: user
81+
advanced: false
82+
value_type: plain
83+
hidden_value: false
84+
default: "false"
85+
description: "Enable debug logging: true or false"
86+
- name: virt_who_filtering_mode
87+
required: false
88+
input_type: user
89+
advanced: false
90+
value_type: plain
91+
hidden_value: false
92+
default: "none"
93+
description: "Host filtering mode: none, whitelist, or blacklist"
94+
- name: virt_who_whitelist
95+
required: false
96+
input_type: user
97+
advanced: true
98+
value_type: plain
99+
hidden_value: false
100+
description: "Comma-separated list of hosts to include (whitelist mode)"
101+
- name: virt_who_blacklist
102+
required: false
103+
input_type: user
104+
advanced: true
105+
value_type: plain
106+
hidden_value: false
107+
description: "Comma-separated list of hosts to exclude (blacklist mode)"
108+
- name: virt_who_filter_host_parents
109+
required: false
110+
input_type: user
111+
advanced: true
112+
value_type: plain
113+
hidden_value: false
114+
description: "Comma-separated parent compute resources to include (ESX whitelist)"
115+
- name: virt_who_exclude_host_parents
116+
required: false
117+
input_type: user
118+
advanced: true
119+
value_type: plain
120+
hidden_value: false
121+
description: "Comma-separated parent compute resources to exclude (ESX blacklist)"
122+
- name: virt_who_http_proxy
123+
required: false
124+
input_type: user
125+
advanced: false
126+
value_type: plain
127+
hidden_value: false
128+
description: "Full proxy URL (e.g., http://proxy.example.com:8080)"
129+
- name: virt_who_no_proxy
130+
required: false
131+
input_type: user
132+
advanced: false
133+
value_type: plain
134+
hidden_value: false
135+
description: "Comma-separated list of hosts/domains to bypass proxy"
136+
- name: virt_who_kubeconfig_path
137+
required: false
138+
input_type: user
139+
advanced: true
140+
value_type: plain
141+
hidden_value: false
142+
description: "Path to kubeconfig file (kubevirt only)"
143+
- name: virt_who_prism_flavor
144+
required: false
145+
input_type: user
146+
advanced: true
147+
value_type: plain
148+
hidden_value: false
149+
default: "central"
150+
description: "AHV Prism type: central or element"
151+
- name: virt_who_ahv_internal_debug
152+
required: false
153+
input_type: user
154+
advanced: true
155+
value_type: plain
156+
hidden_value: false
157+
description: "AHV internal debug value"
158+
model: JobTemplate
159+
job_category: Virt-who
160+
description_format: "Deploy virt-who configuration %{virt_who_identifier}"
161+
provider_type: Ansible
162+
kind: job_template
163+
feature: deploy_virt_who_config
164+
%>
165+
<%
166+
identifier = input('virt_who_identifier')
167+
identifier = 'virt-who-config' if identifier.to_s.empty?
168+
hypervisor_id = input('virt_who_hypervisor_id')
169+
hypervisor_id = 'hostname' if hypervisor_id.to_s.empty?
170+
interval = input('virt_who_interval')
171+
interval = '7200' if interval.to_s.empty?
172+
debug_val = input('virt_who_debug').to_s == 'true' ? '1' : '0'
173+
hypervisor_type = input('virt_who_hypervisor_type')
174+
filtering_mode = input('virt_who_filtering_mode')
175+
filtering_mode = 'none' if filtering_mode.to_s.empty?
176+
prism_flavor = input('virt_who_prism_flavor')
177+
prism_flavor = 'central' if prism_flavor.to_s.empty?
178+
179+
# Build per-config file content
180+
config_lines = []
181+
config_lines << "### This configuration file is managed via the virt-who configure plugin"
182+
config_lines << "### manual edits will be deleted."
183+
config_lines << "[#{identifier}]"
184+
config_lines << "type=#{hypervisor_type}"
185+
config_lines << "hypervisor_id=#{hypervisor_id}"
186+
config_lines << "owner=#{input('virt_who_organization_label')}"
187+
188+
if hypervisor_type != 'kubevirt'
189+
config_lines << "server=#{input('virt_who_hypervisor_server')}"
190+
config_lines << "username=#{input('virt_who_hypervisor_username')}"
191+
end
192+
if !['kubevirt', 'libvirt'].include?(hypervisor_type)
193+
config_lines << "encrypted_password={{ __virt_who_cr_encrypted_password.stdout }}"
194+
end
195+
196+
if filtering_mode == 'whitelist'
197+
wl = input('virt_who_whitelist')
198+
fhp = input('virt_who_filter_host_parents')
199+
config_lines << "filter_hosts=#{wl}" unless wl.to_s.empty?
200+
config_lines << "filter_host_parents=#{fhp}" unless fhp.to_s.empty?
201+
elsif filtering_mode == 'blacklist'
202+
bl = input('virt_who_blacklist')
203+
ehp = input('virt_who_exclude_host_parents')
204+
config_lines << "exclude_hosts=#{bl}" unless bl.to_s.empty?
205+
config_lines << "exclude_host_parents=#{ehp}" unless ehp.to_s.empty?
206+
end
207+
208+
config_lines << "rhsm_hostname=#{foreman_server_url.sub('https://', '').sub('http://', '')}"
209+
config_lines << "rhsm_username=#{input('virt_who_service_user')}"
210+
config_lines << "rhsm_encrypted_password={{ __virt_who_service_user_encrypted_password.stdout }}"
211+
config_lines << "rhsm_prefix=/rhsm"
212+
213+
if hypervisor_type == 'kubevirt'
214+
config_lines << "kubeconfig=#{input('virt_who_kubeconfig_path')}"
215+
end
216+
217+
if hypervisor_type == 'ahv'
218+
config_lines << "prism_central=#{prism_flavor == 'central'}"
219+
ahv_debug = input('virt_who_ahv_internal_debug')
220+
config_lines << "ahv_internal_debug=#{ahv_debug}" unless ahv_debug.to_s.empty?
221+
end
222+
223+
config_content = config_lines.join("\n") + "\n"
224+
225+
# Build global sysconfig content
226+
sysconfig_lines = []
227+
sysconfig_lines << "### This configuration file is managed via the virt-who configure plugin"
228+
sysconfig_lines << "### manual edits will be deleted."
229+
sysconfig_lines << "[global]"
230+
sysconfig_lines << "debug=#{debug_val}"
231+
sysconfig_lines << "interval=#{interval}"
232+
sysconfig_lines << "oneshot=False"
233+
sysconfig_lines << ""
234+
sysconfig_lines << "[system_environment]"
235+
236+
http_proxy = input('virt_who_http_proxy')
237+
unless http_proxy.to_s.empty?
238+
if http_proxy.start_with?('https')
239+
sysconfig_lines << "https_proxy=#{http_proxy}"
240+
else
241+
sysconfig_lines << "http_proxy=#{http_proxy}"
242+
end
243+
end
244+
245+
no_proxy = input('virt_who_no_proxy')
246+
sysconfig_lines << "no_proxy=#{no_proxy}" unless no_proxy.to_s.empty?
247+
248+
sysconfig_content = sysconfig_lines.join("\n") + "\n"
249+
-%>
250+
---
251+
- hosts: all
252+
become: true
253+
tasks:
254+
- name: Check if virt-who is already installed
255+
ansible.builtin.command: rpm -q virt-who
256+
register: __virt_who_installed
257+
changed_when: false
258+
failed_when: false
259+
260+
- name: Install virt-who
261+
when: __virt_who_installed.rc != 0
262+
block:
263+
- name: Check for satellite-maintain
264+
ansible.builtin.command: rpm -q satellite-maintain
265+
register: __virt_who_satellite_maintain
266+
changed_when: false
267+
failed_when: false
268+
269+
- name: Check for foreman-maintain
270+
ansible.builtin.command: rpm -q rubygem-foreman_maintain
271+
register: __virt_who_foreman_maintain
272+
changed_when: false
273+
failed_when: false
274+
when: __virt_who_satellite_maintain.rc != 0
275+
276+
- name: Install virt-who using satellite-maintain
277+
when: __virt_who_satellite_maintain.rc == 0
278+
block:
279+
- name: Unlock packages via satellite-maintain
280+
ansible.builtin.command: satellite-maintain packages unlock
281+
- name: Install virt-who via satellite-maintain
282+
ansible.builtin.command: satellite-maintain advanced procedure run packages-install --packages virt-who --assumeyes
283+
- name: Lock packages via satellite-maintain
284+
ansible.builtin.command: satellite-maintain packages lock
285+
286+
- name: Install virt-who using foreman-maintain
287+
when:
288+
- __virt_who_satellite_maintain.rc != 0
289+
- __virt_who_foreman_maintain.rc == 0
290+
block:
291+
- name: Unlock packages via foreman-maintain
292+
ansible.builtin.command: foreman-maintain packages unlock
293+
- name: Install virt-who via foreman-maintain
294+
ansible.builtin.command: foreman-maintain advanced procedure run packages-install --packages virt-who --assumeyes
295+
- name: Lock packages via foreman-maintain
296+
ansible.builtin.command: foreman-maintain packages lock
297+
298+
- name: Install virt-who via package manager
299+
ansible.builtin.package:
300+
name: virt-who
301+
state: present
302+
when:
303+
- __virt_who_satellite_maintain.rc != 0
304+
- __virt_who_foreman_maintain.rc | default(1) != 0
305+
306+
- name: Get installed virt-who version
307+
ansible.builtin.command: rpm -q --queryformat '%{VERSION}' virt-who
308+
register: __virt_who_installed_version
309+
changed_when: false
310+
311+
- name: Verify minimum virt-who version
312+
ansible.builtin.assert:
313+
that:
314+
- __virt_who_installed_version.stdout is version('0.24.2', '>=')
315+
fail_msg: >-
316+
virt-who {{ __virt_who_installed_version.stdout }} does not meet minimum requirements,
317+
minimum version is 0.24.2
318+
<% if !['kubevirt', 'libvirt'].include?(hypervisor_type) -%>
319+
320+
- name: Encrypt hypervisor password
321+
ansible.builtin.command: virt-who-password --password '<%= input('virt_who_hypervisor_password') %>'
322+
register: __virt_who_cr_encrypted_password
323+
changed_when: false
324+
no_log: true
325+
<% end -%>
326+
327+
- name: Encrypt service user password
328+
ansible.builtin.command: virt-who-password --password '<%= input('virt_who_service_user_password') %>'
329+
register: __virt_who_service_user_encrypted_password
330+
changed_when: false
331+
no_log: true
332+
333+
- name: Ensure virt-who config directory exists
334+
ansible.builtin.file:
335+
path: /etc/virt-who.d
336+
state: directory
337+
owner: root
338+
group: root
339+
mode: '0755'
340+
341+
- name: Deploy virt-who per-config configuration
342+
ansible.builtin.copy:
343+
content: |
344+
<%= config_content.split("\n").map { |l| " #{l}\n" }.join -%>
345+
dest: /etc/virt-who.d/<%= identifier %>.conf
346+
owner: root
347+
group: root
348+
mode: '0640'
349+
notify:
350+
- Restart virt-who
351+
352+
- name: Deploy virt-who global configuration
353+
ansible.builtin.copy:
354+
content: |
355+
<%= sysconfig_content.split("\n").map { |l| " #{l}\n" }.join -%>
356+
dest: /etc/virt-who.conf
357+
owner: root
358+
group: root
359+
mode: '0644'
360+
notify:
361+
- Restart virt-who
362+
363+
- name: Enable virt-who service
364+
ansible.builtin.service:
365+
name: virt-who
366+
enabled: true
367+
368+
handlers:
369+
- name: Restart virt-who
370+
ansible.builtin.service:
371+
name: virt-who
372+
state: restarted

db/seeds.d/50_job_templates.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
begin
2+
organizations = Organization.unscoped.all
3+
locations = Location.unscoped.all
4+
User.as_anonymous_admin do
5+
JobTemplate.without_auditing do
6+
Dir[File.join("#{ForemanVirtWhoConfigure::Engine.root}/app/views/job_templates/**/*.erb")].each do |template|
7+
template = JobTemplate.import_raw!(File.read(template),
8+
:default => true,
9+
:lock => true,
10+
:update => true)
11+
template.organizations = organizations if template.present?
12+
template.locations = locations if template.present?
13+
end
14+
end
15+
end
16+
rescue => e
17+
Rails.logger.warn("Skipping virt-who job template seeding: #{e.message}")
18+
end

0 commit comments

Comments
 (0)