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
@@ -184,7 +184,7 @@ module Ridley
184
184
  end
185
185
 
186
186
  def to_s
187
- "#{self.chef_id}: #{self._attributes_}"
187
+ "#<#{self.class} chef_id:#{self.chef_id}, attributes:#{self._attributes_}>"
188
188
  end
189
189
 
190
190
  # @param [Object] other
@@ -1,5 +1,12 @@
1
1
  module Ridley
2
2
  # @author Jamie Winsor <reset@riotgames.com>
3
+ #
4
+ # @example listing all clients
5
+ # conn = Ridley.new(...)
6
+ # conn.client.all #=> [
7
+ # #<Ridley::ClientResource chef_id:'reset'>,
8
+ # #<Ridley::ClientResource chef_id:'reset-validator'>
9
+ # ]
3
10
  class ClientResource < Ridley::Resource
4
11
  class << self
5
12
  # Retrieves a client from the remote connection matching the given chef_id
@@ -10,6 +10,10 @@ module Ridley
10
10
  # * :password (String) the password for the shell user that will perform the bootstrap
11
11
  # * :keys (Array, String) an array of keys (or a single key) to authenticate the ssh user with instead of a password
12
12
  # * :timeout (Float) [5.0] timeout value for SSH bootstrap
13
+ # @option options [Hash] :winrm
14
+ # * :user (String) a user that will login to each node and perform the bootstrap command on (required)
15
+ # * :password (String) the password for the user that will perform the bootstrap
16
+ # * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
13
17
  # @option options [String] :validator_client
14
18
  # @option options [String] :validator_path
15
19
  # filepath to the validator used to bootstrap the node (required)
@@ -24,7 +28,7 @@ module Ridley
24
28
  # @option options [Array] :run_list
25
29
  # an initial run list to bootstrap with (default: Array.new)
26
30
  # @option options [String] :chef_version
27
- # version of Chef to install on the node (default: {Ridley::CHEF_VERSION})
31
+ # version of Chef to install on the node (default: nil)
28
32
  # @option options [String] :environment
29
33
  # environment to join the node to (default: '_default')
30
34
  # @option options [Boolean] :sudo
@@ -41,12 +45,13 @@ module Ridley
41
45
  validator_path: client.validator_path,
42
46
  validator_client: client.validator_client,
43
47
  encrypted_data_bag_secret_path: client.encrypted_data_bag_secret_path,
44
- ssh: client.ssh
48
+ ssh: client.ssh,
49
+ winrm: client.winrm,
50
+ chef_version: client.chef_version
45
51
  }
46
52
 
47
53
  options = default_options.merge(options)
48
-
49
- Bootstrapper.new(*args, options).run
54
+ Bootstrapper.new(args, options).run
50
55
  end
51
56
 
52
57
  # Merges the given data with the the data of the target node on the remote
@@ -94,7 +94,7 @@ module Ridley
94
94
  # @return [Hash, nil]
95
95
  def upload(chk_id, path)
96
96
  checksum = self.checksum(chk_id)
97
-
97
+
98
98
  unless checksum[:needs_upload]
99
99
  return nil
100
100
  end
@@ -109,12 +109,6 @@ module Ridley
109
109
  upload_path = url.path
110
110
  url.path = ""
111
111
 
112
- # versions prior to OSS Chef 11 will strip the port to upload the file to in the checksum
113
- # url returned. This will ensure we are uploading to the proper location.
114
- if client.connection.foss?
115
- url.port = URI(client.connection.server_url).port
116
- end
117
-
118
112
  begin
119
113
  Faraday.new(url, client.options.slice(*Connection::VALID_OPTIONS)) do |c|
120
114
  c.response :chef_response
@@ -1,3 +1,3 @@
1
1
  module Ridley
2
- VERSION = "0.9.1"
2
+ VERSION = "0.10.0.rc1"
3
3
  end
data/ridley.gemspec CHANGED
@@ -33,4 +33,5 @@ Gem::Specification.new do |s|
33
33
  s.add_runtime_dependency 'erubis'
34
34
  s.add_runtime_dependency 'net-http-persistent', '>= 2.8'
35
35
  s.add_runtime_dependency 'retryable'
36
+ s.add_runtime_dependency 'winrm', '~> 1.1.0'
36
37
  end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::UnixTemplateBinding do
4
+
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
+ }
12
+ end
13
+
14
+ describe "ClassMethods" do
15
+ subject { described_class }
16
+
17
+ describe "::new" do
18
+ context "when no sudo option is passed through" do
19
+ it "sets a default value of 'true' to 'sudo'" do
20
+ options.delete(:sudo)
21
+ obj = subject.new(options)
22
+
23
+ obj.send(:sudo).should be_true
24
+ end
25
+ end
26
+
27
+ context "when the sudo option is passed through as false" do
28
+ it "sets the value of sudo to 'false' if provided" do
29
+ options.merge!(sudo: false)
30
+ obj = subject.new(options)
31
+
32
+ obj.send(:sudo).should be_false
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ subject { Ridley::UnixTemplateBinding.new(options) }
39
+
40
+ describe "MixinMethods" do
41
+
42
+ describe "#templates_path" do
43
+ it "returns a pathname" do
44
+ subject.templates_path.should be_a(Pathname)
45
+ end
46
+ end
47
+
48
+ describe "#first_boot" do
49
+ it "returns a string" do
50
+ subject.first_boot.should be_a(String)
51
+ end
52
+ end
53
+
54
+ describe "#encrypted_data_bag_secret" do
55
+ it "returns a string" do
56
+ subject.encrypted_data_bag_secret.should be_a(String)
57
+ end
58
+ end
59
+
60
+ describe "#validation_key" do
61
+ it "returns a string" do
62
+ subject.validation_key.should be_a(String)
63
+ end
64
+ end
65
+
66
+ describe "template" do
67
+ it "returns a string" do
68
+ subject.template.should be_a(Erubis::Eruby)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#boot_command" do
74
+ it "returns a string" do
75
+ subject.boot_command.should be_a(String)
76
+ end
77
+ end
78
+
79
+ describe "#chef_run" do
80
+ it "returns a string" do
81
+ subject.chef_run.should be_a(String)
82
+ end
83
+ end
84
+
85
+ describe "#chef_config" do
86
+ it "returns a string" do
87
+ subject.chef_config.should be_a(String)
88
+ end
89
+ end
90
+
91
+ describe "#default_template" do
92
+ it "returns a string" do
93
+ subject.default_template.should be_a(String)
94
+ end
95
+ end
96
+
97
+ describe "#bootstrap_directory" do
98
+ it "returns a string" do
99
+ subject.bootstrap_directory.should be_a(String)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::WindowsTemplateBinding do
4
+ let(:options) do
5
+ {
6
+ server_url: "https://api.opscode.com/organizations/vialstudios",
7
+ validator_client: "chef-validator",
8
+ validator_path: fixtures_path.join("reset.pem").to_s,
9
+ encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s,
10
+ chef_version: "11.4.0"
11
+ }
12
+ end
13
+
14
+ describe "ClassMethods" do
15
+ subject { described_class }
16
+
17
+ describe "::new" do
18
+ context "when a chef_version is passed through" do
19
+ it "sets the chef_version attribute to the same value" do
20
+ subject.new(options).chef_version.should eq("11.4.0")
21
+ end
22
+ end
23
+
24
+ context "when the chef_version is not passed through" do
25
+ it "sets the chef_version to 'latest'" do
26
+ options.delete(:chef_version)
27
+ subject.new(options).chef_version.should eq("latest")
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ subject { Ridley::WindowsTemplateBinding.new(options) }
34
+
35
+ describe "MixinMethods" do
36
+
37
+ describe "#templates_path" do
38
+ it "returns a pathname" do
39
+ subject.templates_path.should be_a(Pathname)
40
+ end
41
+ end
42
+
43
+ describe "#first_boot" do
44
+ it "returns a string" do
45
+ subject.first_boot.should be_a(String)
46
+ end
47
+ end
48
+
49
+ describe "#encrypted_data_bag_secret" do
50
+ it "returns a string" do
51
+ subject.encrypted_data_bag_secret.should be_a(String)
52
+ end
53
+ end
54
+
55
+ describe "#validation_key" do
56
+ it "returns a string" do
57
+ subject.validation_key.should be_a(String)
58
+ end
59
+ end
60
+
61
+ describe "template" do
62
+ it "returns a string" do
63
+ subject.template.should be_a(Erubis::Eruby)
64
+ end
65
+ end
66
+ end
67
+
68
+
69
+ describe "#boot_command" do
70
+ it "returns a string" do
71
+ subject.boot_command.should be_a(String)
72
+ end
73
+ end
74
+
75
+ describe "#chef_run" do
76
+ it "returns a string" do
77
+ subject.chef_run.should be_a(String)
78
+ end
79
+ end
80
+
81
+ describe "#chef_config" do
82
+ it "returns a string" do
83
+ subject.chef_config.should be_a(String)
84
+ end
85
+ end
86
+
87
+ describe "#default_template" do
88
+ it "returns a string" do
89
+ subject.default_template.should be_a(String)
90
+ end
91
+ end
92
+
93
+ describe "#bootstrap_directory" do
94
+ it "returns a string" do
95
+ subject.bootstrap_directory.should be_a(String)
96
+ end
97
+ end
98
+
99
+ describe "#escape_and_echo" do
100
+ let(:output) { "foo()" }
101
+
102
+ it "adds 'echo.' to the beginning of each line and escapes special batch characters" do
103
+ subject.escape_and_echo(output).should eq("echo.foo^(^)")
104
+ end
105
+ end
106
+
107
+ describe "#windows_wget_vb" do
108
+ it "returns a string" do
109
+ subject.windows_wget_vb.should be_a(String)
110
+ end
111
+ end
112
+
113
+ describe "#windows_wget_powershell" do
114
+ it "returns a string" do
115
+ subject.windows_wget_powershell.should be_a(String)
116
+ end
117
+ end
118
+ end
@@ -15,118 +15,31 @@ describe Ridley::Bootstrapper::Context do
15
15
  describe "ClassMethods" do
16
16
  subject { Ridley::Bootstrapper::Context }
17
17
 
18
- describe "::new" do
19
- it "sets a default value of 'true' to 'sudo'" do
20
- options.delete(:sudo)
21
- obj = subject.new(host, options)
22
-
23
- obj.send(:sudo).should be_true
24
- end
25
-
26
- it "sets the value of sudo to 'false' if provided" do
27
- options.merge!(sudo: false)
28
- obj = subject.new(host, options)
29
-
30
- obj.send(:sudo).should be_false
31
- end
32
-
33
- context "when validator_path is not specified" do
34
- let(:options) { Hash.new }
35
-
36
- it "raises an ArgumentError" do
37
- lambda {
38
- subject.new(host, options)
39
- }.should raise_error(Ridley::Errors::ArgumentError)
18
+ describe "::create" do
19
+
20
+ context "when the best connection is SSH" do
21
+ it "sets template_binding to a Ridley::UnixTemplateBinding" do
22
+ Ridley::HostConnector.stub(:best_connector_for).and_return(Ridley::HostConnector::SSH)
23
+ context = subject.create(host, options)
24
+ context.template_binding.should be_a(Ridley::UnixTemplateBinding)
40
25
  end
41
26
  end
42
27
 
43
- context "when a validator_path is specified" do
44
- let(:options) do
45
- {
46
- server_url: "https://api.opscode.com/organizations/vialstudios",
47
- validator_path: fixtures_path.join("reset.pem").to_s
48
- }
49
- end
50
-
51
- it "sets a value for validation_key" do
52
- subject.new(host, options).validation_key.should_not be_nil
28
+ context "when the best connection is WinRM" do
29
+ it "sets template_binding to a Ridley::WindowsTemplateBinding" do
30
+ Ridley::HostConnector.stub(:best_connector_for).and_return(Ridley::HostConnector::WinRM)
31
+ context = subject.create(host, options)
32
+ context.template_binding.should be_a(Ridley::WindowsTemplateBinding)
53
33
  end
54
34
  end
55
- end
56
- end
57
-
58
- subject { Ridley::Bootstrapper::Context.new(host, options) }
59
-
60
- describe "#boot_command" do
61
- it "returns a string" do
62
- subject.boot_command.should be_a(String)
63
- end
64
- end
65
-
66
- describe "#chef_run" do
67
- it "returns a string" do
68
- subject.chef_run.should be_a(String)
69
- end
70
- end
71
-
72
- describe "#chef_config" do
73
- it "returns a string" do
74
- subject.chef_config.should be_a(String)
75
- end
76
- end
77
-
78
- describe "#first_boot" do
79
- it "returns a string" do
80
- subject.first_boot.should be_a(String)
81
- end
82
- end
83
-
84
- describe "#validation_key" do
85
- it "returns a string" do
86
- subject.validation_key.should be_a(String)
87
- end
88
-
89
- it "returns the chomped contents of the file found at validator_path" do
90
- subject.validation_key.should eql(File.read(options[:validator_path]).chomp)
91
- end
92
-
93
- context "when a validator file is not found at validator_path" do
94
- before(:each) do
95
- subject.stub(:validator_path) { fixtures_path.join("not.txt").to_s }
96
- end
97
-
98
- it "raises a ValidatorNotFound error" do
99
- lambda {
100
- subject.validation_key
101
- }.should raise_error(Ridley::Errors::ValidatorNotFound)
102
- end
103
- end
104
- end
105
-
106
- describe "#encrypted_data_bag_secret" do
107
- it "returns a string" do
108
- subject.encrypted_data_bag_secret.should be_a(String)
109
- end
110
-
111
- context "when a encrypted_data_bag_secret_path is not provided" do
112
- before(:each) do
113
- subject.stub(:encrypted_data_bag_secret_path) { nil }
114
- end
115
35
 
116
- it "returns nil" do
117
- subject.encrypted_data_bag_secret.should be_nil
118
- end
119
- end
120
-
121
- context "when the file is not found at the given encrypted_data_bag_secret_path" do
122
- before(:each) do
123
- subject.stub(:encrypted_data_bag_secret_path) { fixtures_path.join("not.txt").to_s }
124
- end
125
-
126
- it "raises an EncryptedDataBagSecretNotFound erorr" do
127
- lambda {
128
- subject.encrypted_data_bag_secret
129
- }.should raise_error(Ridley::Errors::EncryptedDataBagSecretNotFound)
36
+ context "when there is no good connection option" do
37
+ it "raises an error" do
38
+ Ridley::HostConnector.stub(:best_connector_for).and_return(nil)
39
+ expect {
40
+ context = subject.create(host, options)
41
+ }.to raise_error(Ridley::Errors::HostConnectionError)
42
+ end
130
43
  end
131
44
  end
132
45
  end