ridley-connectors 1.0.1
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.
- 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
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: c1d5f17ffd3feb5cafb982a127e2395f533e8413
|
|
4
|
+
data.tar.gz: 489a86773e6532a1e39896062c4057625cd64d0e
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0e0d43263f510aafd2f797e00d6401af61bd6f98dce4461804de9d6c538808b709c45eef96ed2ea963ad61af8255da5cd0a19936b84fd6293a747a5f0792568d
|
|
7
|
+
data.tar.gz: b4e15afa128530307f6b21c8dc857a6c26c1807d5ed53aecd3461efd68a126fee293eb6395bcb2be96522a71cd4374d766473f712a158d5624906af228ec8d31
|
data/.gitignore
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
*.sw[op]
|
|
19
|
+
.DS_Store
|
|
20
|
+
.rspec
|
|
21
|
+
.bin/
|
|
22
|
+
vendor/
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0.0-p247
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
## v.1.0.1
|
|
2
|
+
|
|
3
|
+
* [#3](https://github.com/RiotGames/ridley-connectors/pull/3) Fix the broken Ridley::Client
|
|
4
|
+
|
|
5
|
+
## v.1.0.0
|
|
6
|
+
|
|
7
|
+
* [Ridley #227](https://github.com/RiotGames/ridley/pull/227) Move code out of Ridley and into its own gem
|
|
8
|
+
* See the [Ridley 2.0.0 Changelog](https://github.com/RiotGames/ridley/blob/v2.0.0/CHANGELOG.md) for more details.
|
data/Gemfile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gemspec
|
|
4
|
+
|
|
5
|
+
group :development do
|
|
6
|
+
gem 'yard'
|
|
7
|
+
gem 'spork'
|
|
8
|
+
gem 'guard', '>= 1.5.0'
|
|
9
|
+
gem 'guard-yard'
|
|
10
|
+
gem 'guard-rspec'
|
|
11
|
+
gem 'guard-spork', platforms: :ruby
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
group :test do
|
|
15
|
+
gem 'rspec', '~> 2.14.0'
|
|
16
|
+
gem 'webmock'
|
|
17
|
+
gem 'thor'
|
|
18
|
+
end
|
data/Guardfile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
notification :off
|
|
2
|
+
|
|
3
|
+
guard 'spork' do
|
|
4
|
+
watch('Gemfile')
|
|
5
|
+
watch('spec/spec_helper.rb') { :rspec }
|
|
6
|
+
watch(%r{^spec/support/.+\.rb$}) { :rspec }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
guard 'yard', stdout: '/dev/null', stderr: '/dev/null' do
|
|
10
|
+
watch(%r{app/.+\.rb})
|
|
11
|
+
watch(%r{lib/.+\.rb})
|
|
12
|
+
watch(%r{ext/.+\.c})
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
guard 'rspec', cli: "--color --drb --format Fuubar", all_on_start: false, all_after_pass: false do
|
|
16
|
+
watch(%r{^spec/unit/.+_spec\.rb$})
|
|
17
|
+
watch(%r{^spec/acceptance/.+_spec\.rb$})
|
|
18
|
+
|
|
19
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
|
|
20
|
+
watch('spec/spec_helper.rb') { "spec" }
|
|
21
|
+
watch(%r{^spec/support/.+\.rb$}) { "spec" }
|
|
22
|
+
end
|
data/LICENSE
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Copyright 2012-2013 Riot Games
|
|
2
|
+
|
|
3
|
+
Jamie Winsor (<jamie@vialstudios.com>)
|
|
4
|
+
Kyle Allan (<kallan@riotgames.com>)
|
|
5
|
+
|
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License.
|
|
8
|
+
You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
See the License for the specific language governing permissions and
|
|
16
|
+
limitations under the License.
|
data/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Ridley Connectors
|
|
2
|
+
[](http://badge.fury.io/rb/ridley-connectors)
|
|
3
|
+
[](http://travis-ci.org/RiotGames/ridley-connectors)
|
|
4
|
+
[](https://gemnasium.com/RiotGames/ridley-connectors)
|
|
5
|
+
[](https://codeclimate.com/github/RiotGames/ridley-connectors)
|
|
6
|
+
|
|
7
|
+
An extension on [Ridley](https://github.com/RiotGames/ridley) adding support for connecting and communicating with nodes in Chef.
|
|
8
|
+
|
|
9
|
+
Installation
|
|
10
|
+
------------
|
|
11
|
+
Add ridley-connectors to your `Gemfile`:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'ridley-connectors'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And run the `bundle` command to install. Alternatively, you can install the gem directly:
|
|
18
|
+
|
|
19
|
+
$ gem install ridley-connectors
|
|
20
|
+
|
|
21
|
+
Usage
|
|
22
|
+
-----
|
|
23
|
+
You can use ridley-connectors just like using Ridley.
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
require 'ridley'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Creating a new Ridley client
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
ridley = Ridley.new(
|
|
33
|
+
server_url: "https://api.opscode.com/organizations/ridley",
|
|
34
|
+
client_name: "me",
|
|
35
|
+
client_key: "/Users/me/.chef/me.pem"
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
ridley-connectors exposes all the usual features of Ridley, but adds some sugar for interacting with nodes.
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
ridley.node.bootstrap("hostname.to.bootstrap.com") # Bootstraps a hostname or IP
|
|
43
|
+
ridley.node.put_secret("hostname") # Puts your configured encrypted data bag secret onto a hostname or IP
|
|
44
|
+
ridley.node.chef_run("hostname") # Runs Chef on a hostname or IP
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Node Resource
|
|
48
|
+
-------------
|
|
49
|
+
|
|
50
|
+
### Bootstrapping Unix nodes
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
ridley = Ridley.new(
|
|
54
|
+
server_url: "https://api.opscode.com",
|
|
55
|
+
organization: "vialstudios",
|
|
56
|
+
validator_client: "vialstudios-validator",
|
|
57
|
+
validator_path: "/Users/reset/.chef/vialstudios-validator.pem",
|
|
58
|
+
ssh: {
|
|
59
|
+
user: "vagrant",
|
|
60
|
+
password: "vagrant"
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
ridley.node.bootstrap("33.33.33.10", "33.33.33.11")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Bootstrapping Windows Nodes
|
|
68
|
+
|
|
69
|
+
Windows Nodes are bootstrapped using a combination of WinRM, Batch, and PowerShell. You will probably need to tweak some settings on your Windows servers to ensure the commands are successful.
|
|
70
|
+
|
|
71
|
+
#### WinRM Settings
|
|
72
|
+
|
|
73
|
+
1. Enable WinRM: `winrm quickconfig` and say Yes.
|
|
74
|
+
2. Set some WinRM settings to ensure that you don't get 401 Unauthorized responses and 500 Responses because of timeouts.
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
winrm set winrm/config/service/auth @{Basic="true"}
|
|
78
|
+
winrm set winrm/config/service @{AllowUnencrypted="true"}
|
|
79
|
+
winrm set winrm/config/service @{EnumerationTimeoutms="600000"}
|
|
80
|
+
winrm set winrm/config @{MaxTimeoutms="600000"}
|
|
81
|
+
winrm set winrm/config/client @{TrustedHosts="*"}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### PowerShell Settings
|
|
85
|
+
|
|
86
|
+
1. You should also configure your PowerShell profile, so that PowerShell commands have a more lenient timeout period.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
mkdir C:\Users\my_user\Documents\WindowsPowerShell
|
|
90
|
+
echo "$PSSessionOption = New-PSSessionOption -OpenTimeout 0 -CancelTimeout 0 -IdleTimeout 0 -OperationTimeout 0" > C:\Users\my_user\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Verify the PowerShell settings by opening up the PowerShell Console and entering `$PSSessionOption` and ensure those values are set, and that there are no errors output.
|
|
94
|
+
|
|
95
|
+
The following links offer some information about configuring a machine's PowerShell settings:
|
|
96
|
+
- [PowerShell Profiles](http://technet.microsoft.com/en-us/library/ee692764.aspx)
|
|
97
|
+
- [The $PSSessionOptions Preference Variable](http://technet.microsoft.com/library/hh847796.aspx)
|
|
98
|
+
- [Creating a new PSSessionOption](http://technet.microsoft.com/en-us/library/hh849703.aspx)
|
|
99
|
+
|
|
100
|
+
You may also want to tweak your Windows boxes a bit more ex: turning UAC off, turning off the Windows Firewall.
|
|
101
|
+
|
|
102
|
+
Authors and Contributors
|
|
103
|
+
------------------------
|
|
104
|
+
- Jamie Winsor (<jamie@vialstudios.com>)
|
|
105
|
+
- Kyle Allan (<kallan@riotgames.com>)
|
|
106
|
+
|
|
107
|
+
Thank you to all of our [Contributors](https://github.com/RiotGames/ridley-connectors/graphs/contributors), testers, and users.
|
data/Thorfile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
|
|
4
|
+
require 'bundler'
|
|
5
|
+
require 'bundler/setup'
|
|
6
|
+
require 'ridley-connectors'
|
|
7
|
+
|
|
8
|
+
class Default < Thor
|
|
9
|
+
|
|
10
|
+
require 'thor/rake_compat'
|
|
11
|
+
|
|
12
|
+
include Thor::RakeCompat
|
|
13
|
+
Bundler::GemHelper.install_tasks
|
|
14
|
+
|
|
15
|
+
desc "build", "Build ridley-connectors-#{Ridley::Connectors::VERSION}.gem into the pkg directory"
|
|
16
|
+
def build
|
|
17
|
+
Rake::Task["build"].execute
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc "install", "Build and install ridley-connectors-#{Ridley::Connectors::VERSION}.gem into system gems"
|
|
21
|
+
def install
|
|
22
|
+
Rake::Task["install"].execute
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc "release", "Create tag v#{Ridley::Connectors::VERSION} and build and push ridley-connectors-#{Ridley::Connectors::VERSION}.gem to Rubygems"
|
|
26
|
+
def release
|
|
27
|
+
Rake::Task["release"].execute
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class Spec < Thor
|
|
31
|
+
namespace :spec
|
|
32
|
+
default_task :all
|
|
33
|
+
|
|
34
|
+
desc "all", "run all tests"
|
|
35
|
+
def all
|
|
36
|
+
exec "rspec --color --format=documentation spec"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Ridley
|
|
2
|
+
class NodeObject
|
|
3
|
+
# Executes a Chef run on the node
|
|
4
|
+
#
|
|
5
|
+
# @return [HostConnector::Response]
|
|
6
|
+
def chef_run
|
|
7
|
+
resource.chef_run(self.public_hostname)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Puts the configured encrypted data bag secret on the node
|
|
11
|
+
#
|
|
12
|
+
# @return [HostConnector::Response]
|
|
13
|
+
def put_secret
|
|
14
|
+
resource.put_secret(self.public_hostname)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Ridley
|
|
2
|
+
class Client
|
|
3
|
+
attr_accessor :ssh
|
|
4
|
+
attr_accessor :winrm
|
|
5
|
+
|
|
6
|
+
# @option options [String] :server_url
|
|
7
|
+
# URL to the Chef API
|
|
8
|
+
# @option options [String] :client_name
|
|
9
|
+
# name of the client used to authenticate with the Chef API
|
|
10
|
+
# @option options [String] :client_key
|
|
11
|
+
# filepath to the client's private key used to authenticate with the Chef API
|
|
12
|
+
# @option options [String] :validator_client (nil)
|
|
13
|
+
# @option options [String] :validator_path (nil)
|
|
14
|
+
# @option options [String] :encrypted_data_bag_secret_path (nil)
|
|
15
|
+
# @option options [Hash] :ssh (Hash.new)
|
|
16
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on (required)
|
|
17
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
18
|
+
# * :keys (Array, String) an array of keys (or a single key) to authenticate the ssh user with instead of a password
|
|
19
|
+
# * :timeout (Float) [5.0] timeout value for SSH bootstrap
|
|
20
|
+
# * :sudo (Boolean) [true] bootstrap with sudo
|
|
21
|
+
# @option options [Hash] :winrm (Hash.new)
|
|
22
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on (required)
|
|
23
|
+
# * :password (String) the password for the user that will perform the bootstrap
|
|
24
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
25
|
+
# @option options [String] :chef_version
|
|
26
|
+
# the version of Chef to use when bootstrapping
|
|
27
|
+
# @option options [Hash] :params
|
|
28
|
+
# URI query unencoded key/value pairs
|
|
29
|
+
# @option options [Hash] :headers
|
|
30
|
+
# unencoded HTTP header key/value pairs
|
|
31
|
+
# @option options [Hash] :request
|
|
32
|
+
# request options
|
|
33
|
+
# @option options [Hash] :ssl
|
|
34
|
+
# * :verify (Boolean) [true] set to false to disable SSL verification
|
|
35
|
+
# @option options [URI, String, Hash] :proxy
|
|
36
|
+
# URI, String, or Hash of HTTP proxy options
|
|
37
|
+
# @option options [Integer] :pool_size (4)
|
|
38
|
+
# size of the connection pool
|
|
39
|
+
#
|
|
40
|
+
# @raise [Errors::ClientKeyFileNotFoundOrInvalid] if the option for :client_key does not contain
|
|
41
|
+
# a file path pointing to a readable client key, or is a string containing a valid key
|
|
42
|
+
alias_method :old_initialize, :initialize
|
|
43
|
+
def initialize(options = {})
|
|
44
|
+
old_initialize(options)
|
|
45
|
+
@options = options.reverse_merge(
|
|
46
|
+
ssh: Hash.new,
|
|
47
|
+
winrm: Hash.new,
|
|
48
|
+
).deep_symbolize_keys
|
|
49
|
+
|
|
50
|
+
@ssh = @options[:ssh]
|
|
51
|
+
@winrm = @options[:winrm]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
module Ridley
|
|
2
|
+
class ConnectorSupervisor < ::Celluloid::SupervisionGroup
|
|
3
|
+
# @param [Celluloid::Registry] registry
|
|
4
|
+
def initialize(registry)
|
|
5
|
+
super(registry)
|
|
6
|
+
supervise_as :ssh, HostConnector::SSH
|
|
7
|
+
supervise_as :winrm, HostConnector::WinRM
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class HostCommander
|
|
12
|
+
include Celluloid
|
|
13
|
+
include Ridley::Logging
|
|
14
|
+
|
|
15
|
+
PORT_CHECK_TIMEOUT = 3
|
|
16
|
+
|
|
17
|
+
finalizer :finalize_callback
|
|
18
|
+
|
|
19
|
+
def initialize
|
|
20
|
+
@connector_registry = Celluloid::Registry.new
|
|
21
|
+
@connector_supervisor = ConnectorSupervisor.new_link(@connector_registry)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Execute a shell command on a node
|
|
25
|
+
#
|
|
26
|
+
# @param [String] host
|
|
27
|
+
# the host to perform the action on
|
|
28
|
+
# @param [String] command
|
|
29
|
+
#
|
|
30
|
+
# @option options [Hash] :ssh
|
|
31
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
|
32
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
33
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
|
34
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
|
35
|
+
# * :sudo (Boolean) run as sudo
|
|
36
|
+
# @option options [Hash] :winrm
|
|
37
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
|
38
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
|
39
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
40
|
+
#
|
|
41
|
+
# @return [HostConnector::Response]
|
|
42
|
+
def run(host, command, options = {})
|
|
43
|
+
execute(__method__, host, command, options)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Bootstrap a node
|
|
47
|
+
#
|
|
48
|
+
# @param [String] host
|
|
49
|
+
# the host to perform the action on
|
|
50
|
+
#
|
|
51
|
+
# @option options [Hash] :ssh
|
|
52
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
|
53
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
54
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
|
55
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
|
56
|
+
# * :sudo (Boolean) run as sudo
|
|
57
|
+
# @option options [Hash] :winrm
|
|
58
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
|
59
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
|
60
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
61
|
+
#
|
|
62
|
+
# @return [HostConnector::Response]
|
|
63
|
+
def bootstrap(host, options = {})
|
|
64
|
+
execute(__method__, host, options)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Perform a chef client run on a node
|
|
68
|
+
#
|
|
69
|
+
# @param [String] host
|
|
70
|
+
# the host to perform the action on
|
|
71
|
+
#
|
|
72
|
+
# @option options [Hash] :ssh
|
|
73
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
|
74
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
75
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
|
76
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
|
77
|
+
# * :sudo (Boolean) run as sudo
|
|
78
|
+
# @option options [Hash] :winrm
|
|
79
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
|
80
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
|
81
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
82
|
+
#
|
|
83
|
+
# @return [HostConnector::Response]
|
|
84
|
+
def chef_client(host, options = {})
|
|
85
|
+
execute(__method__, host, options)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Write your encrypted data bag secret on a node
|
|
89
|
+
#
|
|
90
|
+
# @param [String] host
|
|
91
|
+
# the host to perform the action on
|
|
92
|
+
# @param [String] secret
|
|
93
|
+
# your organization's encrypted data bag secret
|
|
94
|
+
#
|
|
95
|
+
# @option options [Hash] :ssh
|
|
96
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
|
97
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
98
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
|
99
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
|
100
|
+
# * :sudo (Boolean) run as sudo
|
|
101
|
+
# @option options [Hash] :winrm
|
|
102
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
|
103
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
|
104
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
105
|
+
#
|
|
106
|
+
# @return [HostConnector::Response]
|
|
107
|
+
def put_secret(host, secret, options = {})
|
|
108
|
+
execute(__method__, host, secret, options)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Execute line(s) of Ruby code on a node using Chef's embedded Ruby
|
|
112
|
+
#
|
|
113
|
+
# @param [String] host
|
|
114
|
+
# the host to perform the action on
|
|
115
|
+
# @param [Array<String>] command_lines
|
|
116
|
+
# An Array of lines of the command to be executed
|
|
117
|
+
#
|
|
118
|
+
# @option options [Hash] :ssh
|
|
119
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
|
120
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
121
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
|
122
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
|
123
|
+
# * :sudo (Boolean) run as sudo
|
|
124
|
+
# @option options [Hash] :winrm
|
|
125
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
|
126
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
|
127
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
128
|
+
#
|
|
129
|
+
# @return [HostConnector::Response]
|
|
130
|
+
def ruby_script(host, command_lines, options = {})
|
|
131
|
+
execute(__method__, host, command_lines, options)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Uninstall Chef from a node
|
|
135
|
+
#
|
|
136
|
+
# @param [String] host
|
|
137
|
+
# the host to perform the action on
|
|
138
|
+
#
|
|
139
|
+
# @option options [Boolena] :skip_chef (false)
|
|
140
|
+
# skip removal of the Chef package and the contents of the installation
|
|
141
|
+
# directory. Setting this to true will only remove any data and configurations
|
|
142
|
+
# generated by running Chef client.
|
|
143
|
+
# @option options [Hash] :ssh
|
|
144
|
+
# * :user (String) a shell user that will login to each node and perform the bootstrap command on
|
|
145
|
+
# * :password (String) the password for the shell user that will perform the bootstrap
|
|
146
|
+
# * :keys (Array, String) an array of key(s) to authenticate the ssh user with instead of a password
|
|
147
|
+
# * :timeout (Float) timeout value for SSH bootstrap (5.0)
|
|
148
|
+
# * :sudo (Boolean) run as sudo (true)
|
|
149
|
+
# @option options [Hash] :winrm
|
|
150
|
+
# * :user (String) a user that will login to each node and perform the bootstrap command on
|
|
151
|
+
# * :password (String) the password for the user that will perform the bootstrap (required)
|
|
152
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
153
|
+
#
|
|
154
|
+
# @return [HostConnector::Response]
|
|
155
|
+
def uninstall_chef(host, options = {})
|
|
156
|
+
execute(__method__, host, options)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Finds and returns the best HostConnector for a given host
|
|
160
|
+
#
|
|
161
|
+
# @param [String] host
|
|
162
|
+
# the host to attempt to connect to
|
|
163
|
+
# @option options [Hash] :ssh
|
|
164
|
+
# * :port (Fixnum) the ssh port to connect on the node the bootstrap will be performed on (22)
|
|
165
|
+
# * :timeout (Float) [5.0] timeout value for testing SSH connection
|
|
166
|
+
# @option options [Hash] :winrm
|
|
167
|
+
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
|
|
168
|
+
# @param block [Proc]
|
|
169
|
+
# an optional block that is yielded the best HostConnector
|
|
170
|
+
#
|
|
171
|
+
# @return [HostConnector::SSH, HostConnector::WinRM]
|
|
172
|
+
def connector_for(host, options = {})
|
|
173
|
+
options = options.reverse_merge(ssh: Hash.new, winrm: Hash.new)
|
|
174
|
+
options[:ssh][:port] ||= HostConnector::SSH::DEFAULT_PORT
|
|
175
|
+
options[:winrm][:port] ||= HostConnector::WinRM::DEFAULT_PORT
|
|
176
|
+
|
|
177
|
+
if connector_port_open?(host, options[:winrm][:port])
|
|
178
|
+
options.delete(:ssh)
|
|
179
|
+
winrm
|
|
180
|
+
elsif connector_port_open?(host, options[:ssh][:port], options[:ssh][:timeout])
|
|
181
|
+
options.delete(:winrm)
|
|
182
|
+
ssh
|
|
183
|
+
else
|
|
184
|
+
raise Errors::HostConnectionError, "No connector ports open on '#{host}'"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
private
|
|
189
|
+
|
|
190
|
+
def execute(method, host, *args)
|
|
191
|
+
options = args.last.is_a?(Hash) ? args.pop : Hash.new
|
|
192
|
+
|
|
193
|
+
connector_for(host, options).send(method, host, *args, options)
|
|
194
|
+
rescue Errors::HostConnectionError => ex
|
|
195
|
+
abort(ex)
|
|
196
|
+
rescue Resolv::ResolvError => ex
|
|
197
|
+
abort Errors::DNSResolvError.new(ex)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Checks to see if the given port is open for TCP connections
|
|
201
|
+
# on the given host.
|
|
202
|
+
#
|
|
203
|
+
# @param [String] host
|
|
204
|
+
# the host to attempt to connect to
|
|
205
|
+
# @param [Fixnum] port
|
|
206
|
+
# the port to attempt to connect on
|
|
207
|
+
# @param [Float] wait_time ({PORT_CHECK_TIMEOUT})
|
|
208
|
+
# the number of seconds to wait
|
|
209
|
+
#
|
|
210
|
+
# @return [Boolean]
|
|
211
|
+
def connector_port_open?(host, port, wait_time = nil)
|
|
212
|
+
defer {
|
|
213
|
+
Timeout.timeout(wait_time || PORT_CHECK_TIMEOUT) { Celluloid::IO::TCPSocket.new(host, port).close; true }
|
|
214
|
+
}
|
|
215
|
+
rescue Errno::ETIMEDOUT, Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EADDRNOTAVAIL => ex
|
|
216
|
+
false
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def finalize_callback
|
|
220
|
+
@connector_supervisor.async.terminate if @connector_supervisor && @connector_supervisor.alive?
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def ssh
|
|
224
|
+
@connector_registry[:ssh]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def winrm
|
|
228
|
+
@connector_registry[:winrm]
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Ridley
|
|
2
|
+
module HostConnector
|
|
3
|
+
class Response
|
|
4
|
+
attr_reader :host
|
|
5
|
+
|
|
6
|
+
attr_accessor :stdout
|
|
7
|
+
attr_accessor :stderr
|
|
8
|
+
attr_accessor :exit_code
|
|
9
|
+
attr_accessor :exit_signal
|
|
10
|
+
|
|
11
|
+
def initialize(host, options = {})
|
|
12
|
+
@host = host
|
|
13
|
+
@stdout = options[:stdout] || String.new
|
|
14
|
+
@stderr = options[:stderr] || String.new
|
|
15
|
+
@exit_code = options[:exit_code] || -1
|
|
16
|
+
@exit_signal = options[:exit_signal] || nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Return true if the response was not successful
|
|
20
|
+
#
|
|
21
|
+
# @return [Boolean]
|
|
22
|
+
def error?
|
|
23
|
+
self.exit_code != 0
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|