ridley 0.9.1 → 0.10.0.rc1

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 (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