From 39b67efa1a6927c132f881d008c8776942b7d3b3 Mon Sep 17 00:00:00 2001 From: Jason Frey Date: Tue, 16 Jul 2024 18:34:09 -0400 Subject: [PATCH 1/2] Add an ansible-runner test for vaulted playbooks Co-Authored-By: jaisejose1123 --- .../data/hello_world_vault_encrypted.yml | 40 +++++++++++++++++++ spec/lib/ansible/runner_execution_spec.rb | 9 +++++ 2 files changed, 49 insertions(+) create mode 100644 spec/lib/ansible/runner/data/hello_world_vault_encrypted.yml diff --git a/spec/lib/ansible/runner/data/hello_world_vault_encrypted.yml b/spec/lib/ansible/runner/data/hello_world_vault_encrypted.yml new file mode 100644 index 00000000000..0c638eb6a36 --- /dev/null +++ b/spec/lib/ansible/runner/data/hello_world_vault_encrypted.yml @@ -0,0 +1,40 @@ +# Note: The password for `encrypted_msg` is just 'vault' +# +# This playbook is just used for testing vault integration, so when provided +# with the correct password the message displayed should be: +# +# "Hello World! (NOTE: This message has been encrypted with ansible-vault)" +# +# This var was generated by running the following: +# +# $ ansible-vault encrypt_string --ask-vault-pass --stdin-name "encrypted_msg" +# New Vault password: +# Confirm New Vault password: +# Reading plaintext input from stdin. (ctrl-d to end input) +# Hello World! +# encrypted_msg: !vault | +# $ANSIBLE_VAULT;1.1;AES256 +# 66383635373066393337333631383930366166656134653935663164636636623239333861643936 +# 3664613065666439303135323331616666383030383839310a303461623264646233623037313363 +# 63626562616166353466366232363562353461366162396262363461666439386165663565643832 +# 3239396633396466630a616463393237303338633562656664653433633437383161353933303737 +# 3764 +# Encryption successful +# +# (NOTE: When running the above, Ctrl-D was required twice for `ansible-vault` +# to respond. Most likely due to the '!' character in the base string.) +# +- name: Hello World Sample (Vault Encrypted) + hosts: localhost + vars: + encrypted_msg: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 66383635373066393337333631383930366166656134653935663164636636623239333861643936 + 3664613065666439303135323331616666383030383839310a303461623264646233623037313363 + 63626562616166353466366232363562353461366162396262363461666439386165663565643832 + 3239396633396466630a616463393237303338633562656664653433633437383161353933303737 + 3764 + tasks: + - name: Hello Message + debug: + msg: "{{encrypted_msg}} (NOTE: This message has been encrypted with ansible-vault)" diff --git a/spec/lib/ansible/runner_execution_spec.rb b/spec/lib/ansible/runner_execution_spec.rb index a1e4a8de0d5..620d97aedaf 100644 --- a/spec/lib/ansible/runner_execution_spec.rb +++ b/spec/lib/ansible/runner_execution_spec.rb @@ -13,5 +13,14 @@ expect(response.return_code).to eq(0), "ansible-runner failed with:\n#{response.stderr}" expect(response.human_stdout).to include('"msg": "Hello, world!"') end + + it "runs a hello-world-vault-encrypted playbook" do + credential = FactoryBot.create(:embedded_ansible_vault_credential, :password => "vault") + playbook = File.join(__dir__, "runner/data/hello_world_vault_encrypted.yml") + response = Ansible::Runner.run(env_vars, extra_vars, playbook, :credentials => [credential.id]) + + expect(response.return_code).to eq(0), "ansible-runner failed with:\n#{response.stderr}" + expect(response.human_stdout).to include('"msg": "Hello World! (NOTE: This message has been encrypted with ansible-vault)"') + end end end From b6d0c4ed10f836cff12f94915368af8d976fedca Mon Sep 17 00:00:00 2001 From: Jason Frey Date: Tue, 16 Jul 2024 19:24:04 -0400 Subject: [PATCH 2/2] Add ansible-runner specs for run_async method --- lib/ansible/runner/response_async.rb | 19 ++++++++++++++++++ spec/lib/ansible/runner_execution_spec.rb | 24 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/ansible/runner/response_async.rb b/lib/ansible/runner/response_async.rb index 77ee5101f23..ab9c6630900 100644 --- a/lib/ansible/runner/response_async.rb +++ b/lib/ansible/runner/response_async.rb @@ -54,6 +54,25 @@ def dump } end + # Waits for the async process to complete or hit the given timeout + # + # @param timeout [Integer, ActiveSupport::Duration] Number of seconds to wait for the process to complete + # @return [Ansible::Runner::Response] Response object with all details about the Ansible run + def wait(timeout) + result = nil + # Poll once per second until complete + 1.upto(timeout) do |t| + result = response + result ? break : sleep(1) + end + # If the process is still running, then stop it + if result.nil? + stop + result = response + end + result + end + # Creates the Ansible::Runner::ResponseAsync object from hash data # # @param hash [Hash] Dumped Ansible::Runner::ResponseAsync object diff --git a/spec/lib/ansible/runner_execution_spec.rb b/spec/lib/ansible/runner_execution_spec.rb index 620d97aedaf..a68e252834c 100644 --- a/spec/lib/ansible/runner_execution_spec.rb +++ b/spec/lib/ansible/runner_execution_spec.rb @@ -17,7 +17,29 @@ it "runs a hello-world-vault-encrypted playbook" do credential = FactoryBot.create(:embedded_ansible_vault_credential, :password => "vault") playbook = File.join(__dir__, "runner/data/hello_world_vault_encrypted.yml") - response = Ansible::Runner.run(env_vars, extra_vars, playbook, :credentials => [credential.id]) + + response = Ansible::Runner.run(env_vars, extra_vars, playbook, :credentials => [credential.id]) + + expect(response.return_code).to eq(0), "ansible-runner failed with:\n#{response.stderr}" + expect(response.human_stdout).to include('"msg": "Hello World! (NOTE: This message has been encrypted with ansible-vault)"') + end + end + + describe ".run_async" do + it "runs a hello-world playbook" do + response = Ansible::Runner.run_async(env_vars, extra_vars, File.join(__dir__, "runner/data/hello_world.yml")) + response = response.wait(5.seconds) + + expect(response.return_code).to eq(0), "ansible-runner failed with:\n#{response.stderr}" + expect(response.human_stdout).to include('"msg": "Hello, world!"') + end + + it "runs a hello-world-vault-encrypted playbook" do + credential = FactoryBot.create(:embedded_ansible_vault_credential, :password => "vault") + playbook = File.join(__dir__, "runner/data/hello_world_vault_encrypted.yml") + + response = Ansible::Runner.run_async(env_vars, extra_vars, playbook, :credentials => [credential.id]) + response = response.wait(5.seconds) expect(response.return_code).to eq(0), "ansible-runner failed with:\n#{response.stderr}" expect(response.human_stdout).to include('"msg": "Hello World! (NOTE: This message has been encrypted with ansible-vault)"')