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
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
|
+
[![Gem Version](https://badge.fury.io/rb/ridley-connectors.png)](http://badge.fury.io/rb/ridley-connectors)
|
3
|
+
[![Build Status](https://secure.travis-ci.org/RiotGames/ridley-connectors.png?branch=master)](http://travis-ci.org/RiotGames/ridley-connectors)
|
4
|
+
[![Dependency Status](https://gemnasium.com/RiotGames/ridley-connectors.png?travis)](https://gemnasium.com/RiotGames/ridley-connectors)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/RiotGames/ridley-connectors.png)](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
|