cucumber-chef 1.0.3 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -35
- data/.rspec +1 -0
- data/.rvmrc.template +2 -0
- data/.travis.yml +22 -0
- data/Gemfile +2 -15
- data/LICENSE +202 -201
- data/NOTICE +9 -0
- data/README.md +696 -92
- data/Rakefile +39 -25
- data/TODO.md +28 -0
- data/bin/cc-knife +32 -0
- data/bin/cucumber-chef +409 -79
- data/chef_repo/cookbooks/cucumber-chef/LICENSE +202 -0
- data/chef_repo/cookbooks/cucumber-chef/README.md +69 -0
- data/chef_repo/cookbooks/cucumber-chef/attributes/default.rb +27 -0
- data/chef_repo/cookbooks/cucumber-chef/metadata.rb +13 -0
- data/chef_repo/cookbooks/cucumber-chef/recipes/default.rb +23 -0
- data/chef_repo/cookbooks/cucumber-chef/recipes/lxc.rb +315 -0
- data/chef_repo/cookbooks/cucumber-chef/recipes/test_lab.rb +146 -0
- data/chef_repo/cookbooks/cucumber-chef/templates/default/db-168-192.erb +15 -0
- data/chef_repo/cookbooks/cucumber-chef/templates/default/db-test-lab.erb +15 -0
- data/chef_repo/cookbooks/cucumber-chef/templates/default/dhcpd-conf.erb +44 -0
- data/chef_repo/cookbooks/cucumber-chef/templates/default/gemrc.erb +10 -0
- data/{cookbooks/cucumber-chef/files/default/cucumber-net → chef_repo/cookbooks/cucumber-chef/templates/default/lxc-initializer-config.erb} +1 -1
- data/chef_repo/cookbooks/cucumber-chef/templates/default/lxc-install-chef.erb +3 -0
- data/chef_repo/cookbooks/cucumber-chef/templates/default/motd.erb +10 -0
- data/chef_repo/cookbooks/cucumber-chef/templates/default/named-conf-local.erb +25 -0
- data/{cookbooks/cucumber-chef/files/default/permissive-ssh-config → chef_repo/cookbooks/cucumber-chef/templates/default/ssh-config.erb} +3 -1
- data/chef_repo/roles/test_lab.rb +24 -0
- data/cucumber-chef.gemspec +50 -123
- data/examples/README.md +7 -0
- data/examples/users_add.feature +51 -0
- data/examples/users_auto_remove.feature +50 -0
- data/features/support/env.rb +3 -2
- data/lib/cucumber/chef/bootstrap.rb +94 -0
- data/lib/cucumber/chef/command.rb +78 -0
- data/lib/cucumber/chef/config.rb +143 -93
- data/lib/cucumber/chef/helpers/chef_client.rb +87 -0
- data/lib/cucumber/chef/helpers/chef_server.rb +90 -0
- data/lib/cucumber/chef/helpers/command.rb +57 -0
- data/lib/cucumber/chef/helpers/container.rb +154 -0
- data/lib/cucumber/chef/helpers/minitest.rb +35 -0
- data/lib/cucumber/chef/helpers/server.rb +81 -0
- data/lib/cucumber/chef/helpers/test_lab.rb +46 -0
- data/lib/cucumber/chef/helpers/utility.rb +73 -0
- data/lib/cucumber/chef/helpers.rb +56 -0
- data/lib/cucumber/chef/logger.rb +90 -0
- data/lib/cucumber/chef/provisioner.rb +275 -69
- data/lib/cucumber/chef/ssh.rb +190 -0
- data/lib/cucumber/chef/steps/chef_steps.rb +32 -0
- data/lib/cucumber/chef/steps/minitest_steps.rb +29 -0
- data/lib/cucumber/chef/steps/provision_steps.rb +60 -0
- data/lib/cucumber/chef/steps/ssh_steps.rb +95 -0
- data/lib/cucumber/chef/steps.rb +27 -0
- data/lib/cucumber/chef/tcp_socket.rb +83 -0
- data/lib/cucumber/chef/template.rb +57 -0
- data/lib/cucumber/chef/templates/bootstrap/ubuntu-precise-test-lab.erb +99 -0
- data/lib/cucumber/chef/templates/cucumber/env.rb +56 -0
- data/lib/cucumber/chef/templates/cucumber/example_feature.erb +49 -0
- data/lib/cucumber/chef/templates/cucumber/example_steps.erb +11 -0
- data/lib/cucumber/chef/templates/cucumber/readme-data_bags.erb +1 -0
- data/lib/cucumber/chef/templates/cucumber/readme-keys.erb +1 -0
- data/lib/cucumber/chef/templates/cucumber/readme-roles.erb +1 -0
- data/lib/cucumber/chef/templates/cucumber/readme.erb +18 -0
- data/lib/cucumber/chef/templates/cucumber-chef/config-rb.erb +33 -0
- data/lib/cucumber/chef/templates/cucumber-chef/cucumber-yml.erb +2 -0
- data/lib/cucumber/chef/templates/cucumber-chef/knife-rb.erb +18 -0
- data/lib/cucumber/chef/test_lab.rb +308 -52
- data/lib/cucumber/chef/test_runner.rb +86 -15
- data/lib/cucumber/chef/utility.rb +128 -0
- data/lib/cucumber/chef/version.rb +30 -1
- data/lib/cucumber/chef.rb +53 -20
- data/lib/cucumber-chef.rb +24 -1
- data/spec/cucumber/chef/config_spec.rb +144 -78
- data/spec/cucumber/chef/provisioner_spec.rb +60 -16
- data/spec/cucumber/chef/test_lab_spec.rb +62 -19
- data/spec/spec_helper.rb +30 -26
- data/todo.org +17 -0
- metadata +267 -163
- data/.document +0 -5
- data/VERSION +0 -1
- data/cookbooks/cucumber-chef/README.rdoc +0 -8
- data/cookbooks/cucumber-chef/files/default/add-git-identity +0 -2
- data/cookbooks/cucumber-chef/files/default/controller-first-boot +0 -1
- data/cookbooks/cucumber-chef/files/default/cucumber-private-key +0 -27
- data/cookbooks/cucumber-chef/files/default/cucumber-run_list +0 -1
- data/cookbooks/cucumber-chef/files/default/git-private-key +0 -27
- data/cookbooks/cucumber-chef/files/default/install-chef +0 -1
- data/cookbooks/cucumber-chef/files/default/lxc-controller-network-config +0 -5
- data/cookbooks/cucumber-chef/files/default/lxc-lucid-chef +0 -378
- data/cookbooks/cucumber-chef/metadata.rb +0 -6
- data/cookbooks/cucumber-chef/recipes/controller.rb +0 -51
- data/cookbooks/cucumber-chef/recipes/lxc.rb +0 -35
- data/cookbooks/cucumber-chef/recipes/test_lab.rb +0 -23
- data/cookbooks/cucumber-chef/recipes/testrunner.rb +0 -46
- data/cookbooks/cucumber-chef/roles/controller.rb +0 -7
- data/cookbooks/cucumber-chef/roles/test_lab_test.rb +0 -9
- data/cookbooks/cucumber-chef/templates/default/controller-client.erb +0 -5
- data/cookbooks/cucumber-chef/templates/default/lxc-lucid-chef +0 -385
- data/lib/cucumber/chef/handy.rb +0 -90
- data/lib/cucumber/chef/templates/controller.erb +0 -35
- data/lib/cucumber/chef/templates/env.rb +0 -16
- data/lib/cucumber/chef/templates/example_feature.erb +0 -11
- data/lib/cucumber/chef/templates/example_step.erb +0 -19
- data/lib/cucumber/chef/templates/readme.erb +0 -14
- data/lib/cucumber/chef/templates/ubuntu10.04-gems.erb +0 -43
- data/lib/cucumber/ec2_server_create.rb +0 -99
- data/website/website.html +0 -385
@@ -0,0 +1,94 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
+
# Copyright: Copyright (c) 2011-2012 Atalanta Systems Ltd
|
6
|
+
# License: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
################################################################################
|
21
|
+
|
22
|
+
module Cucumber
|
23
|
+
module Chef
|
24
|
+
|
25
|
+
class BootstrapError < Error; end
|
26
|
+
|
27
|
+
class Bootstrap
|
28
|
+
attr_accessor :stdout, :stderr, :stdin, :config
|
29
|
+
|
30
|
+
################################################################################
|
31
|
+
|
32
|
+
def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN)
|
33
|
+
@stdout, @stderr, @stdin = stdout, stderr, stdin
|
34
|
+
@stdout.sync = true if @stdout.respond_to?(:sync=)
|
35
|
+
|
36
|
+
@ssh = Cucumber::Chef::SSH.new(@stdout, @stderr, @stdin)
|
37
|
+
@config = Hash.new(nil)
|
38
|
+
@config[:context] = Hash.new(nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
################################################################################
|
42
|
+
|
43
|
+
def run
|
44
|
+
$logger.debug { "config(#{@config.inspect})" }
|
45
|
+
|
46
|
+
if !@config[:template_file]
|
47
|
+
message = "You must supply a 'template_file' option."
|
48
|
+
$logger.fatal { message }
|
49
|
+
raise BootstrapError, message
|
50
|
+
end
|
51
|
+
|
52
|
+
if !@config[:host]
|
53
|
+
message = "You must supply a 'host' option."
|
54
|
+
$logger.fatal { message }
|
55
|
+
raise BootstrapError, message
|
56
|
+
end
|
57
|
+
|
58
|
+
if !@config[:ssh_user]
|
59
|
+
message = "You must supply a 'ssh_user' option."
|
60
|
+
$logger.fatal { message }
|
61
|
+
raise BootstrapError, message
|
62
|
+
end
|
63
|
+
|
64
|
+
if (!@config[:ssh_password] && !@config[:identity_file])
|
65
|
+
message = "You must supply a 'ssh_password' or 'identity_file' option."
|
66
|
+
$logger.fatal { message }
|
67
|
+
raise BootstrapError, message
|
68
|
+
end
|
69
|
+
|
70
|
+
$logger.debug { "prepare(#{@config[:host]})" }
|
71
|
+
|
72
|
+
@ssh.config[:host] = @config[:host]
|
73
|
+
@ssh.config[:ssh_user] = @config[:ssh_user]
|
74
|
+
@ssh.config[:ssh_password] = @config[:ssh_password]
|
75
|
+
@ssh.config[:identity_file] = @config[:identity_file]
|
76
|
+
@ssh.config[:timeout] = 5
|
77
|
+
|
78
|
+
$logger.debug { "template_file(#{@config[:template_file]})" }
|
79
|
+
command = Cucumber::Chef::Template.render(@config[:template_file], @config[:context])
|
80
|
+
command = "sudo #{command}" if @config[:use_sudo]
|
81
|
+
|
82
|
+
$logger.debug { "begin(#{@config[:host]})" }
|
83
|
+
@ssh.exec(command, :silence => true)
|
84
|
+
$logger.debug { "end(#{@config[:host]})" }
|
85
|
+
end
|
86
|
+
|
87
|
+
################################################################################
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
################################################################################
|
@@ -0,0 +1,78 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
+
# Copyright: Copyright (c) 2011-2012 Atalanta Systems Ltd
|
6
|
+
# License: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
################################################################################
|
21
|
+
|
22
|
+
module Cucumber
|
23
|
+
module Chef
|
24
|
+
|
25
|
+
class CommandError < Error; end
|
26
|
+
|
27
|
+
class Command
|
28
|
+
attr_accessor :stdout, :stderr, :stdin
|
29
|
+
|
30
|
+
################################################################################
|
31
|
+
|
32
|
+
def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN)
|
33
|
+
@stdout, @stderr, @stdin = stdout, stderr, stdin
|
34
|
+
@stdout.sync = true if @stdout.respond_to?(:sync=)
|
35
|
+
|
36
|
+
@knife = (Cucumber::Chef.locate(:file, "bin", "knife") rescue nil)
|
37
|
+
@knife = "/usr/bin/env knife" unless @knife
|
38
|
+
end
|
39
|
+
|
40
|
+
################################################################################
|
41
|
+
|
42
|
+
def run(command, options={})
|
43
|
+
options = { :exit_code => 0, :silence => false }.merge(options)
|
44
|
+
exit_code = options[:exit_code]
|
45
|
+
silence = options[:silence]
|
46
|
+
$logger.debug { "options(#{options.inspect})" }
|
47
|
+
|
48
|
+
command = "#{command} 2>&1"
|
49
|
+
$logger.debug { "command(#{command})" }
|
50
|
+
output = %x( #{command} )
|
51
|
+
$logger.debug { "exit_code(#{$?})" }
|
52
|
+
|
53
|
+
$logger.debug { "--------------------------------------------------------------------------------" }
|
54
|
+
$logger.debug { output }
|
55
|
+
$logger.debug { "--------------------------------------------------------------------------------" }
|
56
|
+
|
57
|
+
@stdout.puts(output) if !silence
|
58
|
+
|
59
|
+
raise CommandError, "run(#{command}) failed! [#{$?}]" if ($? != exit_code)
|
60
|
+
|
61
|
+
output
|
62
|
+
end
|
63
|
+
|
64
|
+
################################################################################
|
65
|
+
|
66
|
+
def knife(command, options={})
|
67
|
+
knife_rb = File.expand_path(File.join(Dir.pwd, ".cucumber-chef", "knife.rb"))
|
68
|
+
run("#{@knife} #{command.flatten.compact.join(" ")} -c #{knife_rb} --color -n", options)
|
69
|
+
end
|
70
|
+
|
71
|
+
################################################################################
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
################################################################################
|
data/lib/cucumber/chef/config.rb
CHANGED
@@ -1,129 +1,179 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
+
# Copyright: Copyright (c) 2011-2012 Atalanta Systems Ltd
|
6
|
+
# License: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
################################################################################
|
21
|
+
|
1
22
|
module Cucumber
|
2
23
|
module Chef
|
3
|
-
|
24
|
+
|
25
|
+
class ConfigError < Error; end
|
4
26
|
|
5
27
|
class Config
|
6
|
-
|
7
|
-
KNIFE_KEYS = %w[aws_access_key_id aws_secret_access_key region aws_image_id availability_zone aws_ssh_key_id identity_file]
|
28
|
+
extend(Mixlib::Config)
|
8
29
|
|
9
|
-
|
10
|
-
|
11
|
-
|
30
|
+
KEYS = %w( mode provider ).map(&:to_sym) unless const_defined?(:KEYS)
|
31
|
+
MODES = %w( user test ).map(&:to_sym) unless const_defined?(:MODES)
|
32
|
+
PROVIDERS = %w( aws vagrant ).map(&:to_sym) unless const_defined?(:PROVIDERS)
|
12
33
|
|
13
|
-
|
14
|
-
config.test_mode? ? 'test' : 'user'
|
15
|
-
end
|
34
|
+
PROVIDER_AWS_KEYS = %w( aws_access_key_id aws_secret_access_key region availability_zone aws_ssh_key_id identity_file ).map(&:to_sym) unless const_defined?(:PROVIDER_AWS_KEYS)
|
16
35
|
|
17
|
-
|
18
|
-
config[key]
|
19
|
-
end
|
36
|
+
################################################################################
|
20
37
|
|
21
|
-
def
|
22
|
-
|
38
|
+
def self.inspect
|
39
|
+
configuration.inspect
|
23
40
|
end
|
24
41
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
::Chef::Config.from_file(knife_file)
|
32
|
-
@config = ::Chef::Config
|
33
|
-
return @config
|
34
|
-
end
|
35
|
-
end
|
36
|
-
raise ConfigError.new("Couldn't find knife.rb")
|
42
|
+
################################################################################
|
43
|
+
|
44
|
+
def self.duplicate(input)
|
45
|
+
output = Hash.new
|
46
|
+
input.each do |key, value|
|
47
|
+
output[key] = (value.is_a?(Hash) ? self.duplicate(input[key]) : value.to_s.dup)
|
37
48
|
end
|
38
|
-
|
49
|
+
output
|
39
50
|
end
|
40
51
|
|
41
|
-
def self.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
52
|
+
def self.load
|
53
|
+
config_rb = Cucumber::Chef.locate(:file, ".cucumber-chef", "config.rb")
|
54
|
+
$logger.info { "Attempting to load cucumber-chef configuration from '%s'." % config_rb }
|
55
|
+
self.from_file(config_rb)
|
56
|
+
self.verify
|
57
|
+
$logger.info { "Successfully loaded cucumber-chef configuration from '%s'." % config_rb }
|
46
58
|
|
47
|
-
|
48
|
-
|
49
|
-
|
59
|
+
log_dump = self.duplicate(self.configuration)
|
60
|
+
log_dump[:aws].merge!(:aws_access_key_id => "[REDACTED]", :aws_secret_access_key => "[REDACTED]")
|
61
|
+
$logger.debug { log_dump.inspect }
|
50
62
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
value = config[key]
|
55
|
-
values << "#{key}: #{value}"
|
56
|
-
end
|
57
|
-
KNIFE_KEYS.each do |key|
|
58
|
-
value = config[:knife][key.to_sym]
|
59
|
-
values << "knife[:#{key}]: #{value}"
|
60
|
-
end
|
61
|
-
values
|
63
|
+
self
|
64
|
+
rescue Errno::ENOENT, UtilityError
|
65
|
+
raise ConfigError, "Could not find your cucumber-chef configuration file; did you run 'cucumber-chef init'?"
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
verify_keys
|
69
|
-
verify_opscode_platform_credentials
|
70
|
-
verify_aws_credentials
|
71
|
-
if @errors.size > 0
|
72
|
-
raise ConfigError.new(@errors.join("\n"))
|
73
|
-
end
|
68
|
+
def self.test
|
69
|
+
self.load
|
70
|
+
self[:mode] = :test
|
71
|
+
self
|
74
72
|
end
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
def verify_orgname
|
79
|
-
if !ENV["ORGNAME"] || ENV["ORGNAME"] == ""
|
80
|
-
@errors << "Your organisation must be set using the environment variable ORGNAME."
|
81
|
-
end
|
82
|
-
end
|
74
|
+
################################################################################
|
83
75
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
76
|
+
def self.verify
|
77
|
+
self.verify_keys
|
78
|
+
self.verify_provider_keys
|
79
|
+
eval("self.verify_provider_#{self[:provider].to_s.downcase}")
|
80
|
+
$logger.debug { "Configuration verified successfully" }
|
88
81
|
end
|
89
82
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
83
|
+
################################################################################
|
84
|
+
|
85
|
+
def self.verify_keys
|
86
|
+
$logger.debug { "Checking for missing configuration keys" }
|
87
|
+
missing_keys = KEYS.select{ |key| !self[key.to_sym] }
|
88
|
+
if missing_keys.count > 0
|
89
|
+
message = "Configuration incomplete, missing configuration keys: #{missing_keys.join(", ")}"
|
90
|
+
$logger.fatal { message }
|
91
|
+
raise ConfigError, message
|
98
92
|
end
|
99
|
-
|
100
|
-
|
93
|
+
|
94
|
+
$logger.debug { "Checking for invalid configuration keys" }
|
95
|
+
invalid_keys = KEYS.select{ |key| !eval("#{key.to_s.upcase}S").include?(self[key]) }
|
96
|
+
if invalid_keys.count > 0
|
97
|
+
message = "Configuration incomplete, invalid configuration keys: #{invalid_keys.join(", ")}"
|
98
|
+
$logger.fatal { message }
|
99
|
+
raise ConfigError, message
|
101
100
|
end
|
102
101
|
end
|
103
102
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
103
|
+
################################################################################
|
104
|
+
|
105
|
+
def self.verify_provider_keys
|
106
|
+
$logger.debug { "Checking for missing provider keys" }
|
107
|
+
missing_keys = eval("PROVIDER_#{self[:provider].to_s.upcase}_KEYS").select{ |key| !self[self[:provider]].key?(key) }
|
108
|
+
if missing_keys.count > 0
|
109
|
+
message = "Configuration incomplete, missing provider configuration keys: #{missing_keys.join(", ")}"
|
110
|
+
$logger.fatal { message }
|
111
|
+
raise ConfigError, message
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
|
115
|
+
################################################################################
|
116
|
+
|
117
|
+
def self.verify_provider_aws
|
118
|
+
if self[:aws][:aws_access_key_id] && self[:aws][:aws_secret_access_key]
|
117
119
|
compute = Fog::Compute.new(:provider => 'AWS',
|
118
|
-
:aws_access_key_id =>
|
119
|
-
:aws_secret_access_key =>
|
120
|
+
:aws_access_key_id => self[:aws][:aws_access_key_id],
|
121
|
+
:aws_secret_access_key => self[:aws][:aws_secret_access_key])
|
120
122
|
compute.describe_availability_zones
|
121
|
-
else
|
122
|
-
@errors << "Invalid AWS credentials. Please check."
|
123
123
|
end
|
124
124
|
rescue Fog::Service::Error => err
|
125
|
-
|
125
|
+
message = "Invalid AWS credentials. Please check your configuration."
|
126
|
+
$logger.fatal { message }
|
127
|
+
raise ConfigError, message
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.verify_provider_vagrant
|
131
|
+
message = "Not yet implemented."
|
132
|
+
$logger.fatal { message }
|
133
|
+
raise ConfigError, message
|
134
|
+
end
|
135
|
+
|
136
|
+
################################################################################
|
137
|
+
|
138
|
+
def self.aws_image_id
|
139
|
+
if self[:aws][:aws_image_id]
|
140
|
+
return self[:aws][:aws_image_id]
|
141
|
+
elsif (self[:aws][:ubuntu_release] && self[:aws][:region])
|
142
|
+
ami = Ubuntu.release(self[:aws][:ubuntu_release]).amis.find do |ami|
|
143
|
+
ami.arch == (self[:aws][:aws_instance_arch] || "i386") &&
|
144
|
+
ami.root_store == (self[:aws][:aws_instance_disk_store] || "instance-store") &&
|
145
|
+
ami.region == self[:aws][:region]
|
146
|
+
end
|
147
|
+
return ami.name if ami
|
148
|
+
end
|
149
|
+
message = "Could not find a valid AMI image ID. Please check your configuration."
|
150
|
+
$logger.fatal { message }
|
151
|
+
raise ConfigError, message
|
126
152
|
end
|
153
|
+
|
154
|
+
################################################################################
|
155
|
+
|
156
|
+
mode :user
|
157
|
+
prerelease true
|
158
|
+
|
159
|
+
provider :aws
|
160
|
+
librarian_chef false
|
161
|
+
|
162
|
+
user ( ENV['OPSCODE_USER'] || ENV['USER'] )
|
163
|
+
|
164
|
+
aws Hash[ :ubuntu_release => "precise",
|
165
|
+
:aws_instance_arch => "i386",
|
166
|
+
:aws_instance_disk_store => "ebs",
|
167
|
+
:aws_instance_type => "m1.small",
|
168
|
+
:aws_security_group => "cucumber-chef" ]
|
169
|
+
|
170
|
+
vagrant Hash.new
|
171
|
+
|
172
|
+
################################################################################
|
173
|
+
|
127
174
|
end
|
175
|
+
|
128
176
|
end
|
129
177
|
end
|
178
|
+
|
179
|
+
################################################################################
|
@@ -0,0 +1,87 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
+
# Copyright: Copyright (c) 2011-2012 Atalanta Systems Ltd
|
6
|
+
# License: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
################################################################################
|
21
|
+
|
22
|
+
module Cucumber::Chef::Helpers::ChefClient
|
23
|
+
|
24
|
+
################################################################################
|
25
|
+
|
26
|
+
# call this in a Before hook
|
27
|
+
def chef_set_client_config(config={})
|
28
|
+
@chef_client_config = { :log_level => :debug,
|
29
|
+
:log_location => "/var/log/chef/client.log",
|
30
|
+
:chef_server_url => "https://api.opscode.com/organizations/#{config[:orgname]}",
|
31
|
+
:validation_client_name => "#{config[:orgname]}-validator" }.merge(config)
|
32
|
+
end
|
33
|
+
|
34
|
+
################################################################################
|
35
|
+
|
36
|
+
# call this before chef_run_client
|
37
|
+
def chef_set_client_attributes(name, attributes={})
|
38
|
+
@chef_client_attributes = (@chef_client_attributes || {}).merge(attributes) { |k,o,n| (k = (o + n)) }
|
39
|
+
end
|
40
|
+
|
41
|
+
################################################################################
|
42
|
+
|
43
|
+
def chef_run_client(name,*args)
|
44
|
+
chef_config_client(name)
|
45
|
+
output = command_run_remote(name, ["/usr/bin/chef-client -j /etc/chef/attributes.json -N #{name}", args].join(" "))
|
46
|
+
log("chef-client", "ran on node '#{name}'")
|
47
|
+
output
|
48
|
+
end
|
49
|
+
|
50
|
+
################################################################################
|
51
|
+
|
52
|
+
def chef_config_client(name)
|
53
|
+
# make sure our configuration location is there
|
54
|
+
client_rb = File.join("/", container_root(name), "etc/chef/client.rb")
|
55
|
+
FileUtils.mkdir_p(File.dirname(client_rb))
|
56
|
+
|
57
|
+
File.open(client_rb, 'w') do |f|
|
58
|
+
f.puts(Cucumber::Chef.generate_do_not_edit_warning("Chef Client Configuration"))
|
59
|
+
f.puts
|
60
|
+
f.puts("log_level :#{@chef_client_config[:log_level]}")
|
61
|
+
f.puts("log_location \"#{@chef_client_config[:log_location]}\"")
|
62
|
+
f.puts("chef_server_url \"#{@chef_client_config[:chef_server_url]}\"")
|
63
|
+
f.puts("ssl_verify_mode :verify_none")
|
64
|
+
f.puts("validation_client_name \"#{@chef_client_config[:validation_client_name]}\"")
|
65
|
+
f.puts("node_name \"#{name}\"")
|
66
|
+
f.puts
|
67
|
+
f.puts("Mixlib::Log::Formatter.show_time = true")
|
68
|
+
end
|
69
|
+
|
70
|
+
attributes_json = File.join("/", container_root(name), "etc", "chef", "attributes.json")
|
71
|
+
FileUtils.mkdir_p(File.dirname(attributes_json))
|
72
|
+
File.open(attributes_json, 'w') do |f|
|
73
|
+
f.puts((@chef_client_attributes || {}).to_json)
|
74
|
+
end
|
75
|
+
|
76
|
+
# make sure our log location is there
|
77
|
+
log_location = File.join("/", container_root(name), @chef_client_config[:log_location])
|
78
|
+
FileUtils.mkdir_p(File.dirname(log_location))
|
79
|
+
|
80
|
+
command_run_local("cp /etc/chef/validation.pem #{container_root(name)}/etc/chef/ 2>&1")
|
81
|
+
end
|
82
|
+
|
83
|
+
################################################################################
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
################################################################################
|
@@ -0,0 +1,90 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
+
# Copyright: Copyright (c) 2011-2012 Atalanta Systems Ltd
|
6
|
+
# License: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
################################################################################
|
21
|
+
|
22
|
+
module Cucumber::Chef::Helpers::ChefServer
|
23
|
+
|
24
|
+
################################################################################
|
25
|
+
|
26
|
+
def chef_server_node_destroy(name)
|
27
|
+
(::Chef::Node.load(name).destroy rescue nil)
|
28
|
+
log("chef-server", "destroyed node '#{name}'")
|
29
|
+
end
|
30
|
+
|
31
|
+
################################################################################
|
32
|
+
|
33
|
+
def chef_server_client_destroy(name)
|
34
|
+
(::Chef::ApiClient.load(name).destroy rescue nil)
|
35
|
+
log("chef-server", "destroyed client '#{name}'")
|
36
|
+
end
|
37
|
+
|
38
|
+
################################################################################
|
39
|
+
|
40
|
+
def load_role(role, role_path)
|
41
|
+
if !File.exists?(File.expand_path(role_path))
|
42
|
+
raise "Role path does not exist!"
|
43
|
+
end
|
44
|
+
::Chef::Config[:role_path] = role_path
|
45
|
+
role = ::Chef::Role.from_disk(role)
|
46
|
+
role.save
|
47
|
+
log("chef-server", "updated role '#{role}' from file '#{role_path}'")
|
48
|
+
end
|
49
|
+
|
50
|
+
################################################################################
|
51
|
+
|
52
|
+
def create_databag(databag)
|
53
|
+
@rest ||= ::Chef::REST.new(Chef::Config[:chef_server_url])
|
54
|
+
@rest.post_rest("data", { "name" => databag })
|
55
|
+
rescue Net::HTTPServerException => e
|
56
|
+
raise unless e.to_s =~ /^409/
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_databag_item(databag_item_path)
|
60
|
+
::Yajl::Parser.parse(IO.read(databag_item_path))
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_databag(databag, databag_path)
|
64
|
+
create_databag(databag)
|
65
|
+
items = Dir.glob(File.expand_path(File.join(databag_path, "*.{json,rb}")))
|
66
|
+
items.each do |item|
|
67
|
+
next if File.directory?(item)
|
68
|
+
|
69
|
+
item_path = File.basename(item)
|
70
|
+
databag_item_path = File.expand_path(File.join(databag_path, item_path))
|
71
|
+
|
72
|
+
data_bag_item = ::Chef::DataBagItem.new
|
73
|
+
data_bag_item.data_bag(databag)
|
74
|
+
data_bag_item.raw_data = load_databag_item(databag_item_path)
|
75
|
+
data_bag_item.save
|
76
|
+
log("chef-server", "updated data bag item '#{databag}/#{item_path}' from file '#{databag_path}'")
|
77
|
+
end
|
78
|
+
|
79
|
+
# TODO fix ghetto sleep
|
80
|
+
# databags don't always update right away; ghetto fix with a sleep
|
81
|
+
# for now. likely needs to loop reading the databag back until it updates
|
82
|
+
# then return
|
83
|
+
sleep(3)
|
84
|
+
end
|
85
|
+
|
86
|
+
################################################################################
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
################################################################################
|