Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add playbooks to specify multiple playbooks to run #54

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ Metrics/CyclomaticComplexity:
# Offense count: 3
Metrics/PerceivedComplexity:
Max: 30

Metrics/ClassLength:
Max: 260
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ gem install kitchen-ansiblepush-<version>.gem
provisioner :
## required options
name : ansible_push
## Either `playbook` or `playbooks` is required
playbook : "../../plays/web.yml" # Path to Play yaml
playbooks :
- "../../plays/database.yml" # Path to database play yaml
- "../../plays/web.yml" # Path to web play yaml
##
## Optional argument
ansible_config : "/path/to/ansible/ansible.cfg" # path to ansible config file
Expand Down
10 changes: 9 additions & 1 deletion lib/kitchen-ansible/idempotancy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

def idempotency_test
info('*************** idempotency test ***************')
conf[:playbooks].each do |playbook|
_idempotency_test_single(playbook)
end
end

def _idempotency_test_single(playbook)
file_path = "/tmp/kitchen_ansible_callback/#{SecureRandom.uuid}.changes"
exec_ansible_command(
command_env.merge(
'ANSIBLE_CALLBACK_PLUGINS' => "#{File.dirname(__FILE__)}/../../callback/",
'ANSIBLE_CALLBACK_WHITELIST' => 'changes',
'PLUGIN_CHANGES_FILE' => file_path
), command, 'ansible-playbook'
),
command(playbook),
'ansible-playbook'
)
debug("idempotency file #{file_path}")
# Check ansible callback if changes has occured in the second run
Expand Down
34 changes: 26 additions & 8 deletions lib/kitchen/provisioner/ansible_push.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class AnsiblePush < Base
default_config :host_key_checking, false
default_config :mygroup, nil
default_config :playbook, nil
default_config :playbooks, []
default_config :generate_inv, true
default_config :generate_inv_path, '`which kitchen-ansible-inventory`'
default_config :raw_arguments, nil
Expand Down Expand Up @@ -66,9 +67,24 @@ class AnsiblePush < Base
def conf
return @validated_config if defined? @validated_config

raise UserError, 'No playbook defined. Please specify one in .kitchen.yml' unless config[:playbook]
unless config[:playbooks].is_a?(Array)
raise UserError,
"ansible playbooks is not an `Array` type. Given type: #{config[:playbooks].class}"
end

playbooks_to_run = config[:playbooks].clone

if config[:playbooks] && config[:playbook]
playbooks_to_run << config[:playbook]
end

raise UserError, "playbook '#{config[:playbook]}' could not be found. Please check path" unless File.exist?(config[:playbook])
if !playbooks_to_run || playbooks_to_run.empty?
raise UserError, 'No `playbook` or `playbooks` defined. Please specify one in .kitchen.yml'
end

playbooks_to_run.each do |playbook|
raise UserError, "playbook '#{config[:playbook]}' could not be found. Please check path" unless File.exist?(playbook)
end

if config[:vault_password_file] && !File.exist?(config[:vault_password_file])
raise UserError, "Vault password '#{config[:vault_password_file]}' could not be found. Please check path"
Expand Down Expand Up @@ -167,10 +183,9 @@ def options
@options = options
end

def command
return @command if defined? @command
def command(playbook)
@command = [conf[:ansible_playbook_bin]]
@command = (@command << options << conf[:playbook]).flatten.join(' ')
@command = (@command << options << playbook).flatten.join(' ')
debug("Ansible push command= #{@command}")
@command
end
Expand Down Expand Up @@ -209,7 +224,7 @@ def true_command
def install_command
info('*************** AnsiblePush install_command ***************')
# Test if ansible-playbook is installed and give a meaningful error message
version_check = command + ' --version'
version_check = command(conf[:playbooks].first) + ' --version'
_, stdout, stderr, wait_thr = Open3.popen3(command_env, version_check)
exit_status = wait_thr.value
raise UserError, "#{version_check} returned a non zero '#{exit_status}' stdout : '#{stdout.read}', stderr: '#{stderr.read}'" unless exit_status.success?
Expand All @@ -232,8 +247,11 @@ def chef_installation(chef_url, omnibus_download_dir)

def run_command
info('*************** AnsiblePush run ***************')
exec_ansible_command(command_env, command, 'ansible-playbook')
idempotency_test if conf[:idempotency_test]
conf[:playbooks].each do |playbook|
exec_ansible_command(command_env, command(playbook), 'ansible-playbook')
idempotency_test if conf[:idempotency_test]
end

info('*************** AnsiblePush end run *******************')
debug("[#{name}] Converge completed (#{conf[:sleep]}s).")
true_command # Place holder so a string is returned. This will execute true on remote host
Expand Down
13 changes: 10 additions & 3 deletions spec/kitchen/provisioner/ansible_push_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@
end

let(:instance) do
instance_double('Kitchen::Instance', name: 'coolbeans', logger: logger, suite: suite, platform: platform)
double = instance_double(
'Kitchen::Instance',
name: 'coolbeans',
logger: logger,
suite: suite,
platform: platform
)
double
end

# let(:machine_name) do
Expand All @@ -39,11 +46,11 @@
expect(provisioner.diagnose_plugin[:api_version]).to eq(2)
end

it 'Should fail with no playbook file' do
it "fails with no 'playbook' and 'playbooks' specified" do
expect { provisioner.prepare_command }.to raise_error(Kitchen::UserError)
end

describe 'Baisc config' do
describe 'Basic config' do
let(:config) do
{
test_base_path: '/b',
Expand Down