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