ridley 0.9.1 → 0.10.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +1 -0
  2. data/.ruby-version +1 -0
  3. data/Guardfile +1 -1
  4. data/README.md +1 -1
  5. data/bootstrappers/{omnibus.erb → unix_omnibus.erb} +20 -5
  6. data/bootstrappers/windows_omnibus.erb +133 -0
  7. data/lib/ridley.rb +4 -1
  8. data/lib/ridley/bootstrap_bindings.rb +5 -0
  9. data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +112 -0
  10. data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +221 -0
  11. data/lib/ridley/bootstrapper.rb +14 -22
  12. data/lib/ridley/bootstrapper/context.rb +53 -162
  13. data/lib/ridley/chef.rb +0 -1
  14. data/lib/ridley/chef/cookbook.rb +0 -9
  15. data/lib/ridley/client.rb +12 -1
  16. data/lib/ridley/errors.rb +1 -0
  17. data/lib/ridley/host_connector.rb +76 -0
  18. data/lib/ridley/{ssh → host_connector}/response.rb +1 -1
  19. data/lib/ridley/{ssh → host_connector}/response_set.rb +11 -11
  20. data/lib/ridley/host_connector/ssh.rb +58 -0
  21. data/lib/ridley/host_connector/ssh/worker.rb +99 -0
  22. data/lib/ridley/host_connector/winrm.rb +55 -0
  23. data/lib/ridley/host_connector/winrm/worker.rb +126 -0
  24. data/lib/ridley/mixin/bootstrap_binding.rb +88 -0
  25. data/lib/ridley/resource.rb +1 -1
  26. data/lib/ridley/resources/client_resource.rb +7 -0
  27. data/lib/ridley/resources/node_resource.rb +9 -4
  28. data/lib/ridley/sandbox_uploader.rb +1 -7
  29. data/lib/ridley/version.rb +1 -1
  30. data/ridley.gemspec +1 -0
  31. data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +102 -0
  32. data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +118 -0
  33. data/spec/unit/ridley/bootstrapper/context_spec.rb +19 -106
  34. data/spec/unit/ridley/bootstrapper_spec.rb +2 -12
  35. data/spec/unit/ridley/client_spec.rb +20 -2
  36. data/spec/unit/ridley/{ssh → host_connector}/response_set_spec.rb +17 -17
  37. data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +15 -0
  38. data/spec/unit/ridley/{ssh_spec.rb → host_connector/ssh_spec.rb} +5 -5
  39. data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +41 -0
  40. data/spec/unit/ridley/host_connector/winrm_spec.rb +47 -0
  41. data/spec/unit/ridley/host_connector_spec.rb +102 -0
  42. data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +56 -0
  43. data/spec/unit/ridley/sandbox_uploader_spec.rb +1 -28
  44. metadata +53 -25
  45. data/.rbenv-version +0 -1
  46. data/lib/ridley/chef/chefignore.rb +0 -76
  47. data/lib/ridley/ssh.rb +0 -56
  48. data/lib/ridley/ssh/worker.rb +0 -87
  49. data/spec/fixtures/chefignore +0 -8
  50. data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
  51. data/spec/unit/ridley/ssh/worker_spec.rb +0 -13
@@ -18,6 +18,8 @@ describe Ridley::Bootstrapper do
18
18
  }
19
19
  end
20
20
 
21
+ before(:each) { Ridley::HostConnector.stub(:best_connector_for).and_return(Ridley::HostConnector::SSH) }
22
+
21
23
  describe "ClassMethods" do
22
24
  subject { Ridley::Bootstrapper }
23
25
 
@@ -50,18 +52,6 @@ describe Ridley::Bootstrapper do
50
52
  end
51
53
  end
52
54
  end
53
-
54
- describe "::templates_path" do
55
- it "returns a pathname" do
56
- subject.templates_path.should be_a(Pathname)
57
- end
58
- end
59
-
60
- describe "::default_template" do
61
- it "returns a string" do
62
- subject.default_template.should be_a(String)
63
- end
64
- end
65
55
  end
66
56
 
67
57
  subject { Ridley::Bootstrapper.new(nodes, options) }
@@ -6,6 +6,9 @@ describe Ridley::Client do
6
6
  let(:client_key) { fixtures_path.join("reset.pem").to_s }
7
7
  let(:organization) { "vialstudios" }
8
8
  let(:encrypted_data_bag_secret_path) { fixtures_path.join("reset.pem").to_s }
9
+ let(:ssh) { {user: "reset", password: "password1", port: "222"} }
10
+ let(:winrm) { {user: "reset", password: "password2", port: "5986"} }
11
+ let(:chef_version) { "10.24.0-01" }
9
12
 
10
13
  let(:config) do
11
14
  {
@@ -13,7 +16,10 @@ describe Ridley::Client do
13
16
  client_name: client_name,
14
17
  client_key: client_key,
15
18
  organization: organization,
16
- encrypted_data_bag_secret_path: encrypted_data_bag_secret_path
19
+ encrypted_data_bag_secret_path: encrypted_data_bag_secret_path,
20
+ ssh: ssh,
21
+ winrm: winrm,
22
+ chef_version: chef_version
17
23
  }
18
24
  end
19
25
 
@@ -28,7 +34,7 @@ describe Ridley::Client do
28
34
  @conn = subject.new(
29
35
  server_url: server_url,
30
36
  client_name: client_name,
31
- client_key: client_key
37
+ client_key: client_key,
32
38
  )
33
39
  end
34
40
 
@@ -108,6 +114,18 @@ describe Ridley::Client do
108
114
 
109
115
  subject.new(config).client_key.should_not == "~/"
110
116
  end
117
+
118
+ it "assigns a 'ssh' attribute from the given 'ssh' option" do
119
+ subject.new(config).ssh.should eql({user: "reset", password: "password1", port: "222"})
120
+ end
121
+
122
+ it "assigns a 'winrm' attribute from the given 'winrm' option" do
123
+ subject.new(config).winrm.should eql({user: "reset", password: "password2", port: "5986"})
124
+ end
125
+
126
+ it "assigns a 'chef_version' attribute from the given 'chef_version' option" do
127
+ subject.new(config).chef_version.should eql("10.24.0-01")
128
+ end
111
129
  end
112
130
 
113
131
  describe "::open" do
@@ -1,15 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Ridley::SSH::ResponseSet do
3
+ describe Ridley::HostConnector::ResponseSet do
4
4
  describe "ClassMethods" do
5
5
  subject { described_class }
6
6
 
7
7
  describe "::merge!" do
8
- let(:target) { Ridley::SSH::ResponseSet.new }
9
- let(:other) { Ridley::SSH::ResponseSet.new }
8
+ let(:target) { Ridley::HostConnector::ResponseSet.new }
9
+ let(:other) { Ridley::HostConnector::ResponseSet.new }
10
10
 
11
11
  before(:each) do
12
- other.add_response(Ridley::SSH::Response.new('host.local'))
12
+ other.add_response(Ridley::HostConnector::Response.new('host.local'))
13
13
  end
14
14
 
15
15
  it "returns the mutated target" do
@@ -26,8 +26,8 @@ describe Ridley::SSH::ResponseSet do
26
26
  describe "#add_response" do
27
27
  it "accepts an array of responses" do
28
28
  responses = [
29
- Ridley::SSH::Response.new("one.riotgames.com"),
30
- Ridley::SSH::Response.new("two.riotgames.com")
29
+ Ridley::HostConnector::Response.new("one.riotgames.com"),
30
+ Ridley::HostConnector::Response.new("two.riotgames.com")
31
31
  ]
32
32
  subject.add_response(responses)
33
33
 
@@ -35,7 +35,7 @@ describe Ridley::SSH::ResponseSet do
35
35
  end
36
36
 
37
37
  it "accepts a single response" do
38
- response = Ridley::SSH::Response.new("one.riotgames.com")
38
+ response = Ridley::HostConnector::Response.new("one.riotgames.com")
39
39
  subject.add_response(response)
40
40
 
41
41
  subject.responses.should have(1).item
@@ -43,7 +43,7 @@ describe Ridley::SSH::ResponseSet do
43
43
  end
44
44
 
45
45
  describe "#responses" do
46
- it "returns an array of Ridley::SSH::Response objects including both failures and successes" do
46
+ it "returns an array of Ridley::HostConnector::Response objects including both failures and successes" do
47
47
  responses = [
48
48
  double('success', error?: false),
49
49
  double('failure', error?: true)
@@ -55,7 +55,7 @@ describe Ridley::SSH::ResponseSet do
55
55
  end
56
56
 
57
57
  describe "#successes" do
58
- it "returns an array of Ridley::SSH::Response objects only including the successes" do
58
+ it "returns an array of Ridley::HostConnector::Response objects only including the successes" do
59
59
  responses = [
60
60
  double('success', error?: false),
61
61
  double('failure', error?: true)
@@ -67,7 +67,7 @@ describe Ridley::SSH::ResponseSet do
67
67
  end
68
68
 
69
69
  describe "#failures" do
70
- it "returns an array of Ridley::SSH::Response objects only including the failures" do
70
+ it "returns an array of Ridley::HostConnector::Response objects only including the failures" do
71
71
  responses = [
72
72
  double('success', error?: false),
73
73
  double('failure', error?: true)
@@ -79,14 +79,14 @@ describe Ridley::SSH::ResponseSet do
79
79
  end
80
80
 
81
81
  describe "#merge" do
82
- let(:target) { Ridley::SSH::ResponseSet.new }
83
- let(:other) { Ridley::SSH::ResponseSet.new }
82
+ let(:target) { Ridley::HostConnector::ResponseSet.new }
83
+ let(:other) { Ridley::HostConnector::ResponseSet.new }
84
84
 
85
85
  before(:each) do
86
- other.add_response(Ridley::SSH::Response.new('host.local'))
86
+ other.add_response(Ridley::HostConnector::Response.new('host.local'))
87
87
  end
88
88
 
89
- it "returns a new Ridley::SSH::ResponseSet object" do
89
+ it "returns a new Ridley::HostConnector::ResponseSet object" do
90
90
  result = target.merge(other)
91
91
 
92
92
  result.should have(1).item
@@ -95,11 +95,11 @@ describe Ridley::SSH::ResponseSet do
95
95
  end
96
96
 
97
97
  describe "#merge!" do
98
- let(:target) { Ridley::SSH::ResponseSet.new }
99
- let(:other) { Ridley::SSH::ResponseSet.new }
98
+ let(:target) { Ridley::HostConnector::ResponseSet.new }
99
+ let(:other) { Ridley::HostConnector::ResponseSet.new }
100
100
 
101
101
  before(:each) do
102
- other.add_response(Ridley::SSH::Response.new('host.local'))
102
+ other.add_response(Ridley::HostConnector::Response.new('host.local'))
103
103
  end
104
104
 
105
105
  it "returns the mutated target" do
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector::SSH::Worker do
4
+ describe "ClassMethods" do
5
+ let(:host) { 'reset.riotgames.com' }
6
+
7
+ subject { described_class }
8
+
9
+ describe "::new" do
10
+ it { subject.new(host, ssh: {sudo: true}).sudo.should be_true }
11
+ it { subject.new(host, ssh: {sudo: false}).sudo.should be_false }
12
+ it { subject.new(host).sudo.should be_false }
13
+ end
14
+ end
15
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Ridley::SSH do
3
+ describe Ridley::HostConnector::SSH do
4
4
  let(:connection) { double('conn', ssh: { user: "vagrant", password: "vagrant" }) }
5
5
 
6
6
  let(:node_one) do
@@ -12,7 +12,7 @@ describe Ridley::SSH do
12
12
  end
13
13
 
14
14
  describe "ClassMethods" do
15
- subject { Ridley::SSH }
15
+ subject { Ridley::HostConnector::SSH }
16
16
 
17
17
  describe "::start" do
18
18
  let(:options) do
@@ -27,7 +27,7 @@ describe Ridley::SSH do
27
27
  ssh.run("ls")
28
28
  end
29
29
 
30
- result.should be_a(Ridley::SSH::ResponseSet)
30
+ result.should be_a(Ridley::HostConnector::ResponseSet)
31
31
  end
32
32
 
33
33
  it "raises a LocalJumpError if a block is not provided" do
@@ -38,11 +38,11 @@ describe Ridley::SSH do
38
38
  end
39
39
  end
40
40
 
41
- subject { Ridley::SSH.new([node_one, node_two], user: "vagrant", password: "vagrant") }
41
+ subject { Ridley::HostConnector::SSH.new([node_one, node_two], user: "vagrant", password: "vagrant") }
42
42
 
43
43
  describe "#run" do
44
44
  it "returns an SSH::ResponseSet" do
45
- subject.run("ls").should be_a(Ridley::SSH::ResponseSet)
45
+ subject.run("ls").should be_a(Ridley::HostConnector::ResponseSet)
46
46
  end
47
47
  end
48
48
  end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector::WinRM::Worker do
4
+ let(:host) { 'reset.riotgames.com' }
5
+
6
+ let(:options) do
7
+ {
8
+ winrm: {
9
+ port: 1234
10
+ }
11
+ }
12
+ end
13
+
14
+ subject { Ridley::HostConnector::WinRM::Worker.new(host, options) }
15
+
16
+ describe "#winrm_port" do
17
+ it "can be overridden if options contains :winrm_port" do
18
+ subject.winrm_port.should eq(1234)
19
+ end
20
+
21
+ it "defaults to Ridley::HostConnector::DEFAULT_WINRM_PORT when not overridden" do
22
+ options.delete(:winrm)
23
+ subject.winrm_port.should eq(Ridley::HostConnector::DEFAULT_WINRM_PORT)
24
+ end
25
+ end
26
+
27
+ describe "#winrm" do
28
+ it "returns a WinRM::WinRMWebService" do
29
+ subject.winrm.should be_a(WinRM::WinRMWebService)
30
+ end
31
+ end
32
+
33
+ describe "#get_command" do
34
+ let(:command) { "echo %TEMP%" }
35
+ context "when a command is less than 2047 characters" do
36
+ it "returns the command" do
37
+ subject.get_command(command).should eq(command)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector::WinRM do
4
+ let(:connection) { double('conn', ssh: { user: "vagrant", password: "vagrant" }) }
5
+
6
+ let(:node_one) do
7
+ Ridley::NodeResource.new(connection, automatic: { cloud: { public_hostname: "33.33.33.10" } })
8
+ end
9
+
10
+ let(:node_two) do
11
+ Ridley::NodeResource.new(connection, automatic: { cloud: { public_hostname: "33.33.33.11" } })
12
+ end
13
+
14
+ describe "ClassMethods" do
15
+ subject { Ridley::HostConnector::WinRM }
16
+
17
+ describe "::start" do
18
+ let(:options) do
19
+ {
20
+ user: "Administrator",
21
+ password: "password1"
22
+ }
23
+ end
24
+
25
+ it "evaluates within the context of a new WinRM and returns the last item in the block" do
26
+ result = subject.start([node_one, node_two], options) do |winrm|
27
+ winrm.run("dir")
28
+ end
29
+ result.should be_a(Ridley::HostConnector::ResponseSet)
30
+ end
31
+
32
+ it "raises a LocalJumpError if a block is not provided" do
33
+ expect {
34
+ subject.start([node_one, node_two], options)
35
+ }.to raise_error(LocalJumpError)
36
+ end
37
+ end
38
+ end
39
+
40
+ subject { Ridley::HostConnector::WinRM.new([node_one, node_two], user: 'Administrator', password: 'password1') }
41
+
42
+ describe "#run" do
43
+ it "returns a ResponseSet" do
44
+ subject.run("dir").should be_a(Ridley::HostConnector::ResponseSet)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::HostConnector do
4
+
5
+ subject do
6
+ described_class
7
+ end
8
+
9
+ it "returns 22 as the default SSH port" do
10
+ described_class::DEFAULT_SSH_PORT.should eq(22)
11
+ end
12
+
13
+ it "returns 5985 as the default WinRM port" do
14
+ described_class::DEFAULT_WINRM_PORT.should eq(5985)
15
+ end
16
+
17
+ describe "#connector_port_open" do
18
+ let(:host) {"127.0.0.1"}
19
+ let(:port) {22}
20
+ let(:socket) {double(:new => true, :close => nil)}
21
+
22
+ context "when a port is open" do
23
+ it "returns true" do
24
+ TCPSocket.stub(:new).and_return(socket)
25
+ subject.connector_port_open?(host, port).should eq(true)
26
+ end
27
+ end
28
+
29
+ context "when a port is closed" do
30
+ it "returns false" do
31
+ TCPSocket.stub(:new).and_raise(Errno::ECONNREFUSED)
32
+ subject.connector_port_open?(host, port).should eq(false)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#best_connector_for" do
38
+ let(:host) {"127.0.0.1"}
39
+
40
+ context "when an SSH port is open" do
41
+ it "returns Ridley::HostConnector::SSH" do
42
+ subject.stub(:connector_port_open?).and_return(true)
43
+ subject.best_connector_for(host).should eq(Ridley::HostConnector::SSH)
44
+ end
45
+ end
46
+
47
+ context "when an SSH port isnt open and a WinRM port is open" do
48
+ it "retrns Ridley::HostConnector::WinRM" do
49
+ subject.stub(:connector_port_open?).and_return(false, true)
50
+ subject.best_connector_for(host).should eq(Ridley::HostConnector::WinRM)
51
+ end
52
+ end
53
+
54
+ context "when no useable ports are open" do
55
+ it "raises an exception" do
56
+ subject.stub(:connector_port_open?).and_return(false, false)
57
+ expect {
58
+ subject.best_connector_for(host)
59
+ }.to raise_error(Ridley::Errors::HostConnectionError)
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#parse_port_options" do
65
+ let(:options) do
66
+ {
67
+ ssh: {
68
+ port: 1234
69
+ },
70
+ winrm: {
71
+ port: 5678
72
+ }
73
+ }
74
+ end
75
+
76
+ context "when :ssh has a key for :port" do
77
+ it "returns the value of port instead of the default" do
78
+ subject.parse_port_options(options).should include(1234)
79
+ end
80
+ end
81
+
82
+ context "when there is no :ssh key" do
83
+ it "returns the default value for port" do
84
+ options.delete(:ssh)
85
+ subject.parse_port_options(options).should include(22)
86
+ end
87
+ end
88
+
89
+ context "when :winrm has a key for :port" do
90
+ it "returns the value of port instead of the default" do
91
+ subject.parse_port_options(options).should include(5678)
92
+ end
93
+ end
94
+
95
+ context "when there is no :ssh key" do
96
+ it "returns the default value for port" do
97
+ options.delete(:winrm)
98
+ subject.parse_port_options(options).should include(5985)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::BootstrapBinding do
4
+ let(:host) { "reset.riotgames.com" }
5
+ let(:options) do
6
+ {
7
+ server_url: "https://api.opscode.com/organizations/vialstudios",
8
+ validator_client: "chef-validator",
9
+ validator_path: fixtures_path.join("reset.pem").to_s,
10
+ encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s,
11
+ chef_version: "11.4.0"
12
+ }
13
+ end
14
+
15
+ describe "ClassMethods" do
16
+ subject do
17
+ Class.new do
18
+ include Ridley::BootstrapBinding
19
+ end
20
+ end
21
+
22
+ describe ":included" do
23
+ context "when a class includes Ridley::BootstrapBinding" do
24
+ it "should have a validate_options class method`" do
25
+ subject.methods.should include(:validate_options)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe ":validate_options" do
31
+ context "when server_url is not specified" do
32
+ let(:options) { Hash.new }
33
+
34
+ it "raises an ArgumentError" do
35
+ expect {
36
+ subject.validate_options(options)
37
+ }.to raise_error(Ridley::Errors::ArgumentError)
38
+ end
39
+ end
40
+ end
41
+
42
+ context "when validator_path is not specified" do
43
+ let(:options) do
44
+ {
45
+ server_url: "https://api.opscode.com/organizations/vialstudios"
46
+ }
47
+ end
48
+
49
+ it "raises an ArgumentError" do
50
+ expect {
51
+ subject.validate_options(options)
52
+ }.to raise_error(Ridley::Errors::ArgumentError)
53
+ end
54
+ end
55
+ end
56
+ end