smart_proxy_ansible 3.5.8 → 3.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12f791dcb337052aba097f02210ac04a3fedd80afff15d79b370058d6f06b108
4
- data.tar.gz: a41495f8bad24dcd1d7c5c0798b992abf96f1dff501c1cdd7e22dfd68e5406ea
3
+ metadata.gz: 10b497d0820ed673dd5a1c22eee9340f412b8da5da5cfcf592d7c95f1f61b971
4
+ data.tar.gz: eef960a9a5e56832222fabba46c0fd6f413f22d5007bd8c70d9939bc1553b76e
5
5
  SHA512:
6
- metadata.gz: 5ce5d1746e0bb01220cdd67bf1af0b414cbbb6d8215079e8b35ed089e83e95c70b4b75646867892dab443ed67fb8b1433d9b18da9d5a0142b1a18e7adea33f0a
7
- data.tar.gz: c41477f577e7c73a026a3cb80fdc0a3910ed1f007f08c7121d3cec0b88a30ae2b76220d43def38db6bba53a3aa8130c7acb260f7dfb45840a116b7d0debc8ace
6
+ metadata.gz: 3133b0693041281d4c2d657fa762e414732e987a938e353a64444b3951265933634a7da8623b09680fae648a41b8650061058f5392e2d320d1737c510ba0148d
7
+ data.tar.gz: 7d59d08e818ad2ee5dbd280fbb10cc2b523c7d9f1accaa800e949f23fef13e9ff5efd03aa380488e8a7de247ed2b708a5372fda0926922a9cf037a665233d196
@@ -22,11 +22,14 @@ module Proxy::Ansible
22
22
  @verbosity_level = action_input[:verbosity_level]
23
23
  @rex_command = action_input[:remote_execution_command]
24
24
  @check_mode = action_input[:check_mode]
25
+ @job_check_mode = action_input[:job_check_mode]
26
+ @diff_mode = action_input[:diff_mode]
25
27
  @tags = action_input[:tags]
26
28
  @tags_flag = action_input[:tags_flag]
27
29
  @passphrase = action_input['secrets']['key_passphrase']
28
30
  @execution_timeout_interval = action_input[:execution_timeout_interval]
29
31
  @cleanup_working_dirs = action_input.fetch(:cleanup_working_dirs, true)
32
+ prune_known_hosts_on_first_execution
30
33
  end
31
34
 
32
35
  def start
@@ -213,7 +216,7 @@ module Proxy::Ansible
213
216
  end
214
217
 
215
218
  def cmdline
216
- cmd_args = [tags_cmd, check_cmd].reject(&:empty?)
219
+ cmd_args = [tags_cmd, check_cmd, diff_cmd].reject(&:empty?)
217
220
  return nil unless cmd_args.any?
218
221
  cmd_args.join(' ')
219
222
  end
@@ -224,7 +227,15 @@ module Proxy::Ansible
224
227
  end
225
228
 
226
229
  def check_cmd
227
- check_mode? ? '"--check"' : ''
230
+ if check_mode? || job_check_mode?
231
+ '"--check"'
232
+ else
233
+ ''
234
+ end
235
+ end
236
+
237
+ def diff_cmd
238
+ diff_mode? ? '"--diff"' : ''
228
239
  end
229
240
 
230
241
  def verbosity
@@ -239,6 +250,14 @@ module Proxy::Ansible
239
250
  @check_mode == true && @rex_command == false
240
251
  end
241
252
 
253
+ def job_check_mode?
254
+ @job_check_mode == true
255
+ end
256
+
257
+ def diff_mode?
258
+ @diff_mode == true
259
+ end
260
+
242
261
  def prepare_directory_structure
243
262
  inner = %w[inventory project env].map { |part| File.join(@root, part) }
244
263
  ([@root] + inner).each do |path|
@@ -252,21 +271,40 @@ module Proxy::Ansible
252
271
  logger.debug("[foreman_ansible] - handling event #{description}: #{JSON.pretty_generate(event)}") if logger.level <= ::Logger::DEBUG
253
272
  end
254
273
 
255
- # Each per-host task has inventory only for itself, we must
256
- # collect all the partial inventories into one large inventory
257
- # containing all the hosts.
274
+ # Rebuilds a unified Ansible inventory from multiple per-host inventories.
275
+ # @param input [Hash] The input hash mapping hostnames to inventory data.
276
+ # @return [Hash] The merged inventory.
258
277
  def rebuild_inventory(input)
259
- action_inputs = input.values.map { |hash| hash[:input][:action_input] }
260
- inventories = action_inputs.map { |hash| hash[:ansible_inventory] }
261
- host_vars = inventories.map { |i| i['_meta']['hostvars'] }.reduce({}) do |acc, hosts|
262
- hosts.reduce(acc) do |inner_acc, (hostname, vars)|
278
+ action_inputs = input.values.map { |entry| entry['input']['action_input'] }
279
+ inventories = action_inputs.map { |action_input| action_input['ansible_inventory'] }
280
+ first_execution_by_host = action_inputs.to_h { |action_input| [action_input['name'], action_input['first_execution']] }
281
+
282
+ host_vars = merge_hostvars_from_inventories(inventories)
283
+
284
+ # Use the first inventory's group vars as a base, fallback to empty hash if missing
285
+ group_vars = inventories.first.dig('all', 'vars') || {}
286
+
287
+ inventory = {
288
+ 'all' => {
289
+ 'hosts' => host_vars,
290
+ 'vars' => group_vars
291
+ }
292
+ }
293
+
294
+ update_first_execution_flags(inventory['all']['hosts'], first_execution_by_host)
295
+
296
+ inventory
297
+ end
298
+
299
+ # Helper: Merges hostvars from a list of inventories, ensuring ssh key is set.
300
+ def merge_hostvars_from_inventories(inventories)
301
+ inventories.each_with_object({}) do |inventory, acc|
302
+ inventory.dig('_meta', 'hostvars')&.each do |hostname, vars|
303
+ # Ensure the ssh key is set for each host
263
304
  vars[:ansible_ssh_private_key_file] ||= Proxy::RemoteExecution::Ssh::Plugin.settings[:ssh_identity_key_file]
264
- inner_acc.merge(hostname => vars)
305
+ acc[hostname] = vars
265
306
  end
266
307
  end
267
-
268
- { 'all' => { 'hosts' => host_vars,
269
- 'vars' => inventories.first['all']['vars'] } }
270
308
  end
271
309
 
272
310
  def working_dir
@@ -294,6 +332,57 @@ module Proxy::Ansible
294
332
 
295
333
  inventory
296
334
  end
335
+
336
+ # Removes known hosts entries for hosts marked as 'first_execution' in the inventory.
337
+ # This ensures SSH host key checking does not fail on first connection.
338
+ # @return [void]
339
+ def prune_known_hosts_on_first_execution
340
+ @inventory.dig('all', 'hosts')&.each_value do |host_data|
341
+ next unless host_data.dig("foreman", "first_execution")
342
+
343
+ interface = host_data.dig("foreman", "foreman_interfaces", 0)
344
+ next unless interface
345
+
346
+ extract_host_identifiers(interface, host_data).each do |host|
347
+ extract_ports(host_data).each do |port|
348
+ Proxy::RemoteExecution::Utils.prune_known_hosts!(host, port, logger)
349
+ end
350
+ end
351
+ end
352
+ end
353
+
354
+ private
355
+
356
+ # Updates the 'first_execution' flag in the foreman data for each host in the inventory.
357
+ # @param hosts [Hash] hostname => host data hash
358
+ # @param execution_flags [Hash] hostname => boolean (first_execution)
359
+ # @return [void]
360
+ def update_first_execution_flags(hosts, execution_flags)
361
+ hosts.each do |hostname, vars|
362
+ foreman = vars['foreman']
363
+ next unless foreman
364
+
365
+ if execution_flags.key?(hostname)
366
+ foreman['first_execution'] = execution_flags[hostname]
367
+ end
368
+ end
369
+ end
370
+
371
+ def extract_host_identifiers(interface, host_data)
372
+ [
373
+ interface["ip"],
374
+ interface["ip6"],
375
+ host_data["ansible_host"],
376
+ interface["name"]
377
+ ].compact.uniq
378
+ end
379
+
380
+ def extract_ports(host_data)
381
+ [
382
+ host_data["ansible_ssh_port"],
383
+ host_data["ansible_port"]
384
+ ].compact.uniq
385
+ end
297
386
  end
298
387
  end
299
388
  end
@@ -2,6 +2,6 @@ module Proxy
2
2
  # Version, this allows the proxy and other plugins know
3
3
  # what version of the Ansible plugin is running
4
4
  module Ansible
5
- VERSION = '3.5.8'
5
+ VERSION = '3.6.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_proxy_ansible
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.8
4
+ version: 3.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-01-13 00:00:00.000000000 Z
12
+ date: 2025-07-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -45,14 +45,14 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '0.4'
48
+ version: '0.5'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '0.4'
55
+ version: '0.5'
56
56
  description: " Smart-Proxy ansible plugin\n"
57
57
  email:
58
58
  - inecas@redhat.com