chef-metal-ssh 0.0.2
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.
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +1 -0
- data/lib/chef_metal/provisioner_init/ssh_init.rb +4 -0
- data/lib/chef_metal_ssh.rb +2 -0
- data/lib/chef_metal_ssh/ssh_provisioner.rb +232 -0
- data/lib/chef_metal_ssh/version.rb +3 -0
- metadata +108 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 double-z
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# ChefMetalSsh
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'chef-metal-ssh'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install chef-metal-ssh
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
machine "one" do
|
22
|
+
action :create
|
23
|
+
converge true
|
24
|
+
provisioner ChefMetalSsh::SshProvisioner.new
|
25
|
+
provisioner_options 'target_ip' => '192.168.33.21',
|
26
|
+
'ssh_user' => 'vagrant',
|
27
|
+
'ssh_connect_options' => {
|
28
|
+
'ssh_pass' => 'vagrant'
|
29
|
+
}
|
30
|
+
recipe 'ssh_test::remote1'
|
31
|
+
notifies :create, 'machine[two]'
|
32
|
+
notifies :run, 'execute[run_touch1]'
|
33
|
+
end
|
34
|
+
|
35
|
+
To test it out, clone the repo:
|
36
|
+
|
37
|
+
`git clone https://github.com/double-z/chef-metal-ssh.git`
|
38
|
+
|
39
|
+
in the root there is a Vagrantfile with 3 nodes, 1 master and 2 targets. Run:
|
40
|
+
|
41
|
+
first run:
|
42
|
+
|
43
|
+
`rake build`
|
44
|
+
|
45
|
+
from the repo root to build the gem in the repo root `./pkg/` directory. then run:
|
46
|
+
|
47
|
+
`vagrant up`
|
48
|
+
|
49
|
+
which will bring up all 3 nodes. FYI, nothing will get installed on your local machine in this proces. So then ssh to the master:
|
50
|
+
|
51
|
+
`vagrant ssh master`
|
52
|
+
|
53
|
+
the repo test directory has a test cookbook and `run_zero` script. its located at `/vagrant/test`
|
54
|
+
|
55
|
+
cd into it:
|
56
|
+
|
57
|
+
`cd /vagrant/test`
|
58
|
+
|
59
|
+
then run:
|
60
|
+
|
61
|
+
`bash run_zero install`
|
62
|
+
|
63
|
+
this will install the prereqs. then run:
|
64
|
+
|
65
|
+
`bash run_zero both`
|
66
|
+
|
67
|
+
this will run the `ssh_test::both` recipe which will converge both targets, with target one
|
68
|
+
notifying target two. target one will converge the `ssh_test::remote1` recipe, target two the `ssh_test::remote2` recipe.
|
69
|
+
|
70
|
+
thats it.
|
71
|
+
|
72
|
+
party on wayne.
|
73
|
+
|
74
|
+
## Contributing
|
75
|
+
|
76
|
+
1. Fork it ( http://github.com/double-z/chef-metal-ssh/fork )
|
77
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
78
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
79
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
80
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'chef_metal/provisioner'
|
2
|
+
require 'chef_metal/version'
|
3
|
+
require 'chef_metal/machine/basic_machine'
|
4
|
+
require 'chef_metal/machine/unix_machine'
|
5
|
+
require 'chef_metal/convergence_strategy/install_cached'
|
6
|
+
require 'chef_metal/transport/ssh'
|
7
|
+
|
8
|
+
module ChefMetalSsh
|
9
|
+
# Provisions machines with ssh.
|
10
|
+
class SshProvisioner < ChefMetal::Provisioner
|
11
|
+
|
12
|
+
def initialize(target_host=nil)
|
13
|
+
@target_host = target_host
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :target_host
|
17
|
+
|
18
|
+
# Acquire a machine, generally by provisioning it. Returns a Machine
|
19
|
+
# object pointing at the machine, allowing useful actions like setup,
|
20
|
+
# converge, execute, file and directory. The Machine object will have a
|
21
|
+
# "node" property which must be saved to the server (if it is any
|
22
|
+
# different from the original node object).
|
23
|
+
#
|
24
|
+
# ## Parameters
|
25
|
+
# action_handler - the action_handler object that provides context.
|
26
|
+
# node - node object (deserialized json) representing this machine. If
|
27
|
+
# the node has a provisioner_options hash in it, these will be used
|
28
|
+
# instead of options provided by the provisioner. TODO compare and
|
29
|
+
# fail if different?
|
30
|
+
# node will have node['normal']['provisioner_options'] in it with any options.
|
31
|
+
# It is a hash with this format:
|
32
|
+
#
|
33
|
+
# -- provisioner_url: ssh:<ssh_path>
|
34
|
+
# -- target_ip: the IP address of the target machine - IP or FQDN is required
|
35
|
+
# -- target_fqdn: The Resolvable name of the target machine - IP or FQDN is required
|
36
|
+
# -- ssh_user: the user to ssh as
|
37
|
+
# -- ssh_config: options to pass the ssh command. available options are here - https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh.rb#L61
|
38
|
+
#
|
39
|
+
# node['normal']['provisioner_output'] will be populated with information
|
40
|
+
# about the created machine. For ssh, it is a hash with this
|
41
|
+
# format:
|
42
|
+
#
|
43
|
+
# -- provisioner_url: ssh:<ssh_path>
|
44
|
+
# -- name: container name
|
45
|
+
#
|
46
|
+
def acquire_machine(action_handler, node)
|
47
|
+
# TODO verify that the existing provisioner_url in the node is the same as ours
|
48
|
+
|
49
|
+
# Set up the modified node data
|
50
|
+
provisioner_options = node['normal']['provisioner_options']
|
51
|
+
|
52
|
+
Chef::Log.debug("======================================>")
|
53
|
+
Chef::Log.debug("acquire_machine - provisioner_options.inspect: #{provisioner_options.inspect}")
|
54
|
+
Chef::Log.debug("======================================>")
|
55
|
+
|
56
|
+
if @target_host.nil?
|
57
|
+
target_host = get_target_connection_method(node)
|
58
|
+
@target_host = target_host
|
59
|
+
end
|
60
|
+
|
61
|
+
Chef::Log.debug("======================================>")
|
62
|
+
Chef::Log.debug("acquire_machine - target_host: #{target_host}")
|
63
|
+
Chef::Log.debug("======================================>")
|
64
|
+
|
65
|
+
# Set up Provisioner Output
|
66
|
+
# TODO - make url the chef server url path? maybe disk path if zero?
|
67
|
+
provisioner_output = node['normal']['provisioner_output'] || {
|
68
|
+
'provisioner_url' => "ssh:#{target_host}",
|
69
|
+
'name' => node['name']
|
70
|
+
}
|
71
|
+
|
72
|
+
Chef::Log.debug("======================================>")
|
73
|
+
Chef::Log.debug("acquire_machine - provisioner_output.inspect: #{provisioner_output.inspect}")
|
74
|
+
Chef::Log.debug("======================================>")
|
75
|
+
|
76
|
+
node['normal']['provisioner_output'] = provisioner_output
|
77
|
+
|
78
|
+
# Create machine object for callers to use
|
79
|
+
machine_for(node)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Connect to machine without acquiring it
|
83
|
+
def connect_to_machine(node)
|
84
|
+
if @target_host.nil?
|
85
|
+
target_host = get_target_connection_method(node)
|
86
|
+
@target_host = target_host
|
87
|
+
end
|
88
|
+
|
89
|
+
Chef::Log.debug("======================================>")
|
90
|
+
Chef::Log.debug("connect_to_machine - target_host: #{target_host}")
|
91
|
+
Chef::Log.debug("======================================>")
|
92
|
+
|
93
|
+
machine_for(node)
|
94
|
+
end
|
95
|
+
|
96
|
+
def delete_machine(action_handler, node)
|
97
|
+
convergence_strategy_for(node).delete_chef_objects(action_handler, node)
|
98
|
+
end
|
99
|
+
|
100
|
+
def stop_machine(action_handler, node)
|
101
|
+
# What to do What to do.
|
102
|
+
# On one level there's really only one thing to do here,
|
103
|
+
# shellout and halt, or shutdown -h now,
|
104
|
+
# maybe provide abitily to pass some shutdown options
|
105
|
+
# But be vewwy vewwy careful, you better have console,
|
106
|
+
# or be close to your datacenter
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def restart_machine(action_handler, node)
|
111
|
+
# Full Restart, POST BIOS and all
|
112
|
+
end
|
113
|
+
|
114
|
+
def reload_machine(action_handler, node)
|
115
|
+
# Use `kexec` here to skip POST and BIOS and all that noise.
|
116
|
+
end
|
117
|
+
|
118
|
+
# Not meant to be part of public interface
|
119
|
+
def transport_for(node)
|
120
|
+
create_ssh_transport(node)
|
121
|
+
end
|
122
|
+
|
123
|
+
protected
|
124
|
+
|
125
|
+
def get_target_connection_method(node)
|
126
|
+
|
127
|
+
provisioner_options = node['normal']['provisioner_options']
|
128
|
+
|
129
|
+
target_ip = ''
|
130
|
+
target_ip = provisioner_options['target_ip'] || nil
|
131
|
+
|
132
|
+
target_fqdn = ''
|
133
|
+
target_fqdn = provisioner_options['target_fqdn'] || nil
|
134
|
+
|
135
|
+
remote_host = ''
|
136
|
+
if @target_host
|
137
|
+
remote_host = @target_host
|
138
|
+
elsif target_ip
|
139
|
+
remote_host = target_ip
|
140
|
+
elsif target_fqdn
|
141
|
+
remote_host = target_fqdn
|
142
|
+
else
|
143
|
+
raise "aint got no target yo, that dog dont hunt"
|
144
|
+
end
|
145
|
+
|
146
|
+
Chef::Log.debug("======================================>")
|
147
|
+
Chef::Log.debug("get_target_connection_method - remote_host: #{remote_host}")
|
148
|
+
Chef::Log.debug("======================================>")
|
149
|
+
|
150
|
+
remote_host
|
151
|
+
end
|
152
|
+
|
153
|
+
def machine_for(node)
|
154
|
+
ChefMetal::Machine::UnixMachine.new(node, transport_for(node), convergence_strategy_for(node))
|
155
|
+
end
|
156
|
+
|
157
|
+
def convergence_strategy_for(node)
|
158
|
+
@convergence_strategy ||= begin
|
159
|
+
ChefMetal::ConvergenceStrategy::InstallCached.new
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Setup Ssh
|
164
|
+
def create_ssh_transport(node)
|
165
|
+
# TODO - verify target_host resolves
|
166
|
+
# Verify Valid IP
|
167
|
+
|
168
|
+
provisioner_options = node['normal']['provisioner_options']
|
169
|
+
|
170
|
+
##
|
171
|
+
# Ssh Target
|
172
|
+
target_host = ''
|
173
|
+
target_host = @target_host
|
174
|
+
|
175
|
+
Chef::Log.debug("======================================>")
|
176
|
+
Chef::Log.debug("create_ssh_transport - target_host: #{target_host}")
|
177
|
+
Chef::Log.debug("======================================>")
|
178
|
+
|
179
|
+
##
|
180
|
+
# Ssh Username
|
181
|
+
username = ''
|
182
|
+
username = provisioner_options['ssh_user'] || 'vagrant'
|
183
|
+
|
184
|
+
Chef::Log.debug("======================================>")
|
185
|
+
Chef::Log.debug("create_ssh_transport - username: #{username}")
|
186
|
+
Chef::Log.debug("======================================>")
|
187
|
+
|
188
|
+
##
|
189
|
+
# Ssh Password
|
190
|
+
ssh_pass = ''
|
191
|
+
ssh_pass = provisioner_options['ssh_connect_options']['ssh_pass']
|
192
|
+
|
193
|
+
Chef::Log.debug("======================================>")
|
194
|
+
Chef::Log.debug("create_ssh_transport - ssh_pass: #{ssh_pass}")
|
195
|
+
Chef::Log.debug("======================================>")
|
196
|
+
|
197
|
+
##
|
198
|
+
# Ssh Main Options
|
199
|
+
ssh_options = {}
|
200
|
+
ssh_options = {
|
201
|
+
# TODO create a user known hosts file
|
202
|
+
# :user_known_hosts_file => provisioner_options['ssh_connect_options']['UserKnownHostsFile'],
|
203
|
+
# :paranoid => true,
|
204
|
+
# :auth_methods => [ 'publickey' ],
|
205
|
+
:keys_only => false,
|
206
|
+
:password => ssh_pass
|
207
|
+
}
|
208
|
+
|
209
|
+
Chef::Log.debug("======================================>")
|
210
|
+
Chef::Log.debug("create_ssh_transport - ssh_options: #{ssh_options.inspect}")
|
211
|
+
Chef::Log.debug("======================================>")
|
212
|
+
|
213
|
+
|
214
|
+
##
|
215
|
+
# Ssh Additional Options
|
216
|
+
options = {}
|
217
|
+
#Enable pty by default
|
218
|
+
options[:ssh_pty_enable] = true
|
219
|
+
|
220
|
+
if username != 'root'
|
221
|
+
options[:prefix] = 'sudo '
|
222
|
+
end
|
223
|
+
|
224
|
+
Chef::Log.debug("======================================>")
|
225
|
+
Chef::Log.debug("create_ssh_transport - options: #{options.inspect}")
|
226
|
+
Chef::Log.debug("======================================>")
|
227
|
+
|
228
|
+
ChefMetal::Transport::SSH.new(target_host, username, ssh_options, options)
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chef-metal-ssh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Zack Zondlo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: chef
|
16
|
+
requirement: &6594860 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *6594860
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: chef-metal
|
27
|
+
requirement: &6650460 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.6'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *6650460
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: bundler
|
38
|
+
requirement: &6649080 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.5'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *6649080
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &6647280 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *6647280
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rake
|
60
|
+
requirement: &6077260 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *6077260
|
69
|
+
description: Provisioner for converging servers using ssh ssh in Chef Metal.
|
70
|
+
email: zackzondlo@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- README.md
|
75
|
+
- LICENSE.txt
|
76
|
+
files:
|
77
|
+
- Rakefile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- lib/chef_metal/provisioner_init/ssh_init.rb
|
81
|
+
- lib/chef_metal_ssh.rb
|
82
|
+
- lib/chef_metal_ssh/ssh_provisioner.rb
|
83
|
+
- lib/chef_metal_ssh/version.rb
|
84
|
+
homepage: https://github.com/double-z/chef-metal-ssh
|
85
|
+
licenses: []
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.8.11
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Provisioner for converging servers using ssh ssh in Chef Metal.
|
108
|
+
test_files: []
|