kitchen-ansiblepush 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +61 -0
- data/bin/kitchen-ansible-inventory +40 -0
- data/callback/changes_callback.py +97 -0
- data/kitchen-ansiblepush.gemspec +35 -0
- data/lib/kitchen-ansible/util-inventory.rb +30 -0
- data/lib/kitchen-ansible/version.rb +5 -0
- data/lib/kitchen/provisioner/ansible_push.rb +242 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 82964df38e42759e837ed505d7f760afaff977cb
|
4
|
+
data.tar.gz: 75caa47b0cbc04aaf182fc12e1e6fecd5364b658
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1cf540b68aa64e6d803f41f7f8345f483e907552bf8477d349998958864b5445da5fc3760a1002c8f23aec5b55bb1f036ee6f86dff142a10f9df70776f7ceff6
|
7
|
+
data.tar.gz: f0f45bd5780a607f2c1fbe6bc1cdbe3b3abe43d719164ef56ead52f6c31ce175c6ace4fd04445e4c7eb9cfb51bb3e90d7a2b3017b352d05b81f83c3a107f3cc2
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# kitchen-ansiblepush
|
2
|
+
|
3
|
+
A test-kitchen plugin that adds the support for ansible in push mode
|
4
|
+
|
5
|
+
## TODO
|
6
|
+
* Tests
|
7
|
+
|
8
|
+
## Intro
|
9
|
+
This kitchen plugin adds ansible as a provisioner in push mode. Ansible will run from your host rather than run from guest machines.
|
10
|
+
|
11
|
+
## How to install
|
12
|
+
|
13
|
+
### Ruby gem
|
14
|
+
```
|
15
|
+
gem install kitchen-ansiblepush
|
16
|
+
```
|
17
|
+
|
18
|
+
### To install from code
|
19
|
+
```
|
20
|
+
git clone git@github.com:ahelal/kitchen-ansiblepush.git
|
21
|
+
cd kitchen-ansiblepush
|
22
|
+
gem build kitchen-ansiblepush.gemspec
|
23
|
+
sudo gem install kitchen-ansiblepush-<version>.gem
|
24
|
+
```
|
25
|
+
|
26
|
+
## kitchen.yml Options
|
27
|
+
```yaml
|
28
|
+
provisioner :
|
29
|
+
## required options
|
30
|
+
name : ansible_push
|
31
|
+
playbook : "../../plays/web.yml" # Path to Play yaml
|
32
|
+
##
|
33
|
+
## Optional argument
|
34
|
+
ansible_config : "/path/to/ansible/ansible.cfg" # path to ansible config file
|
35
|
+
verbose : "vvvv" # verbose level v, vv, vvv, vvvv
|
36
|
+
diff : true # print file diff
|
37
|
+
mygroup : "web" # ansible group
|
38
|
+
raw_arguments : "--timeout=200"
|
39
|
+
extra_vars : "@vars.yml"
|
40
|
+
tags : [ "that", "this" ]
|
41
|
+
skip_tags : [ "notme", "orme" ]
|
42
|
+
start_at_task : [ "five" ]
|
43
|
+
# Hash of other groups
|
44
|
+
groups :
|
45
|
+
db :
|
46
|
+
- db01
|
47
|
+
sudo : true
|
48
|
+
sudo_user : root
|
49
|
+
remote_user : ubuntu
|
50
|
+
private_key : "/path..../id_rsa"
|
51
|
+
ask_vault_pass : true
|
52
|
+
vault_password_file : "/..../file"
|
53
|
+
host_key_checking : false
|
54
|
+
generate_inv : true
|
55
|
+
|
56
|
+
```
|
57
|
+
## idempotency test
|
58
|
+
If you want to check your code is idempotent you can use the idempotency_test. Essentially, this will run Ansible twice and check nothing changed in the next run. If something changed it will list the tasks. Note: If your using Ansible callback in your config this might conflict.
|
59
|
+
```yaml
|
60
|
+
idempotency_test: True
|
61
|
+
```
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'yaml'
|
3
|
+
require 'json'
|
4
|
+
require 'kitchen-ansible/util-inventory.rb'
|
5
|
+
|
6
|
+
all = []
|
7
|
+
groups = Hash.new
|
8
|
+
hosts = Hash.new
|
9
|
+
if File.exist?(TEMP_GROUP_FILE)
|
10
|
+
groups = YAML::load_file TEMP_GROUP_FILE
|
11
|
+
end
|
12
|
+
|
13
|
+
Dir.glob(TEMP_INV_DIR + '/ansiblepush_host_*.yml') do |inv_yml|
|
14
|
+
vm = YAML::load_file inv_yml
|
15
|
+
vm.each do |host, host_attr|
|
16
|
+
if host_attr["mygroup"]
|
17
|
+
if host_attr["mygroup"].is_a?(Hash)
|
18
|
+
host_attr["mygroup"].each do | group |
|
19
|
+
groups[group] ||= []
|
20
|
+
groups[group] << host
|
21
|
+
end
|
22
|
+
elsif host_attr["mygroup"].kind_of?(String)
|
23
|
+
groups[host_attr["mygroup"]] ||= []
|
24
|
+
groups[host_attr["mygroup"]] << host
|
25
|
+
end
|
26
|
+
end
|
27
|
+
host_attr.delete("mygroup")
|
28
|
+
hosts[host] = host_attr
|
29
|
+
all << host
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
inventory = { "all" => all, "_meta" => { "hostvars" => hosts }}
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
inventory = groups.merge(inventory)
|
38
|
+
|
39
|
+
# Print our inventory
|
40
|
+
puts JSON.pretty_generate(inventory)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import json
|
2
|
+
import os
|
3
|
+
import errno
|
4
|
+
|
5
|
+
change_dir = "/tmp/kitchen_ansible_callback"
|
6
|
+
change_file = change_dir + "/changes"
|
7
|
+
|
8
|
+
class CallbackModule(object):
|
9
|
+
def __init__(self):
|
10
|
+
if not os.path.exists(change_dir):
|
11
|
+
os.makedirs(change_dir)
|
12
|
+
|
13
|
+
try:
|
14
|
+
os.remove(change_file)
|
15
|
+
except OSError as e: # this would be "except OSError, e:" before Python 2.6
|
16
|
+
if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
|
17
|
+
raise # re-raise exception if a different error occured
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
def write_changed_to_file(self, host, res, name=None):
|
22
|
+
changed_data = dict()
|
23
|
+
invocation = res.get("invocation", {})
|
24
|
+
changed_data["changed_module_args"] = invocation.get("module_args", "")
|
25
|
+
changed_data["changed_module_name"] = invocation.get("module_name", "")
|
26
|
+
changed_data["host"] = host
|
27
|
+
if name:
|
28
|
+
changed_data["task_name"] = name
|
29
|
+
changed_data["changed_msg"] = res.get("msg", "")
|
30
|
+
|
31
|
+
try:
|
32
|
+
with open(change_file, 'at') as the_file:
|
33
|
+
the_file.write(json.dumps(changed_data) + "\n")
|
34
|
+
except Exception, e:
|
35
|
+
print "Ansible callback idempotency: Write to file failed '%s' error:'%s'" % (change_file, e)
|
36
|
+
exit(1)
|
37
|
+
|
38
|
+
def on_any(self, *args, **kwargs):
|
39
|
+
pass
|
40
|
+
|
41
|
+
def runner_on_failed(self, host, res, ignore_errors=False):
|
42
|
+
pass
|
43
|
+
|
44
|
+
def runner_on_ok(self, host, res):
|
45
|
+
if res.get("changed"):
|
46
|
+
self.write_changed_to_file(host, res, self.current_task)
|
47
|
+
|
48
|
+
def runner_on_skipped(self, host, item=None):
|
49
|
+
pass
|
50
|
+
|
51
|
+
def runner_on_unreachable(self, host, res):
|
52
|
+
pass
|
53
|
+
|
54
|
+
def runner_on_no_hosts(self):
|
55
|
+
pass
|
56
|
+
|
57
|
+
def runner_on_async_poll(self, host, res, jid, clock):
|
58
|
+
pass
|
59
|
+
|
60
|
+
def runner_on_async_ok(self, host, res, jid):
|
61
|
+
pass
|
62
|
+
|
63
|
+
def runner_on_async_failed(self, host, res, jid):
|
64
|
+
pass
|
65
|
+
|
66
|
+
def playbook_on_start(self):
|
67
|
+
pass
|
68
|
+
|
69
|
+
def playbook_on_notify(self, host, handler):
|
70
|
+
pass
|
71
|
+
|
72
|
+
def playbook_on_no_hosts_matched(self):
|
73
|
+
pass
|
74
|
+
|
75
|
+
def playbook_on_no_hosts_remaining(self):
|
76
|
+
pass
|
77
|
+
|
78
|
+
def playbook_on_task_start(self, name, is_conditional):
|
79
|
+
self.current_task = name
|
80
|
+
|
81
|
+
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
|
82
|
+
pass
|
83
|
+
|
84
|
+
def playbook_on_setup(self):
|
85
|
+
pass
|
86
|
+
|
87
|
+
def playbook_on_import_for_host(self, host, imported_file):
|
88
|
+
pass
|
89
|
+
|
90
|
+
def playbook_on_not_import_for_host(self, host, missing_file):
|
91
|
+
pass
|
92
|
+
|
93
|
+
def playbook_on_play_start(self, name):
|
94
|
+
pass
|
95
|
+
|
96
|
+
def playbook_on_stats(self, stats):
|
97
|
+
pass
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
4
|
+
require 'kitchen-ansible/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "kitchen-ansiblepush"
|
8
|
+
gem.version = Kitchen::AnsiblePush::VERSION
|
9
|
+
gem.authors = ["Adham Helal"]
|
10
|
+
gem.email = ["adham.helal@gmail.com"]
|
11
|
+
gem.licenses = ['MIT']
|
12
|
+
gem.homepage = "https://github.com/ahelal/kitchen-ansiblepush"
|
13
|
+
gem.summary = "ansible provisioner for test-kitchen"
|
14
|
+
candidates = Dir.glob("{lib}/**/*") + ['README.md', 'kitchen-ansiblepush.gemspec', 'callback/changes_callback.py']
|
15
|
+
gem.files = candidates.sort
|
16
|
+
gem.platform = Gem::Platform::RUBY
|
17
|
+
gem.require_paths = ['lib']
|
18
|
+
gem.executables = ['kitchen-ansible-inventory']
|
19
|
+
gem.rubyforge_project = '[none]'
|
20
|
+
gem.description = <<-EOF
|
21
|
+
== DESCRIPTION:
|
22
|
+
|
23
|
+
Ansible push Provisioner for Test Kitchen
|
24
|
+
|
25
|
+
== FEATURES:
|
26
|
+
|
27
|
+
Supports running ansible in push mode
|
28
|
+
|
29
|
+
EOF
|
30
|
+
|
31
|
+
gem.add_runtime_dependency 'test-kitchen'
|
32
|
+
gem.add_development_dependency 'rspec'
|
33
|
+
gem.add_development_dependency 'pry'
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
TEMP_INV_DIR = ".kitchen/ansiblepush"
|
2
|
+
TEMP_GROUP_FILE = "#{TEMP_INV_DIR}/ansiblepush_groups_inventory.yml"
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
def write_instance_inventory(name, host, mygroup, instance_connection_option)
|
7
|
+
Dir.mkdir TEMP_INV_DIR if !File.exist?(TEMP_INV_DIR)
|
8
|
+
port = instance_connection_option[:port]
|
9
|
+
keys = instance_connection_option[:keys]
|
10
|
+
user = instance_connection_option[:user]
|
11
|
+
|
12
|
+
temp_hash = Hash.new
|
13
|
+
temp_hash["ansible_ssh_host"] = host
|
14
|
+
temp_hash["ansible_ssh_port"] = port if port
|
15
|
+
temp_hash["ansible_ssh_private_key_file"] = keys[0] if keys
|
16
|
+
temp_hash["ansible_ssh_user"] = user if user
|
17
|
+
temp_hash["mygroup"] = mygroup if mygroup
|
18
|
+
|
19
|
+
host = { name => temp_hash }
|
20
|
+
File.open("%s/ansiblepush_host_%s.yml" % [TEMP_INV_DIR, name], "w") do |file|
|
21
|
+
file.write host.to_yaml
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def write_group_inventory(groups)
|
26
|
+
Dir.mkdir TEMP_INV_DIR if !File.exist?(TEMP_INV_DIR)
|
27
|
+
File.open(TEMP_GROUP_FILE, "w") do |file|
|
28
|
+
file.write groups.to_yaml
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'kitchen'
|
2
|
+
require 'kitchen/provisioner/base'
|
3
|
+
require 'kitchen-ansible/util-inventory.rb'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Kitchen
|
7
|
+
|
8
|
+
class Busser
|
9
|
+
def non_suite_dirs
|
10
|
+
%w{data}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Provisioner
|
15
|
+
class AnsiblePush < Base
|
16
|
+
kitchen_provisioner_api_version 2
|
17
|
+
default_config :ansible_config, nil
|
18
|
+
default_config :verbose, nil
|
19
|
+
default_config :diff, nil
|
20
|
+
default_config :groups, nil
|
21
|
+
default_config :extra_vars, nil
|
22
|
+
default_config :sudo, nil
|
23
|
+
default_config :sudo_user, nil
|
24
|
+
default_config :remote_user, nil
|
25
|
+
default_config :private_key, nil
|
26
|
+
default_config :ask_vault_pass, nil
|
27
|
+
default_config :vault_password_file, nil
|
28
|
+
default_config :limit, nil
|
29
|
+
default_config :tags, nil
|
30
|
+
default_config :skip_tags, nil
|
31
|
+
default_config :start_at_task, nil
|
32
|
+
default_config :host_key_checking, false
|
33
|
+
default_config :mygroup, nil
|
34
|
+
default_config :playbook, nil
|
35
|
+
default_config :generate_inv, true
|
36
|
+
default_config :raw_arguments, nil
|
37
|
+
default_config :idempotency_test, false
|
38
|
+
|
39
|
+
# For tests disable if not needed
|
40
|
+
default_config :chef_bootstrap_url, "https://www.getchef.com/chef/install.sh"
|
41
|
+
|
42
|
+
def prepare_command
|
43
|
+
validate_config
|
44
|
+
prepare_inventory
|
45
|
+
complie_config
|
46
|
+
end
|
47
|
+
|
48
|
+
def install_command
|
49
|
+
# Must install chef for busser and serverspec to work :(
|
50
|
+
info("*************** AnsiblePush install_command ***************")
|
51
|
+
omnibus_download_dir = config[:omnibus_cachier] ? "/tmp/vagrant-cache/omnibus_chef" : "/tmp"
|
52
|
+
chef_url = config[:chef_bootstrap_url]
|
53
|
+
<<-INSTALL
|
54
|
+
sh -c '
|
55
|
+
#{Util.shell_helpers}
|
56
|
+
if [ ! -d "/opt/chef" ]
|
57
|
+
then
|
58
|
+
echo "-----> Installing Chef Omnibus"
|
59
|
+
mkdir -p #{omnibus_download_dir}
|
60
|
+
if [ ! -x #{omnibus_download_dir}/install.sh ]
|
61
|
+
then
|
62
|
+
do_download #{chef_url} #{omnibus_download_dir}/install.sh
|
63
|
+
fi
|
64
|
+
|
65
|
+
sudo sh #{omnibus_download_dir}/install.sh -d #{omnibus_download_dir}
|
66
|
+
echo "-----> End Installing Chef Omnibus"
|
67
|
+
fi
|
68
|
+
|
69
|
+
# Fix for https://github.com/test-kitchen/busser/issues/12
|
70
|
+
if [ -h /usr/bin/ruby ]; then
|
71
|
+
L=$(readlink -f /usr/bin/ruby)
|
72
|
+
sudo rm /usr/bin/ruby
|
73
|
+
sudo ln -s $L /usr/bin/ruby
|
74
|
+
fi
|
75
|
+
'
|
76
|
+
INSTALL
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def run_command
|
81
|
+
info("*************** AnsiblePush run ***************")
|
82
|
+
exec_command(@command_env, @command, "ansible-playbook")
|
83
|
+
# idempotency test
|
84
|
+
if config[:idempotency_test]
|
85
|
+
info("*************** idempotency test ***************")
|
86
|
+
@command_env["ANSIBLE_CALLBACK_PLUGINS"] = "#{File.dirname(__FILE__)}/../../../callback/"
|
87
|
+
exec_command(@command_env, @command, "ansible-playbook")
|
88
|
+
# Check ansible callback if changes has occured in the second run
|
89
|
+
file_path = "/tmp/kitchen_ansible_callback/changes"
|
90
|
+
if File.file?(file_path)
|
91
|
+
task = 0
|
92
|
+
info("idempotency test [Failed]")
|
93
|
+
File.open(file_path, "r") do |f|
|
94
|
+
f.each_line do |line|
|
95
|
+
task += 1
|
96
|
+
info(" #{task}> #{line.strip}")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
raise "idempotency test Failed. Number of non idemptent tasks: #{task}"
|
100
|
+
|
101
|
+
else
|
102
|
+
info("idempotency test [passed]")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
info("*************** AnsiblePush end run *******************")
|
106
|
+
debug("[#{name}] Converge completed (#{config[:sleep]}s).")
|
107
|
+
return nil
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
def exec_command(env, command, desc)
|
113
|
+
debug("env=%s command=%s" % [env, command] )
|
114
|
+
system(env, "#{command}")
|
115
|
+
exit_code = $?.exitstatus
|
116
|
+
debug("ansible-playbook exit code = #{exit_code}")
|
117
|
+
if exit_code.to_i != 0
|
118
|
+
raise "%s returned a non zeroo '%s'. Please see the output above." % [ desc, exit_code.to_s ]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def prepare_inventory
|
123
|
+
@machine_name = instance.to_str.gsub(/[<>]/, '').split("-").drop(1).join("-")
|
124
|
+
@instance_connection_option = instance.transport.instance_variable_get(:@connection_options)
|
125
|
+
hostname = @instance_connection_option[:hostname]
|
126
|
+
debug("instance_connection_option=" + @instance_connection_option.to_s)
|
127
|
+
write_instance_inventory(@machine_name, hostname, config[:mygroup], @instance_connection_option)
|
128
|
+
end
|
129
|
+
|
130
|
+
def complie_config()
|
131
|
+
debug("compile_config")
|
132
|
+
options = []
|
133
|
+
options << "--extra-vars=#{self.get_extra_vars_argument}" if config[:extra_vars]
|
134
|
+
options << "--sudo" if config[:sudo]
|
135
|
+
options << "--sudo-user=#{config[:sudo_user]}" if config[:sudo_user]
|
136
|
+
options << "--user=#{config[:remote_user]}" if self.get_remote_user
|
137
|
+
options << "--private-key=#{config[:private_key]}" if config[:private_key]
|
138
|
+
options << "#{self.get_verbosity_argument}" if config[:verbose]
|
139
|
+
options << "--diff" if config[:diff]
|
140
|
+
options << "--ask-sudo-pass" if config[:ask_sudo_pass]
|
141
|
+
options << "--ask-vault-pass" if config[:ask_vault_pass]
|
142
|
+
options << "--vault-password-file=#{config[:vault_password_file]}" if config[:vault_password_file]
|
143
|
+
options << "--tags=%s" % self.as_list_argument(config[:tags]) if config[:tags]
|
144
|
+
options << "--skip-tags=%s" % self.as_list_argument(config[:skip_tags]) if config[:skip_tags]
|
145
|
+
options << "--start-at-task=#{config[:start_at_task]}" if config[:start_at_task]
|
146
|
+
options << "--inventory-file=`which kitchen-ansible-inventory`" if config[:generate_inv]
|
147
|
+
##options << "--inventory-file=#{ssh_inv}," if ssh_inv
|
148
|
+
|
149
|
+
# By default we limit by the current machine,
|
150
|
+
if config[:limit]
|
151
|
+
options << "--limit=#{as_list_argument(config[:limit])}"
|
152
|
+
else
|
153
|
+
options << "--limit=#{@machine_name}"
|
154
|
+
end
|
155
|
+
|
156
|
+
#Add raw argument as final thing
|
157
|
+
options << config[:raw_arguments] if config[:raw_arguments]
|
158
|
+
|
159
|
+
@command = (%w(ansible-playbook) << options << config[:playbook]).flatten.join(" ")
|
160
|
+
debug("Ansible push command= %s" % @command)
|
161
|
+
@command_env = {
|
162
|
+
"PYTHONUNBUFFERED" => "1", # Ensure Ansible output isn't buffered
|
163
|
+
"ANSIBLE_FORCE_COLOR" => "true",
|
164
|
+
"ANSIBLE_HOST_KEY_CHECKING" => "#{config[:host_key_checking]}",
|
165
|
+
}
|
166
|
+
@command_env["ANSIBLE_CONFIG"]=config[:ansible_config] if config[:ansible_config]
|
167
|
+
|
168
|
+
info("Ansible push compile conig done")
|
169
|
+
end
|
170
|
+
|
171
|
+
def validate_config()
|
172
|
+
if !config[:playbook]
|
173
|
+
raise 'No playbook defined. Please specify one in .kitchen.yml'
|
174
|
+
end
|
175
|
+
|
176
|
+
if !File.exist?(config[:playbook])
|
177
|
+
raise "playbook '%s' could not be found. Please check path" % config[:playbook]
|
178
|
+
end
|
179
|
+
|
180
|
+
if config[:vault_password_file] and !File.exist?(config[:vault_password_file])
|
181
|
+
raise "Vault password '%s' could not be found. Please check path" % config[:vault_password_file]
|
182
|
+
end
|
183
|
+
|
184
|
+
# Validate that extra_vars is either a hash, or a path to an existing file
|
185
|
+
if config[:extra_vars]
|
186
|
+
extra_vars_is_valid = config[:extra_vars].kind_of?(Hash) || config[:extra_vars].kind_of?(String)
|
187
|
+
if config[:extra_vars].kind_of?(String)
|
188
|
+
# Accept the usage of '@' (e.g. '@vars.yml' and 'vars.yml' are both supported)
|
189
|
+
match_data = /^@?(.+)$/.match(config[:extra_vars])
|
190
|
+
extra_vars_path = match_data[1].to_s
|
191
|
+
expanded_path = Pathname.new(extra_vars_path).expand_path(Dir.pwd)
|
192
|
+
extra_vars_is_valid = expanded_path.exist?
|
193
|
+
if extra_vars_is_valid
|
194
|
+
@extra_vars = '@' + extra_vars_path
|
195
|
+
end
|
196
|
+
end
|
197
|
+
if !extra_vars_is_valid
|
198
|
+
raise "ansible extra_vars is in valid type: %s value: %s" % [config[:extra_vars].class.to_s, config[:extra_vars].to_s]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
info("Ansible push config validated")
|
202
|
+
end
|
203
|
+
|
204
|
+
def get_extra_vars_argument()
|
205
|
+
if config[:extra_vars].kind_of?(String) and config[:extra_vars] =~ /^@.+$/
|
206
|
+
# A JSON or YAML file is referenced (requires Ansible 1.3+)
|
207
|
+
return config[:extra_vars]
|
208
|
+
else
|
209
|
+
# Expected to be a Hash after config validation. (extra_vars as
|
210
|
+
# JSON requires Ansible 1.2+, while YAML requires Ansible 1.3+)
|
211
|
+
return config[:extra_vars].to_json
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def get_remote_user
|
216
|
+
if config[:remote_user]
|
217
|
+
return config[:remote_user]
|
218
|
+
elsif @instance_connection_option[:username]
|
219
|
+
config[:remote_user] = @instance_connection_option[:username]
|
220
|
+
return @instance_connection_option[:username]
|
221
|
+
else
|
222
|
+
return nil
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def as_list_argument(v)
|
227
|
+
v.kind_of?(Array) ? v.join(',') : v
|
228
|
+
end
|
229
|
+
|
230
|
+
def get_verbosity_argument
|
231
|
+
if config[:verbose].to_s =~ /^v+$/
|
232
|
+
# ansible-playbook accepts "silly" arguments like '-vvvvv' as '-vvvv' for now
|
233
|
+
return "-#{config[:verbose]}"
|
234
|
+
else
|
235
|
+
# safe default, in case input strays
|
236
|
+
return '-v'
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kitchen-ansiblepush
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adham Helal
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-kitchen
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: |+
|
56
|
+
== DESCRIPTION:
|
57
|
+
|
58
|
+
Ansible push Provisioner for Test Kitchen
|
59
|
+
|
60
|
+
== FEATURES:
|
61
|
+
|
62
|
+
Supports running ansible in push mode
|
63
|
+
|
64
|
+
email:
|
65
|
+
- adham.helal@gmail.com
|
66
|
+
executables:
|
67
|
+
- kitchen-ansible-inventory
|
68
|
+
extensions: []
|
69
|
+
extra_rdoc_files: []
|
70
|
+
files:
|
71
|
+
- README.md
|
72
|
+
- callback/changes_callback.py
|
73
|
+
- kitchen-ansiblepush.gemspec
|
74
|
+
- lib/kitchen-ansible/util-inventory.rb
|
75
|
+
- lib/kitchen-ansible/version.rb
|
76
|
+
- lib/kitchen/provisioner/ansible_push.rb
|
77
|
+
- bin/kitchen-ansible-inventory
|
78
|
+
homepage: https://github.com/ahelal/kitchen-ansiblepush
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project: '[none]'
|
98
|
+
rubygems_version: 2.0.14
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: ansible provisioner for test-kitchen
|
102
|
+
test_files: []
|