vagrant-chef-zero 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +5 -0
  2. data/.travis.yml +8 -0
  3. data/CHANGELOG.md +37 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE.txt +18 -0
  6. data/Makefile +15 -0
  7. data/README.md +68 -0
  8. data/Rakefile +31 -0
  9. data/Vagrantfile +17 -0
  10. data/coverage/.last_run.json +5 -0
  11. data/coverage/.resultset.json +125 -0
  12. data/lib/vagrant-chef-zero/action/default.rb +1 -0
  13. data/lib/vagrant-chef-zero/action/reconfig.rb +38 -0
  14. data/lib/vagrant-chef-zero/action/start.rb +28 -0
  15. data/lib/vagrant-chef-zero/action/stop.rb +27 -0
  16. data/lib/vagrant-chef-zero/action/upload.rb +154 -0
  17. data/lib/vagrant-chef-zero/action.rb +43 -0
  18. data/lib/vagrant-chef-zero/config.rb +61 -0
  19. data/lib/vagrant-chef-zero/env.rb +15 -0
  20. data/lib/vagrant-chef-zero/env_helpers.rb +105 -0
  21. data/lib/vagrant-chef-zero/plugin.rb +53 -0
  22. data/lib/vagrant-chef-zero/server_helpers.rb +44 -0
  23. data/lib/vagrant-chef-zero/version.rb +5 -0
  24. data/lib/vagrant-chef-zero.rb +15 -0
  25. data/spec/lib/server_helpers_spec.rb +65 -0
  26. data/spec/spec_helper.rb +21 -0
  27. data/spec/vagrant-chef-zero/fixtures/cookbooks/blah/metadata.rb +3 -0
  28. data/spec/vagrant-chef-zero/fixtures/cookbooks/blah/recipes/default.rb +1 -0
  29. data/spec/vagrant-chef-zero/fixtures/cookbooks/blah/templates/default/hi +1 -0
  30. data/spec/vagrant-chef-zero/fixtures/cookbooks/blork/recipes/default.rb +1 -0
  31. data/spec/vagrant-chef-zero/fixtures/cookbooks/blork/templates/default/hi +1 -0
  32. data/spec/vagrant-chef-zero/fixtures/data_bags/foo/bar.json +1 -0
  33. data/spec/vagrant-chef-zero/fixtures/data_bags/foo/baz.json +1 -0
  34. data/spec/vagrant-chef-zero/fixtures/data_bags/foo/blarghle.json +1 -0
  35. data/spec/vagrant-chef-zero/fixtures/data_bags/foom/x.json +5 -0
  36. data/spec/vagrant-chef-zero/fixtures/data_bags/widdle/blank.json +1 -0
  37. data/spec/vagrant-chef-zero/fixtures/data_bags/widdle/wow.json +1 -0
  38. data/spec/vagrant-chef-zero/fixtures/environments/desert.json +13 -0
  39. data/spec/vagrant-chef-zero/fixtures/environments/rainforest.json +13 -0
  40. data/spec/vagrant-chef-zero/fixtures/environments/semi_arid_plains.json +13 -0
  41. data/spec/vagrant-chef-zero/fixtures/nodes/blah.json +7 -0
  42. data/spec/vagrant-chef-zero/fixtures/nodes/blarrrrgh.json +7 -0
  43. data/spec/vagrant-chef-zero/fixtures/nodes/boxer.json +7 -0
  44. data/spec/vagrant-chef-zero/fixtures/nodes/camel.json +7 -0
  45. data/spec/vagrant-chef-zero/fixtures/nodes/monkey.json +7 -0
  46. data/vagrant-chef-zero.gemspec +74 -0
  47. metadata +292 -0
@@ -0,0 +1,61 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module ChefZero
5
+ class Config < Vagrant.plugin("2", :config)
6
+ # Path to role fixtures
7
+ #
8
+ # @return [String]
9
+ attr_accessor :roles
10
+
11
+ # Path to environment fixtures
12
+ #
13
+ # @return [String]
14
+ attr_accessor :environments
15
+
16
+ # Path to node fixtures
17
+ #
18
+ # @return [String]
19
+ attr_accessor :nodes
20
+
21
+ # Path to cookbooks
22
+ #
23
+ # @return [String]
24
+ attr_accessor :cookbooks
25
+
26
+ # Path to data bag fixtures
27
+ #
28
+ # @return [String]
29
+ attr_accessor :data_bags
30
+
31
+ # Is the plugin enabled?
32
+ #
33
+ # @return [TrueClass, FalseClass]
34
+ attr_accessor :enabled
35
+
36
+ def initialize
37
+ @roles = UNSET_VALUE
38
+ @environments = UNSET_VALUE
39
+ @nodes = UNSET_VALUE
40
+ @cookbooks = UNSET_VALUE
41
+ @data_bags = UNSET_VALUE
42
+ @enabled = UNSET_VALUE
43
+ end
44
+
45
+ def validate(machine)
46
+ { "Chef Zero" => [] }
47
+ end
48
+
49
+ def finalize!
50
+ @enabled = true if @enabled == UNSET_VALUE
51
+ @roles = nil if @roles == UNSET_VALUE
52
+ @environments = nil if @environments == UNSET_VALUE
53
+ @nodes = nil if @nodes == UNSET_VALUE
54
+ @cookbooks = nil if @cookbooks == UNSET_VALUE
55
+ @data_bags = nil if @data_bags == UNSET_VALUE
56
+ {}
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,15 @@
1
+ module VagrantPlugins
2
+ module ChefZero
3
+ # @author Jamie Winsor <reset@riotgames.com>
4
+ #
5
+ # Environment data to build up and persist through the middleware chain
6
+ class Env
7
+ # @return [Vagrant::UI::Colored]
8
+ attr_accessor :ui
9
+
10
+ def initialize
11
+ @ui = ::Vagrant::UI::Colored.new.scope('Chef Zero')
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,105 @@
1
+ module VagrantPlugins
2
+ module ChefZero
3
+ module EnvHelpers
4
+
5
+ def server_info(env)
6
+ dict = { host: nil, client_name: nil, client_key: nil }
7
+ provisioners(:chef_client, env).each do |provisioner|
8
+ host = provisioner.config.chef_server_url ||= nil
9
+ client_name = provisioner.config.validation_client_name ||= nil
10
+ client_key = provisioner.config.validation_key_path ||= nil
11
+ dict = { host: host, client_name: client_name, client_key: client_key }
12
+ end
13
+ dict
14
+ end
15
+
16
+ def set_config(config_field, new_value, env)
17
+ provisioners(:chef_client, env).each do |provisioner|
18
+ provisioner.config.instance_variable_set(config_field, new_value)
19
+ end
20
+ end
21
+
22
+ def provisioners(name, env)
23
+ env[:machine].config.vm.provisioners.select { |prov| prov.name == name }
24
+ end
25
+
26
+ def get_validation_client_name(env)
27
+ current_client_name = server_info(env)[:client_name]
28
+ if ! current_client_name || current_client_name.empty?
29
+ current_client_name = "dummy-validator"
30
+ end
31
+ current_client_name
32
+ end
33
+
34
+ def get_chef_server_url(env)
35
+ current_chef_server_url = server_info(env)[:host]
36
+ if ! current_chef_server_url || current_chef_server_url.empty?
37
+ require 'socket'
38
+ ip_address = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}.ip_address
39
+ current_chef_server_url = "http://#{ip_address}:4000"
40
+ end
41
+ current_chef_server_url
42
+ end
43
+
44
+ def get_key_path(env)
45
+ current_key_path = server_info(env)[:client_key]
46
+ if ! current_key_path || ! ::File.exists?(current_key_path)
47
+ current_key_path = get_fake_key_path
48
+ end
49
+ current_key_path
50
+ end
51
+
52
+ def get_fake_key_path
53
+ require 'openssl'
54
+ require 'tmpdir'
55
+ fake_key = OpenSSL::PKey::RSA.new(2048)
56
+ fake_directory = File.join(Dir.tmpdir, "fake_key")
57
+ fake_key_path = File.join(fake_directory, "fake.pem")
58
+ Dir.mkdir(fake_directory) unless File.exists?(fake_directory)
59
+ File.open(fake_key_path,"w") {|f| f.puts fake_key } unless File.exists?(fake_key_path)
60
+ fake_key_path
61
+ end
62
+
63
+ def get_host(env)
64
+ url = server_info(env)[:host]
65
+ if url
66
+ # Some terrible string manipulation to get the ip
67
+ return url.split('//').last.split(':').first
68
+ end
69
+ end
70
+
71
+ def get_port(env)
72
+ url = server_info(env)[:host]
73
+ # Same with the port
74
+ if url
75
+ p = url.split(':').last
76
+ if p && p != ""
77
+ port = p
78
+ end
79
+ else
80
+ port = "4000"
81
+ end
82
+ port
83
+ end
84
+
85
+ def chef_client?(env)
86
+ provisioners(:chef_client, env).any?
87
+ end
88
+
89
+ def chef_zero_enabled?(env)
90
+ env[:global_config].chef_zero.enabled && chef_client?(env)
91
+ end
92
+
93
+ def berkshelf_enabled?(env)
94
+ env[:global_config].berkshelf.enabled == true && chef_client?(env)
95
+ end
96
+
97
+ def set_berkshelf_client_key(value)
98
+ ObjectSpace.each_object(Berkshelf::Config).each do |o|
99
+ o.chef.client_key = value
100
+ end
101
+ end
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,53 @@
1
+ require 'ridley'
2
+
3
+ # This is a sanity check to make sure no one is attempting to install
4
+ # this into an early Vagrant version.
5
+ if Vagrant::VERSION < "1.2.0"
6
+ raise "The Vagrant Chef Zero plugin is only compatible with Vagrant 1.2+"
7
+ end
8
+
9
+ module VagrantPlugins
10
+ module ChefZero
11
+ class Plugin < Vagrant.plugin("2")
12
+
13
+ class << self
14
+ def reconfig(hook)
15
+ hook.before(::Vagrant::Action::Builtin::ConfigValidate, VagrantPlugins::ChefZero::Action.chef_zero_ui_setup)
16
+ hook.before(::Vagrant::Action::Builtin::ConfigValidate, VagrantPlugins::ChefZero::Action.chef_zero_reconfig)
17
+ end
18
+
19
+ def provision(hook)
20
+ hook.before(::Vagrant::Action::Builtin::Provision, VagrantPlugins::ChefZero::Action.chef_zero_provision)
21
+ end
22
+
23
+ def destroy(hook)
24
+ hook.after(VagrantPlugins::ProviderVirtualBox::Action::DestroyUnusedNetworkInterfaces, VagrantPlugins::ChefZero::Action.chef_zero_destroy)
25
+ end
26
+
27
+ end
28
+
29
+ name "chef_zero"
30
+ description <<-DESC
31
+ This plugin adds configuration options to allow Vagrant to interact with
32
+ Chef Zero
33
+ DESC
34
+
35
+ # Deep magic of not binding to any specific action.. so we can bind to them all
36
+ action_hook(:chef_zero_reconfig, &method(:reconfig))
37
+
38
+ action_hook(:chef_zero_up, :machine_action_up, &method(:provision))
39
+
40
+ action_hook(:chef_zero_provision, :machine_action_provision, &method(:provision))
41
+
42
+ action_hook(:chef_zero_provision, :machine_action_reload, &method(:provision))
43
+
44
+ action_hook(:chef_zero_destroy, :machine_action_destroy, &method(:destroy))
45
+
46
+ config(:chef_zero) do
47
+ require_relative "config"
48
+ Config
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,44 @@
1
+ module VagrantPlugins
2
+ module ChefZero
3
+ module ServerHelpers
4
+
5
+ def start_chef_zero(env)
6
+ port = get_port(env)
7
+ host = get_host(env)
8
+ if ! chef_zero_server_running?(port)
9
+ vagrant_gems = ENV['GEM_PATH'].split(':').select { |gp| gp.include?('vagrant.d')}.first
10
+ chef_zero_binary = ::File.join(vagrant_gems, "bin", "chef-zero")
11
+ proc = IO.popen("#{chef_zero_binary} --host #{host} --port #{port} 2>&1 > /dev/null")
12
+ env[:chef_zero].ui.info("Starting Chef Zero at http://#{host}:#{port}")
13
+ end
14
+ while ! chef_zero_server_running?(port)
15
+ sleep 1
16
+ env[:chef_zero].ui.warn("Waiting for Chef Zero to start")
17
+ end
18
+ end
19
+
20
+ def stop_chef_zero(env)
21
+ port = get_port(env)
22
+ if chef_zero_server_running?(port)
23
+ pid = get_chef_zero_server_pid(port)
24
+ env[:chef_zero].ui.info("Stopping Chef Zero")
25
+ system("kill #{pid}")
26
+ end
27
+ end
28
+
29
+ def chef_zero_server_running?(port)
30
+ pid = get_chef_zero_server_pid(port)
31
+ !! pid
32
+ end
33
+
34
+ def get_chef_zero_server_pid(port)
35
+ pid = %x[ lsof -i tcp:#{port} | grep -E 'ruby|chef-zero' | awk '{print $2}' ]
36
+ if pid && pid != ""
37
+ return pid
38
+ end
39
+ return nil
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module ChefZero
3
+ VERSION = "0.2.10"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant Chef-Zero plugin must be run within Vagrant."
5
+ end
6
+
7
+ module VagrantPlugins
8
+ module ChefZero
9
+ autoload :Env, 'vagrant-chef-zero/env'
10
+ autoload :Action, 'vagrant-chef-zero/action'
11
+ autoload :Config, 'vagrant-chef-zero/config'
12
+ end
13
+ end
14
+
15
+ require "vagrant-chef-zero/plugin"
@@ -0,0 +1,65 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe 'VagrantPlugins::ChefZero::ServerHelpers' do
4
+
5
+ before do
6
+ class DummyClass
7
+ include VagrantPlugins::ChefZero::ServerHelpers
8
+ end
9
+
10
+ @d = DummyClass.new
11
+ end
12
+
13
+ describe "chef_zero_server_running?" do
14
+
15
+ it "should have an chef_zero_server_running method" do
16
+ @d.must_respond_to(:chef_zero_server_running?)
17
+ end
18
+
19
+ describe "server is running" do
20
+
21
+ before do
22
+ @d.stubs(:get_chef_zero_server_pid).returns("bar")
23
+ end
24
+
25
+ it "should show that the server is running" do
26
+ port = "foo"
27
+ @d.chef_zero_server_running?(port).must_equal true
28
+ end
29
+
30
+ end
31
+
32
+ describe "server not running" do
33
+
34
+ before do
35
+ @d.stubs(:get_chef_zero_server_pid).returns(nil)
36
+ end
37
+
38
+ it "should show that the server is running" do
39
+ port = "foo"
40
+ @d.chef_zero_server_running?(port).must_equal false
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ describe "stop_chef_zero" do
48
+
49
+ it "should have an stop_chef_zero method" do
50
+ @d.must_respond_to(:stop_chef_zero)
51
+ end
52
+
53
+ describe "server is running" do
54
+
55
+ before do
56
+ @d.stubs(:chef_zero_server_running?).returns(true)
57
+ @d.stubs(:`).returns
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,21 @@
1
+ require 'simplecov'
2
+ SimpleCov.formatter = SimpleCov::Formatter::SimpleFormatter
3
+ SimpleCov.start
4
+
5
+ require_relative "../lib/vagrant-chef-zero"
6
+ require_relative "../lib/vagrant-chef-zero/server_helpers.rb"
7
+ require_relative "../lib/vagrant-chef-zero.rb"
8
+
9
+ require 'minitest/autorun'
10
+ require 'minitest/spec'
11
+ require 'minitest/mock'
12
+ require 'mocha/setup' # This should be after any minitest requires
13
+ require 'turn'
14
+ require 'json'
15
+
16
+ Turn.config do |c|
17
+ # :outline - turn's original case/test outline mode [default]
18
+ c.format = :outline
19
+ # use humanized test names (works only with :outline format)
20
+ c.natural = true
21
+ end
@@ -0,0 +1,3 @@
1
+ version "1.5.1"
2
+
3
+ depends "blork"
@@ -0,0 +1 @@
1
+ template "/tmp/hii"
@@ -0,0 +1 @@
1
+ helloooooooooo world
@@ -0,0 +1 @@
1
+ template "/tmp/hii"
@@ -0,0 +1 @@
1
+ { "id": "bar" }
@@ -0,0 +1 @@
1
+ { "id": "baz" }
@@ -0,0 +1 @@
1
+ { "id": "blarghle", "name": "sldfkja" }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id": "x",
3
+ "foo": "barr",
4
+ "wow": "ee"
5
+ }
@@ -0,0 +1 @@
1
+ { "id": "blank" }
@@ -0,0 +1 @@
1
+ { "id": "wow" }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "desert",
3
+ "default_attributes": {
4
+ },
5
+ "json_class": "Chef::Environment",
6
+ "description": "This is your just desert",
7
+ "cookbook_versions": {
8
+ "bork": "> 2.0"
9
+ },
10
+ "override_attributes": {
11
+ },
12
+ "chef_type": "environment"
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "rainforest",
3
+ "description": "Aaaaagh! Save me!",
4
+ "cookbook_versions": {
5
+ },
6
+ "json_class": "Chef::Environment",
7
+ "chef_type": "environment",
8
+ "default_attributes": {
9
+ "a": "b"
10
+ },
11
+ "override_attributes": {
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "semi_arid_plains",
3
+ "description": "The plains, they are so arid",
4
+ "cookbook_versions": {
5
+ },
6
+ "json_class": "Chef::Environment",
7
+ "chef_type": "environment",
8
+ "default_attributes": {
9
+ "derp": true
10
+ },
11
+ "override_attributes": {
12
+ }
13
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "chef_type": "node",
3
+ "json_class": "Chef::Node",
4
+ "name": "blah",
5
+ "chef_environment": "_default",
6
+ "run_list": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "chef_type": "node",
3
+ "json_class": "Chef::Node",
4
+ "name": "blarrrrgh",
5
+ "chef_environment": "_default",
6
+ "run_list": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "chef_type": "node",
3
+ "json_class": "Chef::Node",
4
+ "name": "boxer",
5
+ "chef_environment": "_default",
6
+ "run_list": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "chef_type": "node",
3
+ "json_class": "Chef::Node",
4
+ "name": "camel",
5
+ "chef_environment": "desert",
6
+ "run_list": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "chef_type": "node",
3
+ "json_class": "Chef::Node",
4
+ "name": "monkey",
5
+ "chef_environment": "rainforest",
6
+ "run_list": []
7
+ }
@@ -0,0 +1,74 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "vagrant-chef-zero/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "vagrant-chef-zero"
6
+ s.version = VagrantPlugins::ChefZero::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = "Andrew Gross"
9
+ s.email = "andrew.w.gross@gmail.com"
10
+ s.homepage = "http://github.com/andrewgross/vagrant-chef-zero"
11
+ s.summary = "Enables Vagrant to interact with Chef Zero."
12
+ s.description = "Enables Vagrant to interact with Chef Zero"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "vagrant-chef-zero"
16
+ s.license = "MIT"
17
+
18
+ s.add_dependency "chef-zero", "~> 1.3"
19
+ s.add_dependency "ridley", ">= 1.0.0"
20
+
21
+
22
+ # Stolen from Vagrant Berkshelf because Ruby hates dependency resolution
23
+ # activesupport 3.2.13 contains an incompatible hard lock on i18n (= 0.6.1)
24
+ s.add_dependency 'activesupport', '>= 3.2.0', '< 3.2.13'
25
+
26
+ # Explicit locks to ensure we activate the proper gem versions for Vagrant
27
+ s.add_dependency 'i18n', '~> 0.6.0'
28
+ s.add_dependency 'net-ssh', '~> 2.6.6'
29
+ s.add_dependency 'net-scp', '~> 1.1.0'
30
+
31
+ s.add_development_dependency "mocha"
32
+ s.add_development_dependency "simplecov"
33
+ s.add_development_dependency "rake"
34
+ s.add_development_dependency "turn"
35
+ s.add_development_dependency "minitest", '< 5.0'
36
+ s.add_development_dependency "minitest-reporters"
37
+
38
+ # The following block taken from @mitchellh 's vagrant-aws code
39
+
40
+ # The following block of code determines the files that should be included
41
+ # in the gem. It does this by reading all the files in the directory where
42
+ # this gemspec is, and parsing out the ignored files from the gitignore.
43
+ # Note that the entire gitignore(5) syntax is not supported, specifically
44
+ # the "!" syntax, but it should mostly work correctly.
45
+ root_path = File.dirname(__FILE__)
46
+ all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
47
+ all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
48
+ gitignore_path = File.join(root_path, ".gitignore")
49
+ gitignore = File.readlines(gitignore_path)
50
+ gitignore.map! { |line| line.chomp.strip }
51
+ gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
52
+
53
+ unignored_files = all_files.reject do |file|
54
+ # Ignore any directories, the gemspec only cares about files
55
+ next true if File.directory?(file)
56
+
57
+ # Ignore any paths that match anything in the gitignore. We do
58
+ # two tests here:
59
+ #
60
+ # - First, test to see if the entire path matches the gitignore.
61
+ # - Second, match if the basename does, this makes it so that things
62
+ # like '.DS_Store' will match sub-directories too (same behavior
63
+ # as git).
64
+ #
65
+ gitignore.any? do |ignore|
66
+ File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
67
+ File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
68
+ end
69
+ end
70
+
71
+ s.files = unignored_files
72
+ s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
73
+ s.require_path = 'lib'
74
+ end