chef-metal-ssh 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,4 @@
1
+ require 'chef_metal_ssh/ssh_provisioner'
2
+
3
+ ChefMetal.add_registered_provisioner_class("ssh",
4
+ ChefMetalSsh::SshProvisioner)
@@ -0,0 +1,2 @@
1
+ require 'chef_metal'
2
+ require 'chef_metal_ssh/ssh_provisioner'
@@ -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
@@ -0,0 +1,3 @@
1
+ module ChefMetalSsh
2
+ VERSION = "0.0.2"
3
+ 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: []