toft-puppet 0.0.9

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.
Files changed (66) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +62 -0
  3. data/Rakefile +121 -0
  4. data/features/checker.feature +14 -0
  5. data/features/chef.feature +70 -0
  6. data/features/command.feature +20 -0
  7. data/features/node.feature +41 -0
  8. data/features/puppet.feature +40 -0
  9. data/features/step_definitions/centos/checks.rb +9 -0
  10. data/features/step_definitions/checker.rb +15 -0
  11. data/features/step_definitions/chef.rb +43 -0
  12. data/features/step_definitions/command.rb +28 -0
  13. data/features/step_definitions/node.rb +65 -0
  14. data/features/step_definitions/puppet.rb +7 -0
  15. data/features/support/env.rb +25 -0
  16. data/fixtures/chef/attributes.json +9 -0
  17. data/fixtures/chef/cookbooks/test/attributes/default.rb +4 -0
  18. data/fixtures/chef/cookbooks/test/recipes/attribute.rb +19 -0
  19. data/fixtures/chef/cookbooks/test/recipes/default.rb +4 -0
  20. data/fixtures/chef/cookbooks/test/recipes/role.rb +4 -0
  21. data/fixtures/chef/roles/test.rb +3 -0
  22. data/fixtures/puppet/conf/fileserver.conf +3 -0
  23. data/fixtures/puppet/conf/puppet.conf +15 -0
  24. data/fixtures/puppet/conf/puppet_exec.conf +9 -0
  25. data/fixtures/puppet/conf/puppet_fileserver.conf +8 -0
  26. data/fixtures/puppet/conf/puppet_modules.conf +7 -0
  27. data/fixtures/puppet/conf/puppet_template.conf +8 -0
  28. data/fixtures/puppet/manifests/fileserver/conf/test_fileserver +1 -0
  29. data/fixtures/puppet/manifests/nodes/test_node.pp +26 -0
  30. data/fixtures/puppet/manifests/site.pp +1 -0
  31. data/fixtures/puppet/manifests/templates/template_test +2 -0
  32. data/fixtures/puppet/manifests/test.pp +8 -0
  33. data/fixtures/puppet/manifests/test_fileserver.pp +14 -0
  34. data/fixtures/puppet/manifests/test_install.pp +5 -0
  35. data/fixtures/puppet/manifests/test_module.pp +5 -0
  36. data/fixtures/puppet/manifests/test_service.pp +11 -0
  37. data/fixtures/puppet/manifests/test_template.pp +12 -0
  38. data/fixtures/puppet/modules/test_module/manifests/init.pp +8 -0
  39. data/lib/toft.rb +39 -0
  40. data/lib/toft/chef/chef_attributes.rb +29 -0
  41. data/lib/toft/chef/chef_runner.rb +77 -0
  42. data/lib/toft/command_executor.rb +16 -0
  43. data/lib/toft/file_checker.rb +47 -0
  44. data/lib/toft/node.rb +243 -0
  45. data/lib/toft/node_controller.rb +32 -0
  46. data/lib/toft/puppet/puppet_runner.rb +38 -0
  47. data/lib/toft/version.rb +3 -0
  48. data/scripts/bin/centos/lxc-prepare-host +172 -0
  49. data/scripts/bin/centos/provision_vagrant +11 -0
  50. data/scripts/bin/share/install-chef-ubuntu.sh +19 -0
  51. data/scripts/bin/share/lxc-create-centos-image +60 -0
  52. data/scripts/bin/ubuntu/lxc-create-ubuntu-image +77 -0
  53. data/scripts/bin/ubuntu/lxc-prepare-host +199 -0
  54. data/scripts/bin/ubuntu/provision_vagrant +9 -0
  55. data/scripts/lxc-templates/files/rc.local +38 -0
  56. data/scripts/lxc-templates/lxc-centos-6 +279 -0
  57. data/scripts/lxc-templates/lxc-lenny +255 -0
  58. data/scripts/lxc-templates/lxc-lucid +313 -0
  59. data/scripts/lxc-templates/lxc-natty +237 -0
  60. data/spec/fixtures/illegal_syntax.json +1 -0
  61. data/spec/spec_helper.rb +6 -0
  62. data/spec/toft/chef/chef_attributes_spec.rb +39 -0
  63. data/spec/toft/chef/chef_runner_spec.rb +34 -0
  64. data/spec/toft/node_spec.rb +18 -0
  65. data/spec/toft/puppet/puppet_runner_spec.rb +26 -0
  66. metadata +234 -0
@@ -0,0 +1,28 @@
1
+ Then /^Running ssh command "([^"]*)" on "([^"]*)" should succeed$/ do |cmd, node|
2
+ lambda { find(node).run_ssh(cmd) }.should_not raise_error
3
+ end
4
+
5
+ Then /^Running ssh command "([^"]*)" on "([^"]*)" should fail$/ do |cmd, node|
6
+ lambda { find(node).run_ssh(cmd) }.should raise_error
7
+ end
8
+
9
+ Then /^Rm "([^"]*)" on "([^"]*)" should fail$/ do |dir, node|
10
+ lambda { find(node).rm(dir) }.should raise_error
11
+ end
12
+
13
+ Then /^Rm "([^"]*)" on "([^"]*)" should succeed$/ do |dir, node|
14
+ lambda { find(node).rm(dir) }.should_not raise_error
15
+ end
16
+
17
+ Then /^the result of running ssh command "([^"]*)" on "([^"]*)" should contain "([^"]*)"$/ do |cmd, node, s|
18
+ r = find(node).run_ssh(cmd)
19
+ r.stdout.should include(s)
20
+ end
21
+
22
+ Then /^the result of running ssh command "([^"]*)" on "([^"]*)" should fail because of "([^"]*)"$/ do |cmd, node, s|
23
+ begin
24
+ r = find(node).run_ssh(cmd)
25
+ rescue CommandExecutionError => e
26
+ e.stdout.should include(s)
27
+ end
28
+ end
@@ -0,0 +1,65 @@
1
+ Given /^I have a clean running node n1$/ do
2
+ @n1.start
3
+ @n1.rm "/tmp/stub"
4
+ end
5
+
6
+ When /^I add another node "([^"]*)" with ip "([^"]*)"$/ do |node, ip|
7
+ create_node node, {:ip => ip, :type => CONTAINER_TYPE}
8
+ end
9
+
10
+ When /^I add another node "([^"]*)"$/ do |node|
11
+ n = create_node node, {:type => CONTAINER_TYPE}
12
+ n.start
13
+ end
14
+
15
+ When /^I destroy node "([^"]*)"$/ do |node|
16
+ destroy_node node
17
+ end
18
+
19
+ When /^Node "([^"]*)" is destroyed$/ do |node|
20
+ find(node).destroy
21
+ end
22
+
23
+ Then /^There should be ([^"]*) nodes in the environment$/ do |count|
24
+ find(:all).size.should == count.to_i
25
+ end
26
+
27
+ Then /^the node "([^"]*)" should be stopped$/ do |node|
28
+ find(node).should_not be_running
29
+ end
30
+
31
+ When /^I start node "([^"]*)"$/ do |node|
32
+ find(node).start
33
+ end
34
+
35
+ When /^I stop node "([^"]*)"$/ do |node|
36
+ find(node).stop
37
+ end
38
+
39
+ Then /^the node "([^"]*)" should be running$/ do |node|
40
+ find(node).should be_running
41
+ end
42
+
43
+ Then /^Node "([^"]*)" should have ip address same with that obtained from inside it through ssh$/ do |node|
44
+ n = find(node)
45
+ n.run_ssh("ifconfig eth0 | grep 'inet addr:'").stdout.should include(n.ip)
46
+ end
47
+
48
+ When /^I add cname "([^"]*)" to "([^"]*)"$/ do |cname, node|
49
+ find(node).add_cname cname
50
+ end
51
+
52
+ When /^I remove cname "([^"]*)" from "([^"]*)"$/ do |cname, node|
53
+ find(node).remove_cname cname
54
+ end
55
+
56
+ When /^I change the internal hostname for "([^"]*)" to "([^"]*)"$/ do |node_hostname, internal_hostname|
57
+ r = find(node_hostname)
58
+ r.run_ssh("hostname #{internal_hostname}")
59
+ r.run_ssh("echo 127.0.0.1 #{internal_hostname} >> /etc/hosts")
60
+ end
61
+
62
+
63
+ Then /^Hostname of Node "([^"]*)" should match its name$/ do |node|
64
+ find(node).hostname.should == node
65
+ end
@@ -0,0 +1,7 @@
1
+ When /^I run puppet manifest "([^"]*)" on node "([^"]*)"$/ do |run_list, node|
2
+ find(node).run_puppet run_list
3
+ end
4
+
5
+ When /^I run puppet manifest "([^"]*)" with config file "([^"]*)" on node "([^"]*)"$/ do |run_list, conf_file, node|
6
+ find(node).run_puppet(run_list, :conf_file => conf_file)
7
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'rspec/expectations'
3
+ require 'toft'
4
+
5
+ CHEF_FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/chef'
6
+ PUPPET_FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/puppet'
7
+
8
+ CONTAINER_TYPE = "centos-6"
9
+
10
+ World(Toft)
11
+
12
+ include Toft
13
+ n1 = create_node "n1", {:ip => "192.168.20.2", :type => CONTAINER_TYPE}
14
+
15
+ Before do
16
+ Toft.cookbook_path = CHEF_FIXTURE_PATH + '/cookbooks'
17
+ Toft.role_path = CHEF_FIXTURE_PATH + '/roles'
18
+ Toft.manifest_path = PUPPET_FIXTURE_PATH
19
+
20
+ @n1 = n1
21
+ end
22
+
23
+ at_exit do
24
+ n1.destroy
25
+ end
@@ -0,0 +1,9 @@
1
+ {
2
+ "one" : "one",
3
+ "two" :
4
+ {
5
+ "one" : "two_one",
6
+ "two" : "two_two"
7
+ },
8
+ "three" : "three"
9
+ }
@@ -0,0 +1,4 @@
1
+ default[:one] = "test"
2
+ default[:three] = "test"
3
+ default[:two][:one] = "test"
4
+ default[:two][:two] = "test"
@@ -0,0 +1,19 @@
1
+ directory "/tmp/stub/#{node.one}" do
2
+ action :create
3
+ recursive true
4
+ end
5
+
6
+ directory "/tmp/stub/#{node.two.two}" do
7
+ action :create
8
+ recursive true
9
+ end
10
+
11
+ directory "/tmp/stub/#{node.two.one}" do
12
+ action :create
13
+ recursive true
14
+ end
15
+
16
+ directory "/tmp/stub/#{node.three}" do
17
+ action :create
18
+ recursive true
19
+ end
@@ -0,0 +1,4 @@
1
+ directory "/tmp/stub/dir" do
2
+ action :create
3
+ recursive true
4
+ end
@@ -0,0 +1,4 @@
1
+ directory "/tmp/stub/role" do
2
+ action :create
3
+ recursive true
4
+ end
@@ -0,0 +1,3 @@
1
+ name 'test'
2
+ description 'Test!'
3
+ run_list "recipe[test::role]"
@@ -0,0 +1,3 @@
1
+ [conf]
2
+ path /tmp/toft-puppet-tmp/manifests/fileserver/conf
3
+ allow *
@@ -0,0 +1,15 @@
1
+ [main]
2
+ modulepath = /tmp/puppet/modules
3
+ templatedir = /tmp/puppet/manifests/templates
4
+ node_terminus = exec
5
+ external_nodes = /tmp/puppet/tools/extnode.pl
6
+ fileserverconfig = /tmp/puppet/conf/fileserver.conf
7
+ logdir = /var/log/puppet
8
+ vardir = /var/lib/puppet
9
+ ssldir = /var/lib/puppet/ssl
10
+ rundir = /var/run/puppet
11
+ report = true
12
+ server = puppet.dev.int.realestate.com.au
13
+ reportserver = puppet.dev.int.realestate.com.au
14
+ diff = diff
15
+ diff_args = -u
@@ -0,0 +1,9 @@
1
+ [main]
2
+ node_terminus = exec
3
+ external_nodes = /tmp/puppet/tools/extnode.pl
4
+
5
+ logdir = /var/log/puppet
6
+ vardir = /var/lib/puppet
7
+ ssldir = /var/lib/puppet/ssl
8
+ rundir = /var/run/puppet
9
+ report = true
@@ -0,0 +1,8 @@
1
+ [main]
2
+ fileserverconfig = /tmp/toft-puppet-tmp/conf/fileserver.conf
3
+
4
+ logdir = /var/log/puppet
5
+ vardir = /var/lib/puppet
6
+ ssldir = /var/lib/puppet/ssl
7
+ rundir = /var/run/puppet
8
+ report = true
@@ -0,0 +1,7 @@
1
+ [main]
2
+ modulepath = /tmp/toft-puppet-tmp/modules
3
+
4
+ logdir = /var/log/puppet
5
+ vardir = /var/lib/puppet
6
+ ssldir = /var/lib/puppet/ssl
7
+ rundir = /var/run/puppet
@@ -0,0 +1,8 @@
1
+ [main]
2
+ templatedir = /tmp/toft-puppet-tmp/manifests/templates
3
+
4
+ logdir = /var/log/puppet
5
+ vardir = /var/lib/puppet
6
+ ssldir = /var/lib/puppet/ssl
7
+ rundir = /var/run/puppet
8
+ report = true
@@ -0,0 +1 @@
1
+ This is a test for the fileserver config
@@ -0,0 +1,26 @@
1
+ node /^correct.*/ inherits default_node {
2
+
3
+ file { "/tmp/puppet_test_correct":
4
+ ensure => present,
5
+ mode => '0666',
6
+ }
7
+
8
+ }
9
+
10
+ node /^incorrect.*/ inherits default_node {
11
+
12
+ file { "/tmp/puppet_test_incorrect":
13
+ ensure => present,
14
+ mode => '0666',
15
+ }
16
+
17
+ }
18
+
19
+ node default_node {
20
+
21
+ file { "/tmp/puppet_test_default":
22
+ ensure => present,
23
+ mode => '0666',
24
+ }
25
+
26
+ }
@@ -0,0 +1 @@
1
+ import "nodes/*.pp"
@@ -0,0 +1,2 @@
1
+ This is a test for the template config
2
+ Here is the variable <%= variable %>
@@ -0,0 +1,8 @@
1
+ class { 'test': }
2
+
3
+ class test {
4
+ file { "/tmp/puppet_test":
5
+ ensure => present,
6
+ mode => '0666',
7
+ }
8
+ }
@@ -0,0 +1,14 @@
1
+ class { 'test': }
2
+
3
+ class test {
4
+ file { "test_fileserver":
5
+ path => "/tmp/puppet_test_fileserver",
6
+ owner => "root",
7
+ group => "root",
8
+ mode => 0440,
9
+ source => "puppet:///conf/test_fileserver",
10
+ }
11
+ }
12
+
13
+
14
+
@@ -0,0 +1,5 @@
1
+ class { 'test': }
2
+
3
+ class test {
4
+ package { "zip": ensure => installed }
5
+ }
@@ -0,0 +1,5 @@
1
+ class { 'test': }
2
+
3
+ class test {
4
+ include test_module
5
+ }
@@ -0,0 +1,11 @@
1
+ class { 'test': }
2
+
3
+ class test {
4
+ package { "bind": ensure => installed }
5
+
6
+ service { "named":
7
+ enable => true,
8
+ ensure => running,
9
+ require => Package["bind"],
10
+ }
11
+ }
@@ -0,0 +1,12 @@
1
+ class { 'test': }
2
+
3
+ class test {
4
+
5
+ $variable = "BLAH"
6
+
7
+ file { "/tmp/puppet_test_template":
8
+ ensure => present,
9
+ mode => '0666',
10
+ content => template(template_test)
11
+ }
12
+ }
@@ -0,0 +1,8 @@
1
+ class test_module {
2
+
3
+ file { "/tmp/puppet_test_module":
4
+ ensure => present,
5
+ mode => '0666',
6
+ }
7
+
8
+ }
data/lib/toft.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'toft/node_controller'
2
+ require 'toft/file_checker'
3
+ require 'toft/chef/chef_attributes'
4
+ require 'toft/chef/chef_runner'
5
+ require 'toft/puppet/puppet_runner'
6
+
7
+ module Toft
8
+ DYNAMIC_IP = "0.0.0.0"
9
+ DOMAIN = "foo"
10
+
11
+ class << self
12
+ attr_accessor :manifest_path, :cookbook_path, :role_path
13
+ end
14
+
15
+ def create_node(hostname, options = {})
16
+ NodeController.instance.create_node(hostname, options)
17
+ end
18
+
19
+ def find(name)
20
+ return NodeController.instance.nodes if name === :all
21
+ NodeController.instance.nodes[name] if name.is_a? String
22
+ end
23
+
24
+ def destroy_node(hostname)
25
+ NodeController.instance.destroy_node(hostname)
26
+ end
27
+ end
28
+
29
+ class NilClass
30
+ def blank?
31
+ true
32
+ end
33
+ end
34
+
35
+ class String
36
+ def blank?
37
+ empty?
38
+ end
39
+ end
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+
3
+ module Toft
4
+ class ChefAttributes
5
+ attr_reader :attributes
6
+
7
+ def initialize(cuke_ast_table = nil)
8
+ @attributes = {}
9
+ cuke_ast_table.hashes.each do |row|
10
+ add_attribute row[:key], row[:value]
11
+ end unless cuke_ast_table.nil?
12
+ end
13
+
14
+ def add_attribute(key, value)
15
+ stat = "attributes"
16
+ head = attributes
17
+ key.split(".").each do |k|
18
+ head[k] ||= Hash.new
19
+ head = head[k]
20
+ stat += "[\"#{k}\"]"
21
+ end
22
+ eval "#{stat}=\"#{value}\""
23
+ end
24
+
25
+ def to_json
26
+ attributes.to_json
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,77 @@
1
+ require 'toft/chef/chef_attributes'
2
+ require 'fileutils'
3
+
4
+ module Toft
5
+ module Chef
6
+ class ChefRunner
7
+ include FileUtils
8
+
9
+ DEST_CHEF_TMP = "/tmp/toft-chef-tmp"
10
+ DEST_COOKBOOK_PATH = "#{DEST_CHEF_TMP}/cookbooks"
11
+ DEST_ROLE_PATH = "#{DEST_CHEF_TMP}/roles"
12
+ DEST_CHEF_SOLO_PATH = "#{DEST_CHEF_TMP}/solo.rb"
13
+ DEST_CHEF_JSON_PATH = "#{DEST_CHEF_TMP}/solo.json"
14
+
15
+ def initialize(root_dir, &command_runner)
16
+ @root_dir = root_dir
17
+ @command_runner = command_runner
18
+ end
19
+
20
+ def run(run_list, params = {})
21
+ override_attributes_hash = parse_attributes params[:json], params[:attributes]
22
+ copy_chef_material
23
+ generate_solo_rb
24
+ generate_json ([] << run_list).flatten, override_attributes_hash
25
+ @command_runner.call "chef-solo -c #{DEST_CHEF_SOLO_PATH} -j #{DEST_CHEF_JSON_PATH}"
26
+ end
27
+
28
+ private
29
+ def parse_attributes(json_file_path, chef_attributes)
30
+ chef_attributes = chef_attributes || ChefAttributes.new
31
+ chef_attributes_from_json ||= {}
32
+ chef_attributes_from_json = read_json_file json_file_path unless json_file_path.blank?
33
+ chef_attributes_from_json.merge chef_attributes.attributes
34
+ end
35
+
36
+ def read_json_file(json_file_path)
37
+ JSON.parse(File.read(json_file_path))
38
+ end
39
+
40
+ def copy_chef_material
41
+ raise ArgumentError, "Toft.cookbook_path can not be empty!" if Toft.cookbook_path.blank?
42
+ rm_rf "#{@root_dir}#{DEST_CHEF_TMP}"
43
+ mkdir_p "#{@root_dir}#{DEST_CHEF_TMP}"
44
+ cp_r Toft.cookbook_path, "#{@root_dir}#{DEST_COOKBOOK_PATH}"
45
+ cp_r Toft.role_path, "#{@root_dir}#{DEST_ROLE_PATH}" unless roles_missing?
46
+ end
47
+
48
+ def roles_missing?
49
+ Toft.role_path.blank?
50
+ end
51
+
52
+ def generate_solo_rb
53
+ solo = <<-EOF
54
+ file_cache_path "/tmp/chef-file-cache"
55
+ cookbook_path ["#{DEST_COOKBOOK_PATH}"]
56
+ EOF
57
+ solo += "role_path [\"#{DEST_ROLE_PATH}\"]" unless roles_missing?
58
+
59
+ File.open("#{@root_dir}#{DEST_CHEF_SOLO_PATH}", 'w') do |f|
60
+ f.write(solo);
61
+ end
62
+ end
63
+
64
+ def generate_json(run_list, override_attributes_hash)
65
+ run_list = {"run_list" => run_list}
66
+ run_list.merge!(override_attributes_hash)
67
+ File.open("#{@root_dir}#{DEST_CHEF_JSON_PATH}", 'w') do |f|
68
+ f.write(run_list.to_json);
69
+ end
70
+ end
71
+
72
+ def cmd(cmd)
73
+ raise "Command execution failed: [#{cmd}]" unless system cmd
74
+ end
75
+ end
76
+ end
77
+ end