ridley-connectors 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +18 -0
- data/Guardfile +22 -0
- data/LICENSE +16 -0
- data/README.md +107 -0
- data/Thorfile +39 -0
- data/lib/ridley-connectors/chef_objects/node_object.rb +17 -0
- data/lib/ridley-connectors/client.rb +54 -0
- data/lib/ridley-connectors/host_commander.rb +231 -0
- data/lib/ridley-connectors/host_connector/response.rb +27 -0
- data/lib/ridley-connectors/host_connector/ssh.rb +211 -0
- data/lib/ridley-connectors/host_connector/winrm/command_uploader.rb +87 -0
- data/lib/ridley-connectors/host_connector/winrm.rb +218 -0
- data/lib/ridley-connectors/host_connector.rb +83 -0
- data/lib/ridley-connectors/resources/node_resource.rb +198 -0
- data/lib/ridley-connectors/version.rb +5 -0
- data/lib/ridley-connectors.rb +11 -0
- data/ridley-connectors.gemspec +27 -0
- data/spec/fixtures/encrypted_data_bag_secret +1 -0
- data/spec/fixtures/my-fake.pem +27 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/support/actor_mocking.rb +9 -0
- data/spec/support/spec_helpers.rb +20 -0
- data/spec/unit/ridley-connectors/chef_objects/node_object_spec.rb +22 -0
- data/spec/unit/ridley-connectors/client_spec.rb +32 -0
- data/spec/unit/ridley-connectors/host_commander_spec.rb +173 -0
- data/spec/unit/ridley-connectors/host_connector/ssh_spec.rb +57 -0
- data/spec/unit/ridley-connectors/host_connector/winrm/command_uploader_spec.rb +67 -0
- data/spec/unit/ridley-connectors/host_connector/winrm_spec.rb +145 -0
- data/spec/unit/ridley-connectors/host_connector_spec.rb +50 -0
- data/spec/unit/ridley-connectors/resources/node_resource_spec.rb +139 -0
- metadata +178 -0
@@ -0,0 +1,198 @@
|
|
1
|
+
module Ridley
|
2
|
+
class NodeResource
|
3
|
+
|
4
|
+
attr_reader :server_url
|
5
|
+
attr_reader :validator_path
|
6
|
+
attr_reader :validator_client
|
7
|
+
attr_reader :encrypted_data_bag_secret
|
8
|
+
attr_reader :ssh
|
9
|
+
attr_reader :winrm
|
10
|
+
attr_reader :chef_version
|
11
|
+
|
12
|
+
finalizer :finalize_callback
|
13
|
+
|
14
|
+
# @param [Celluloid::Registry] connection_registry
|
15
|
+
#
|
16
|
+
# @option options [String] :server_url
|
17
|
+
# URL to the Chef API
|
18
|
+
# @option options [Hash] ssh
|
19
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
20
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
21
|
+
# * :keys (Array, String) an array of keys (or a single key) to authenticate the ssh user with instead of a password
|
22
|
+
# * :timeout (Float) [5.0] timeout value for SSH bootstrap
|
23
|
+
# @option options [Hash] :winrm
|
24
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
25
|
+
# * :password (String) the password for the user that will perform the bootstrap
|
26
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on
|
27
|
+
# @option options [String] :validator_client
|
28
|
+
# @option options [String] :validator_path
|
29
|
+
# filepath to the validator used to bootstrap the node
|
30
|
+
# @option options [String] :encrypted_data_bag_secret
|
31
|
+
# your organizations encrypted data bag secret
|
32
|
+
# @option options [String] :chef_version
|
33
|
+
# version of Chef to install on the node (default: nil)
|
34
|
+
def initialize(connection_registry, options = {})
|
35
|
+
super(connection_registry)
|
36
|
+
@server_url = options[:server_url]
|
37
|
+
@validator_path = options[:validator_path]
|
38
|
+
@validator_client = options[:validator_client]
|
39
|
+
@encrypted_data_bag_secret = options[:encrypted_data_bag_secret]
|
40
|
+
@ssh = options[:ssh]
|
41
|
+
@winrm = options[:winrm]
|
42
|
+
@chef_version = options[:chef_version]
|
43
|
+
@host_commander = HostCommander.new_link
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [String] host
|
47
|
+
#
|
48
|
+
# @option options [Hash] ssh
|
49
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on (required)
|
50
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
51
|
+
# * :keys (Array, String) an array of keys (or a single key) to authenticate the ssh user with instead of a password
|
52
|
+
# * :timeout (Float) [5.0] timeout value for SSH bootstrap
|
53
|
+
# @option options [Hash] :winrm
|
54
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on (required)
|
55
|
+
# * :password (String) the password for the user that will perform the bootstrap
|
56
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
57
|
+
# @option options [String] :validator_client
|
58
|
+
# @option options [String] :validator_path
|
59
|
+
# filepath to the validator used to bootstrap the node (required)
|
60
|
+
# @option options [String] :bootstrap_proxy
|
61
|
+
# URL to a proxy server to bootstrap through (default: nil)
|
62
|
+
# @option options [String] :encrypted_data_bag_secret_path
|
63
|
+
# filepath on your host machine to your organizations encrypted data bag secret (default: nil)
|
64
|
+
# @option options [Hash] :hints
|
65
|
+
# a hash of Ohai hints to place on the bootstrapped node (default: Hash.new)
|
66
|
+
# @option options [Hash] :attributes
|
67
|
+
# a hash of attributes to use in the first Chef run (default: Hash.new)
|
68
|
+
# @option options [Array] :run_list
|
69
|
+
# an initial run list to bootstrap with (default: Array.new)
|
70
|
+
# @option options [String] :chef_version
|
71
|
+
# version of Chef to install on the node (default: nil)
|
72
|
+
# @option options [String] :environment
|
73
|
+
# environment to join the node to (default: '_default')
|
74
|
+
# @option options [Boolean] :sudo
|
75
|
+
# bootstrap with sudo (default: true)
|
76
|
+
# @option options [String] :template
|
77
|
+
# bootstrap template to use (default: omnibus)
|
78
|
+
#
|
79
|
+
# @return [HostConnector::Response]
|
80
|
+
def bootstrap(host, options = {})
|
81
|
+
options = options.reverse_merge(
|
82
|
+
server_url: server_url,
|
83
|
+
validator_path: validator_path,
|
84
|
+
validator_client: validator_client,
|
85
|
+
encrypted_data_bag_secret: encrypted_data_bag_secret,
|
86
|
+
ssh: ssh,
|
87
|
+
winrm: winrm,
|
88
|
+
chef_version: chef_version
|
89
|
+
)
|
90
|
+
|
91
|
+
host_commander.bootstrap(host, options)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Executes a Chef run using the best worker available for the given
|
95
|
+
# host.
|
96
|
+
#
|
97
|
+
# @param [String] host
|
98
|
+
#
|
99
|
+
# @return [HostConnector::Response]
|
100
|
+
def chef_run(host)
|
101
|
+
host_commander.chef_client(host, ssh: ssh, winrm: winrm)
|
102
|
+
rescue Errors::HostConnectionError => ex
|
103
|
+
abort(ex)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Puts a secret on the host using the best worker available for
|
107
|
+
# the given host.
|
108
|
+
#
|
109
|
+
# @param [String] host
|
110
|
+
#
|
111
|
+
# @return [HostConnector::Response]
|
112
|
+
def put_secret(host)
|
113
|
+
host_commander.put_secret(host, encrypted_data_bag_secret, ssh: ssh, winrm: winrm)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Executes an arbitrary ruby script using the best worker available
|
117
|
+
# for the given host.
|
118
|
+
#
|
119
|
+
# @param [String] host
|
120
|
+
# @param [Array<String>] command_lines
|
121
|
+
#
|
122
|
+
# @return [HostConnector::Response]
|
123
|
+
def ruby_script(host, command_lines)
|
124
|
+
host_commander.ruby_script(host, command_lines, ssh: ssh, winrm: winrm)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Executes the given command on a node using the best worker
|
128
|
+
# available for the given host.
|
129
|
+
#
|
130
|
+
# @param [String] host
|
131
|
+
# @param [String] command
|
132
|
+
#
|
133
|
+
# @return [HostConnector::Response]
|
134
|
+
def run(host, command)
|
135
|
+
host_commander.run(host, command, ssh: ssh, winrm: winrm)
|
136
|
+
end
|
137
|
+
alias_method :execute_command, :run
|
138
|
+
|
139
|
+
# Executes the given command on a node using a platform specific
|
140
|
+
# command.
|
141
|
+
#
|
142
|
+
# @param [String] host
|
143
|
+
# @param [Hash] commands
|
144
|
+
#
|
145
|
+
# @example
|
146
|
+
# platform_specific_run("host.example.com", linux: "hostname -f", windows: "echo %COMPUTERNAME%")
|
147
|
+
#
|
148
|
+
# @return [HostConnector::Response]
|
149
|
+
def platform_specific_run(host, commands)
|
150
|
+
case (type = host_commander.connector_for(host, ssh: ssh, winrm: winrm))
|
151
|
+
when HostConnector::SSH
|
152
|
+
raise Errors::CommandNotProvided.new(:ssh) unless commands[:ssh] and !commands[:ssh].empty?
|
153
|
+
run(host, commands[:ssh])
|
154
|
+
when HostConnector::WinRM
|
155
|
+
raise Errors::CommandNotProvided.new(:winrm) unless commands[:winrm] and !commands[:winrm].empty?
|
156
|
+
run(host, commands[:winrm])
|
157
|
+
else
|
158
|
+
raise RuntimeError, "#{type.class.to_s} is not a supported connector for #{self.class}##{__method__}"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
alias_method :execute_platform_specific_command, :platform_specific_run
|
162
|
+
|
163
|
+
# Uninstall Chef from a node
|
164
|
+
#
|
165
|
+
# @param [String] host
|
166
|
+
# the host to perform the action on
|
167
|
+
#
|
168
|
+
# @option options [Boolena] :skip_chef (false)
|
169
|
+
# skip removal of the Chef package and the contents of the installation
|
170
|
+
# directory. Setting this to true will only remove any data and configurations
|
171
|
+
# generated by running Chef client.
|
172
|
+
# @option options [Hash] :ssh
|
173
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
174
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
175
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
176
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
177
|
+
# * :sudo (Boolean) run as sudo (true)
|
178
|
+
# @option options [Hash] :winrm
|
179
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
180
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
181
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
182
|
+
#
|
183
|
+
# @return [HostConnector::Response]
|
184
|
+
def uninstall_chef(host, options = {})
|
185
|
+
options = options.reverse_merge(ssh: ssh, winrm: winrm)
|
186
|
+
host_commander.uninstall_chef(host, options)
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
# @return [Ridley::HostCommander]
|
192
|
+
attr_reader :host_commander
|
193
|
+
|
194
|
+
def finalize_callback
|
195
|
+
@host_commander.terminate if @host_commander && @host_commander.alive?
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'celluloid'
|
2
|
+
require 'celluloid/io'
|
3
|
+
require 'ridley'
|
4
|
+
|
5
|
+
module Ridley
|
6
|
+
require_relative 'ridley-connectors/client'
|
7
|
+
require_relative 'ridley-connectors/host_commander'
|
8
|
+
require_relative 'ridley-connectors/host_connector'
|
9
|
+
require_relative 'ridley-connectors/chef_objects/node_object'
|
10
|
+
require_relative 'ridley-connectors/resources/node_resource'
|
11
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/ridley-connectors/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.authors = ["Jamie Winsor", "Kyle Allan"]
|
6
|
+
s.email = ["jamie@vialstudios.com", "kallan@riotgames.com"]
|
7
|
+
s.description = %q{A Connector API for talking to nodes managed by Chef}
|
8
|
+
s.summary = s.description
|
9
|
+
s.homepage = "https://github.com/RiotGames/ridley-connectors"
|
10
|
+
s.license = "Apache 2.0"
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split($\)
|
13
|
+
s.executables = Array.new
|
14
|
+
s.test_files = s.files.grep(%r{^(spec)/})
|
15
|
+
s.name = "ridley-connectors"
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.version = Ridley::Connectors::VERSION
|
18
|
+
s.required_ruby_version = ">= 1.9.1"
|
19
|
+
|
20
|
+
s.add_dependency 'celluloid', '~> 0.15'
|
21
|
+
s.add_dependency 'celluloid-io', '~> 0.15'
|
22
|
+
s.add_dependency 'net-ssh'
|
23
|
+
s.add_dependency 'ridley', '~> 2.0.0'
|
24
|
+
s.add_dependency 'winrm', '~> 1.1.0'
|
25
|
+
|
26
|
+
s.add_development_dependency 'buff-ruby_engine', '~> 0.1'
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
NTE5C5gzbe3F7fGBlrT/YTuMQuHlxaOWhY81KsgYXJ0mzDsDMFvCpfi4CUXu5M7n/Umgsf8jdHw/IIkJLZcXgk+Ll75kDU/VI5FyRzib0U0SX4JB8JLM7wRFgRpuk3GD27LnYR1APmLncE7R6ZSJc6iaFHcEL2MdR+hv0nhUZPUqITxYHyrYvqNSfroyxldQ/cvnrIMBS8JrpjIsLdYhcgL6mPJiakl4fM36cFk6Wl2Mxw7vOvGXRSR5l+t42pGDhtOjE3os5reLVoWkYoiQ1fpx3NrOdxsVuz17+3jMLBlmni2SGf2wncui2r9PqCrVbUbaCi6aNV1+SRbeh5kxBxjWSzw59BNXtna4vSK6hFPsT6tfXlOi67Q2vwjjAqltAVStGas/VZyU7DRzxMkbnPPtue+7Pajqe/TfSNWA5SX2cHtkG2X3EqZ8ftOa9p+b/VJlUnnnV2ilVfgjCW2q6XXMbC0C5yIbrDZm+aCJyhueA0j+ZHWM4k07OAuB7FRcuJJBs8H2StEx2o22OdAYUBcN5PRGlOAEBemL+sZAztbex2NjjOYV90806UFvSJLPixVWJgDTSA5OvXtNvUQYDYSGRQ/BmH86aA5gJ60AM9vEVB0BfPi946m9D4LZ/2uK6fqq3zVIV1s0EgfYHYUVz0oaf3srofc5YUAP3Ge/VLE=
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpQIBAAKCAQEAyyUMqrTh1IzKOyE0fvXEWC7m0AdMI8/dr9JJMUKtK9vhhP0w
|
3
|
+
rm6m95GoybFM2IRryukFsAxpcir3M1ungTU3Smq4MshhMJ7H9FbvZVfQoknTbCsR
|
4
|
+
w6scg2fBepxT2+fcGRufr8nAh92M3uUkN9bMMTAkt18D4br6035YvdmvHDJERxYq
|
5
|
+
ByA/720AdI9VNSIvw+x8oqsIkXLEdF6dgT9MpG5iWZT66pbFsnNZpRrd4/bFNWBY
|
6
|
+
+13aOqdmjiTL08/EdgQFKMT5qimpos1TuQhA7mwInOjQgzVu9uCDkMiYejaLbUz0
|
7
|
+
lGyS8y4uxu6z2hA900Jg/z+JJuXymH5QAX3GZQIDAQABAoIBAQCtFXkwbYPI1Nht
|
8
|
+
/wG6du5+8B9K+hy+mppY9wPTy+q+Zs9Ev3Fd/fuXDm1QxBckl9c8AMUO1dR2KPOM
|
9
|
+
t7gFl/DvH/SnmCFvCqp1nijFIUgrLlnMXPn6zG0z7RBlxpKQ2IGohufNIEpBuNwR
|
10
|
+
Ag2U4hgChPGTp4ooJ2cVEh7MS5AupYPDbC62dWEdW68aRTWhh2BCGAWBb6s16yl9
|
11
|
+
aZ7+OcxW2eeRJVbRfLkLQEDutJZi5TfOEn5QPc86ZgxcCmnvwulnpnhpz6QCkgQt
|
12
|
+
OP/+KRqDhWSDVCFREVT30fUIj1EWvK7NFWASZQxueZStuIvMEKeFebYfrbHxRFzJ
|
13
|
+
UmaxJnWVAoGBAPbKLpeky6ClccBaHHrCgjzakoDfGgyNKDQ9g753lJxB8nn7d9X4
|
14
|
+
HQpkWpfqAGFRZp1hI2H+VxyUXLh2Ob5OUeTm0OZJll35vycOaQEtfgIScXTcvzn0
|
15
|
+
16J9eX2YY4wIHEEMh85nKk8BEGgiNP5nuEviHocCeYXoi/Zq3+qj6v63AoGBANK5
|
16
|
+
4nyi6LBQFs1CUc7Sh7vjtOE3ia7KeRmOr7gS6QhS3iK3Oa8FzBLJ6ETjN2a9Bw8N
|
17
|
+
cF7I/+cr4s7DUJjxdb53D/J6TVSYORNNCUVnpF/uB2LqqdXDYmpO0PvFkXFoYTnJ
|
18
|
+
kaLAN8uCoLKr6JH9tq3DfXIfDIHiZ+BOIvI070fDAoGBAMDyzEDFmGruTyRLj66u
|
19
|
+
+rJnVVmqlKwxhLhrS+CTj74nlVOnt0a0KMhiM65IRqnPwcHUG5zXBPaUTHXwAS93
|
20
|
+
/nFPwQ37hLPOupPnoVNJZRZrowbyPBQtCJbDMURv64ylHqoBCQDoCd0hANnZvMMX
|
21
|
+
BrFVhfaaibaXXS542r6SD/27AoGAECadHE5kJTdOOBcwK/jo3Fa8g1J9Y/8yvum3
|
22
|
+
wBT69V9clS6T5j08geglvDnqAh7UzquKBEnFi1NKw+wmXkKLcrivaTdEfApavYb3
|
23
|
+
AfHKoGue907jC3Y5Mcquq81ds2J7qTEwz1eKLzfo1yjj32ShvrmwALIuhDn1GjUC
|
24
|
+
6qtx938CgYEApEqvu0nocR1jmVVlLe5uKQBj949dh6NGq0R5Lztz6xufaTYzMC3d
|
25
|
+
AZG9XPPjRqSLs+ylSXJpwHEwoeyLFDaJcO+GgW1/ut4MC2HppOx6aImwDdXMHUWR
|
26
|
+
KYGIFF4AU/IYoBcanAm4s078EH/Oz01B2c7tR2TqabisPgLYe7PXSCw=
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'buff/ruby_engine'
|
4
|
+
|
5
|
+
def setup_rspec
|
6
|
+
require 'rspec'
|
7
|
+
require 'webmock/rspec'
|
8
|
+
|
9
|
+
Dir[File.join(File.expand_path("../../spec/support/**/*.rb", __FILE__))].each { |f| require f }
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.include Ridley::SpecHelpers
|
13
|
+
|
14
|
+
config.before(:suite) do
|
15
|
+
WebMock.disable_net_connect!(allow_localhost: true, net_http_connect_on_start: true)
|
16
|
+
end
|
17
|
+
|
18
|
+
config.before(:all) { Ridley.logger = Celluloid.logger = nil }
|
19
|
+
|
20
|
+
config.before(:each) do
|
21
|
+
Celluloid.shutdown
|
22
|
+
Celluloid.boot
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if Buff::RubyEngine.mri? && ENV['CI'] != 'true'
|
28
|
+
require 'spork'
|
29
|
+
|
30
|
+
Spork.prefork do
|
31
|
+
setup_rspec
|
32
|
+
end
|
33
|
+
|
34
|
+
Spork.each_run do
|
35
|
+
require 'ridley-connectors'
|
36
|
+
end
|
37
|
+
else
|
38
|
+
require 'ridley-connectors'
|
39
|
+
setup_rspec
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Ridley
|
2
|
+
module SpecHelpers
|
3
|
+
def app_root_path
|
4
|
+
Pathname.new(File.expand_path('../../../', __FILE__))
|
5
|
+
end
|
6
|
+
|
7
|
+
def clean_tmp_path
|
8
|
+
FileUtils.rm_rf(tmp_path)
|
9
|
+
FileUtils.mkdir_p(tmp_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def fixtures_path
|
13
|
+
app_root_path.join('spec/fixtures')
|
14
|
+
end
|
15
|
+
|
16
|
+
def tmp_path
|
17
|
+
app_root_path.join('spec/tmp')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ridley::NodeObject do
|
4
|
+
let(:resource) { double('resource') }
|
5
|
+
let(:instance) { described_class.new(resource) }
|
6
|
+
subject { instance }
|
7
|
+
|
8
|
+
describe "#chef_run" do
|
9
|
+
it "sends the message #chef_run to the resource with the public_hostname of this instance" do
|
10
|
+
resource.should_receive(:chef_run).with(instance.public_hostname)
|
11
|
+
subject.chef_run
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#put_secret" do
|
16
|
+
it "sends the message #put_secret to the resource with the public_hostname of this instance" do
|
17
|
+
resource.should_receive(:put_secret).with(instance.public_hostname)
|
18
|
+
|
19
|
+
subject.put_secret
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ridley::Client do
|
4
|
+
let(:server_url) { "https://api.opscode.com" }
|
5
|
+
let(:client_name) { "fake" }
|
6
|
+
let(:client_key) { fixtures_path.join("my-fake.pem").to_s }
|
7
|
+
let(:ssh) { {user: "fake", password: "password1", port: "222"} }
|
8
|
+
let(:winrm) { {user: "fake", password: "password2", port: "5986"} }
|
9
|
+
let(:config) do
|
10
|
+
{
|
11
|
+
server_url: server_url,
|
12
|
+
client_name: client_name,
|
13
|
+
client_key: client_key,
|
14
|
+
ssh: ssh,
|
15
|
+
winrm: winrm
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "ClassMethods" do
|
20
|
+
describe "::initialize" do
|
21
|
+
subject { described_class.new(options) }
|
22
|
+
|
23
|
+
it "assigns a 'ssh' attribute from the given 'ssh' option" do
|
24
|
+
described_class.new(config).ssh.should eql({user: "fake", password: "password1", port: "222"})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "assigns a 'winrm' attribute from the given 'winrm' option" do
|
28
|
+
described_class.new(config).winrm.should eql({user: "fake", password: "password2", port: "5986"})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ridley::HostCommander do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
describe "#run" do
|
7
|
+
let(:host) { "fake.riotgames.com" }
|
8
|
+
let(:command) { "ls" }
|
9
|
+
let(:options) do
|
10
|
+
{ ssh: { port: 22 }, winrm: { port: 5985 } }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when communicating to a unix node" do
|
14
|
+
before do
|
15
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(false)
|
16
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(true)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "sends a #run message to the ssh host connector" do
|
20
|
+
subject.send(:ssh).should_receive(:run).with(host, command, options)
|
21
|
+
|
22
|
+
subject.run(host, command, options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when communicating to a windows node" do
|
27
|
+
before do
|
28
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(true)
|
29
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(false)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sends a #run message to the ssh host connector" do
|
33
|
+
subject.send(:winrm).should_receive(:run).with(host, command, options)
|
34
|
+
|
35
|
+
subject.run(host, command, options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#bootstrap" do
|
41
|
+
let(:host) { "fake.riotgames.com" }
|
42
|
+
let(:options) do
|
43
|
+
{ ssh: { port: 22 }, winrm: { port: 5985 } }
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when communicating to a unix node" do
|
47
|
+
before do
|
48
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(false)
|
49
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(true)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "sends a #bootstrap message to the ssh host connector" do
|
53
|
+
subject.send(:ssh).should_receive(:bootstrap).with(host, options)
|
54
|
+
|
55
|
+
subject.bootstrap(host, options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when communicating to a windows node" do
|
60
|
+
before do
|
61
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(true)
|
62
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(false)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sends a #bootstrap message to the winrm host connector" do
|
66
|
+
subject.send(:winrm).should_receive(:bootstrap).with(host, options)
|
67
|
+
|
68
|
+
subject.bootstrap(host, options)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#chef_client" do
|
74
|
+
let(:host) { "fake.riotgames.com" }
|
75
|
+
let(:options) do
|
76
|
+
{ ssh: { port: 22 }, winrm: { port: 5985 } }
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when communicating to a unix node" do
|
80
|
+
before do
|
81
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(false)
|
82
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(true)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "sends a #chef_client message to the ssh host connector" do
|
86
|
+
subject.send(:ssh).should_receive(:chef_client).with(host, options)
|
87
|
+
|
88
|
+
subject.chef_client(host, options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when communicating to a windows node" do
|
93
|
+
before do
|
94
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(true)
|
95
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(false)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "sends a #chef_client message to the ssh host connector" do
|
99
|
+
subject.send(:winrm).should_receive(:chef_client).with(host, options)
|
100
|
+
|
101
|
+
subject.chef_client(host, options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#put_secret" do
|
107
|
+
let(:host) { "fake.riotgames.com" }
|
108
|
+
let(:secret) { "something_secret" }
|
109
|
+
let(:options) do
|
110
|
+
{ ssh: { port: 22 }, winrm: { port: 5985 } }
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when communicating to a unix node" do
|
114
|
+
before do
|
115
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(false)
|
116
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(true)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "sends a #put_secret message to the ssh host connector" do
|
120
|
+
subject.send(:ssh).should_receive(:put_secret).with(host, secret, options)
|
121
|
+
|
122
|
+
subject.put_secret(host, secret, options)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when communicating to a windows node" do
|
127
|
+
before do
|
128
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(true)
|
129
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(false)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "sends a #put_secret message to the ssh host connector" do
|
133
|
+
subject.send(:winrm).should_receive(:put_secret).with(host, secret, options)
|
134
|
+
|
135
|
+
subject.put_secret(host, secret, options)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#ruby_script" do
|
141
|
+
let(:host) { "fake.riotgames.com" }
|
142
|
+
let(:command_lines) { ["line one"] }
|
143
|
+
let(:options) do
|
144
|
+
{ ssh: { port: 22 }, winrm: { port: 5985 } }
|
145
|
+
end
|
146
|
+
|
147
|
+
context "when communicating to a unix node" do
|
148
|
+
before do
|
149
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(false)
|
150
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(true)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "sends a #ruby_script message to the ssh host connector" do
|
154
|
+
subject.send(:ssh).should_receive(:ruby_script).with(host, command_lines, options)
|
155
|
+
|
156
|
+
subject.ruby_script(host, command_lines, options)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when communicating to a windows node" do
|
161
|
+
before do
|
162
|
+
subject.stub(:connector_port_open?).with(host, options[:winrm][:port]).and_return(true)
|
163
|
+
subject.stub(:connector_port_open?).with(host, options[:ssh][:port], anything).and_return(false)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "sends a #ruby_script message to the ssh host connector" do
|
167
|
+
subject.send(:winrm).should_receive(:ruby_script).with(host, command_lines, options)
|
168
|
+
|
169
|
+
subject.ruby_script(host, command_lines, options)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ridley::HostConnector::SSH do
|
4
|
+
subject { connector }
|
5
|
+
let(:connector) { described_class.new }
|
6
|
+
|
7
|
+
let(:host) { 'fake.riotgames.com' }
|
8
|
+
let(:options) do
|
9
|
+
{
|
10
|
+
server_url: double('server_url'),
|
11
|
+
validator_path: fixtures_path.join('my-fake.pem'),
|
12
|
+
validator_client: double('validator_client'),
|
13
|
+
encrypted_data_bag_secret: 'encrypted_data_bag_secret',
|
14
|
+
ssh: Hash.new,
|
15
|
+
chef_version: double('chef_version')
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#bootstrap" do
|
20
|
+
it "sends a #run message to self to bootstrap a node" do
|
21
|
+
connector.should_receive(:run).with(host, anything, options)
|
22
|
+
connector.bootstrap(host, options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#chef_client" do
|
27
|
+
it "sends a #run message to self to execute chef-client" do
|
28
|
+
connector.should_receive(:run).with(host, "chef-client", options)
|
29
|
+
connector.chef_client(host, options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#put_secret" do
|
34
|
+
let(:encrypted_data_bag_secret_path) { fixtures_path.join("encrypted_data_bag_secret").to_s }
|
35
|
+
let(:secret) { File.read(encrypted_data_bag_secret_path).chomp }
|
36
|
+
|
37
|
+
it "receives a run command with echo" do
|
38
|
+
connector.should_receive(:run).with(host,
|
39
|
+
"echo '#{secret}' > /etc/chef/encrypted_data_bag_secret; chmod 0600 /etc/chef/encrypted_data_bag_secret",
|
40
|
+
options
|
41
|
+
)
|
42
|
+
connector.put_secret(host, secret, options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#ruby_script" do
|
47
|
+
let(:command_lines) { ["puts 'hello'", "puts 'there'"] }
|
48
|
+
|
49
|
+
it "receives a ruby call with the command" do
|
50
|
+
connector.should_receive(:run).with(host,
|
51
|
+
"#{described_class::EMBEDDED_RUBY_PATH} -e \"puts 'hello';puts 'there'\"",
|
52
|
+
options
|
53
|
+
)
|
54
|
+
connector.ruby_script(host, command_lines, options)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|