chef-provisioning-ssh 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d97758ed8f160bf3594de4ef5ca71e6f73b10766
4
- data.tar.gz: 995af6965a59c982e8fbb3258145ddb74191aa24
3
+ metadata.gz: 69a88cd11bc933287de011039d2e16e43b4ffbc1
4
+ data.tar.gz: 5eea7c73c739a5b6927a87a3acafd1ae8e5ed9ee
5
5
  SHA512:
6
- metadata.gz: 73f0585fc98cc33ce6717419e86e805eea247d138f510a11e8d045e3d200ccaab0c228f15de97a4934ccac501f04783585984330b803ab60ae65c60a4f577376
7
- data.tar.gz: 590f81c78ebcd3b6ddf22e9961907c843a6bb734ab28ddca225edd14b2c4adacb47e13404203a1e7149b936909d28114050d7266e6d6ee16fc59ac57f0d018b9
6
+ metadata.gz: e9dce79bf1c666461cca81e59aa0e9a3aad48aa02f5d477114b14176aa5af3679e8edded22c25fd1fc981bda1db9950f17cf1566fa41387f3adbc3e7c0700331
7
+ data.tar.gz: 7be88e2785e107272b8459b27a13a79405c20ad50c1af8d207ed57bd9de4902ec459fd81d2132dc3537a8ff0ea15a42df73ff38329e8e4171e02698185471b41
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chef-provisioning-ssh.gemspec
4
+ gemspec
data/README.md CHANGED
@@ -1,181 +1,197 @@
1
- [![Gem Version](https://badge.fury.io/rb/chef-provisioning-ssh.svg)](http://badge.fury.io/rb/chef-provisioning-ssh)
2
-
3
1
  # Chef::Provisioning::Ssh
4
2
 
5
- TODO: Write a gem description
3
+ [![Build Status](https://travis-ci.org/chef/chef-provisioning-ssh.svg?branch=master)](https://travis-ci.org/chef/chef-provisioning-ssh) [![Gem Version](https://badge.fury.io/rb/chef-provisioning-ssh.svg)](http://badge.fury.io/rb/chef-provisioning-ssh)
4
+
5
+ Provisions existing machines using SSH.
6
6
 
7
7
  ## Installation
8
8
 
9
9
  Add this line to your application's Gemfile:
10
- e
10
+
11
11
  ```ruby
12
12
  gem 'chef-provisioning-ssh'
13
13
  ```
14
14
 
15
15
  And then execute:
16
16
 
17
- $ bundle
17
+ ```
18
+ $ bundle
19
+ ```
18
20
 
19
21
  Or install it yourself as:
20
22
 
21
- $ gem install chef-provisioning-ssh
23
+ ```
24
+ $ gem install chef-provisioning-ssh
25
+ ```
22
26
 
23
27
  ## Usage
24
28
 
25
- The `machine_options` for provisioning ssh now use the key `transport_options` which line up directly with the `transport_options` for chef-provisioning proper.
29
+ ### driver_url
26
30
 
27
- The `transport_options` key must be a *symbol*.
31
+ - `with_driver 'ssh'` will store machine data in a file in the directory `.chef/provisioning/ssh` on the provisioning machine, with a reference to the file in the node attribute `node['chef_provisioning']['reference']['ssh_machine_file']`
32
+ - `with_driver 'ssh:/some/path'` will store machine data in the specified directory, with a reference to the file as above.
33
+ - `with_driver 'ssh:chef'` will store all machine data in the node attribute `node['chef_provisioning']['reference']`.
28
34
 
29
- Sub-keys should be *strings*.
35
+ ### machine_options
30
36
 
31
- The transport_options can be viewed in the code for chef-provisioning here:
37
+ The `machine_options` for provisioning ssh now use the key `transport_options` which line up directly with the `transport_options` for chef-provisioning proper.
32
38
 
33
- https://github.com/chef/chef-provisioning/blob/master/lib/chef/provisioning/transport/ssh.rb#L17-L34
34
-
35
- The snippet from that link is:
39
+ The `transport_options` key and sub-keys may be strings or symbols.
36
40
 
37
- - host: the host to connect to, e.g. '145.14.51.45'
38
- - username: the username to connect with
39
- - ssh_options: a list of options to Net::SSH.start
40
- - options: a hash of options for the transport itself, including:
41
- - :prefix: a prefix to send before each command (e.g. "sudo ")
42
- - :ssh_pty_enable: set to false to disable pty (some instances don't
43
- support this, most do)
44
- - :ssh_gateway: the gateway to use, e.g. "jkeiser@145.14.51.45:222".
45
- nil (the default) means no gateway. If the username is omitted,
46
- then the default username is used instead (i.e. the user running
47
- chef, or the username configured in .ssh/config).
48
-
49
- The options are used in
50
- Net::SSH.start(host, username, ssh_options, options)
41
+ The `transport_options` can be viewed in the code for chef-provisioning here:
51
42
 
52
- In addition to host, ip_address and hostname are also additional options.
43
+ <https://github.com/chef/chef-provisioning/blob/master/lib/chef/provisioning/transport/ssh.rb#L17-L34>
53
44
 
54
- * the `ssh_options` key accepts options from Net::SSH.start, the full list can be seen here:
45
+ The snippet from that link is:
55
46
 
56
- http://net-ssh.github.io/ssh/v2/api/classes/Net/SSH.html#M000002
47
+ ```
48
+ - host: the host to connect to, e.g. '145.14.51.45'
49
+ - username: the username to connect with
50
+ - ssh_options: a list of options to Net::SSH.start
51
+ - options: a hash of options for the transport itself, including:
52
+ - :prefix: a prefix to send before each command (e.g. "sudo ")
53
+ - :ssh_pty_enable: set to false to disable pty (some instances don't
54
+ support this, most do)
55
+ - :ssh_gateway: the gateway to use, e.g. "jkeiser@145.14.51.45:222".
56
+ nil (the default) means no gateway. If the username is omitted,
57
+ then the default username is used instead (i.e. the user running
58
+ chef, or the username configured in .ssh/config).
59
+
60
+ The options are used in
61
+ Net::SSH.start(host, username, ssh_options, options)
62
+ ```
57
63
 
58
- * full machine_options for SSH example:
64
+ In addition to host, ip_address and hostname are also additional options.
59
65
 
60
- with_machine_options :transport_options => {
61
- 'is_windows' => false,
62
- 'ip_address' => '192.168.33.23',
63
- 'host' => 'somehost',
64
- 'username' => 'vagrant',
65
- 'ssh_options' => {
66
- 'auth_methods' => '',
67
- 'bind_address' => '',
68
- 'compression' => '',
69
- 'compression_level' => '',
70
- 'config' => '',
71
- 'encryption' => '',
72
- 'forward_agent' => '',
73
- 'hmac' => '',
74
- 'host_key' => '',
75
- 'keepalive' => '',
76
- 'keepalive_interval' => '',
77
- 'kex' => '',
78
- 'keys' => ['/home/username/.vagrant.d/insecure_private_key'],
79
- 'key_data' => '',
80
- 'languages' => '',
81
- 'logger' => '',
82
- 'paranoid' => '',
83
- 'password' => '',
84
- 'port' => '',
85
- 'proxy' => '',
86
- 'rekey_blocks_limit' => '',
87
- 'rekey_limit' => '',
88
- 'rekey_packet_limit' => '',
89
- 'timeout' => '',
90
- 'verbose' => '',
91
- 'global_known_hosts_file' => '',
92
- 'user_known_hosts_file' => '',
93
- 'host_key_alias' => '',
94
- 'host_name' => '',
95
- 'user' => '',
96
- 'properties' => '',
97
- 'passphrase' => '',
98
- 'keys_only' => '',
99
- 'max_pkt_size' => '',
100
- 'max_win_size, :send_env' => '',
101
- 'use_agent' => ''
102
- },
103
- 'options' => {
104
- 'prefix' => 'sudo ',
105
- 'ssh_pty_enable' => false,
106
- 'ssh_gateway' => 'yourgateway'
107
- }
108
- }
109
-
110
- * full machine_options for WinRM example:
111
-
112
- with_machine_options :transport_options => {
113
- 'is_windows' => true,
114
- 'host' => '192.168.33.23',
115
- 'port' => 5985,
116
- 'username' => 'vagrant',
117
- 'password' => 'vagrant'
118
- }
119
-
120
-
121
- * machine resource example:
122
-
123
- require 'chef/provisioning/ssh_driver'
124
-
125
- with_driver 'ssh'
126
-
127
- machine "ssh" do
128
- action [:ready, :setup, :converge]
129
- machine_options :transport_options => {
130
- 'ip_address' => '192.168.33.22',
131
- 'username' => 'vagrant',
132
- 'ssh_options' => {
133
- 'password' => 'vagrant'
134
- }
135
- }
136
- recipe 'vagrant::sshone'
137
- converge true
138
- end
139
-
140
- ##
141
- # With WinRM you must use a remote chef-server
142
- # local-mode chef server is not currently supported
143
-
144
- with_chef_server "https://api.opscode.com/organizations/double-z",
145
- :client_name => Chef::Config[:node_name],
146
- :signing_key_filename => Chef::Config[:client_key]
147
-
148
- machine "winrm" do
149
- action [:ready, :setup, :converge]
150
- machine_options :transport_options => {
151
- 'is_windows' => true,
152
- 'host' => '192.168.33.23',
66
+ - the `ssh_options` key accepts options from Net::SSH.start, the full list can be seen here:
67
+
68
+ <http://net-ssh.github.io/ssh/v2/api/classes/Net/SSH.html#M000002>
69
+
70
+ - full machine_options for SSH example:
71
+
72
+ ```ruby
73
+ with_machine_options :transport_options => {
74
+ 'is_windows' => false,
75
+ 'ip_address' => '192.168.33.23',
76
+ 'host' => 'somehost',
77
+ 'username' => 'vagrant',
78
+ 'ssh_options' => {
79
+ 'auth_methods' => '',
80
+ 'bind_address' => '',
81
+ 'compression' => '',
82
+ 'compression_level' => '',
83
+ 'config' => '',
84
+ 'encryption' => '',
85
+ 'forward_agent' => '',
86
+ 'hmac' => '',
87
+ 'host_key' => '',
88
+ 'keepalive' => '',
89
+ 'keepalive_interval' => '',
90
+ 'kex' => '',
91
+ 'keys' => ['/home/username/.vagrant.d/insecure_private_key'],
92
+ 'key_data' => '',
93
+ 'languages' => '',
94
+ 'logger' => '',
95
+ 'paranoid' => '',
96
+ 'password' => '',
97
+ 'port' => '',
98
+ 'proxy' => '',
99
+ 'rekey_blocks_limit' => '',
100
+ 'rekey_limit' => '',
101
+ 'rekey_packet_limit' => '',
102
+ 'timeout' => '',
103
+ 'verbose' => '',
104
+ 'global_known_hosts_file' => '',
105
+ 'user_known_hosts_file' => '',
106
+ 'host_key_alias' => '',
107
+ 'host_name' => '',
108
+ 'user' => '',
109
+ 'properties' => '',
110
+ 'passphrase' => '',
111
+ 'keys_only' => '',
112
+ 'max_pkt_size' => '',
113
+ 'max_win_size, :send_env' => '',
114
+ 'use_agent' => ''
115
+ },
116
+ 'options' => {
117
+ 'prefix' => 'sudo ',
118
+ 'ssh_pty_enable' => false,
119
+ 'ssh_gateway' => 'yourgateway'
120
+ }
121
+ }
122
+ ```
123
+
124
+ - full machine_options for WinRM example:
125
+
126
+ ```ruby
127
+ with_machine_options :transport_options => {
128
+ 'is_windows' => true,
129
+ 'host' => '192.168.33.23',
153
130
  'port' => 5985,
154
- 'username' => 'vagrant',
155
- 'password' => 'vagrant'
156
- }
157
- recipe 'windows'
158
- converge true
159
- end
160
-
131
+ 'username' => 'vagrant',
132
+ 'password' => 'vagrant'
133
+ }
134
+ ```
135
+
136
+ - machine resource example:
137
+
138
+ ```ruby
139
+ require 'chef/provisioning/ssh_driver'
140
+
141
+ with_driver 'ssh'
142
+
143
+ machine "ssh" do
144
+ action [:ready, :setup, :converge]
145
+ machine_options :transport_options => {
146
+ 'ip_address' => '192.168.33.22',
147
+ 'username' => 'vagrant',
148
+ 'ssh_options' => {
149
+ 'password' => 'vagrant'
150
+ }
151
+ }
152
+ recipe 'vagrant::sshone'
153
+ converge true
154
+ end
155
+
156
+ ##
157
+ # With WinRM you must use a remote chef-server
158
+ # local-mode chef server is not currently supported
159
+
160
+ with_chef_server "https://api.opscode.com/organizations/double-z",
161
+ :client_name => Chef::Config[:node_name],
162
+ :signing_key_filename => Chef::Config[:client_key]
163
+
164
+ machine "winrm" do
165
+ action [:ready, :setup, :converge]
166
+ machine_options :transport_options => {
167
+ 'is_windows' => true,
168
+ 'host' => '192.168.33.23',
169
+ 'port' => 5985,
170
+ 'username' => 'vagrant',
171
+ 'password' => 'vagrant'
172
+ }
173
+ recipe 'windows'
174
+ converge true
175
+ end
176
+ ```
161
177
 
162
178
  To test it out, clone the repo:
163
179
 
164
- `git clone https://github.com/double-z/chef-provisioning-ssh.git`
180
+ `git clone https://github.com/chef/chef-provisioning-ssh.git`
165
181
 
166
- in the test directory there is a Vagrantfile with 2 nodes.
182
+ in the test directory there is a Vagrantfile with 2 nodes.
167
183
 
168
184
  Run:
169
185
 
170
186
  `vagrant up`
171
187
 
172
- which will bring up both nodes.
188
+ which will bring up both nodes.
173
189
 
174
190
  Then run from the test directory:
175
191
 
176
- `chef-client -z -o vagrant::test_provisioning_ssh`
192
+ `chef-client -z -o vagrant::test_ssh`
177
193
 
178
- NOTE: if the second machine fails it will be a result of issues with your vagrant key.
194
+ NOTE: if the first machine fails it will likely be a result of issues with your vagrant key.
179
195
 
180
196
  This will run chef-provisioning on each of the two vagrant nodes.
181
197
 
@@ -183,9 +199,11 @@ thats it.
183
199
 
184
200
  party on wayne.
185
201
 
202
+ Be aware, the `test_ssh` recipe is designed for testing, not to illustrate good practice. For example, you do not need to list all three actions `[ :ready, :setup, :converge ]` or specify `converge true` if you want the normal 'bootstrap if needed, converge if changed' behavior.
203
+
186
204
  ## Contributing
187
205
 
188
- 1. Fork it ( http://github.com/double-z/chef-provisioning-ssh/fork )
206
+ 1. Fork it ( <http://github.com/chef/chef-provisioning-ssh/fork> )
189
207
  2. Create your feature branch (`git checkout -b my-new-feature`)
190
208
  3. Commit your changes (`git commit -am 'Add some feature'`)
191
209
  4. Push to the branch (`git push origin my-new-feature`)
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chef/provisioning/ssh_driver/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "chef-provisioning-ssh"
8
+ s.version = Chef::Provisioning::SshDriver::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.author = "Zack Zondlo"
11
+ s.email = "zackzondlo@gmail.com"
12
+ s.extra_rdoc_files = ['README.md', 'LICENSE' ]
13
+ s.summary = 'Provisioner for managing servers using ssh in Chef Provisioning.'
14
+ s.description = s.summary
15
+ s.homepage = 'https://github.com/chef/chef-provisioning-ssh'
16
+
17
+ s.require_path = "lib"
18
+ s.bindir = "bin"
19
+ s.executables = %w( )
20
+ s.files = %w(Rakefile LICENSE README.md Gemfile) + Dir.glob("*.gemspec") +
21
+ Dir.glob("{distro,lib,tasks,spec}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
22
+
23
+ s.add_runtime_dependency "chef-provisioning", ">= 1.0", "< 3.0"
24
+
25
+ s.add_development_dependency "bundler", "~> 1.5"
26
+ s.add_development_dependency "rspec"
27
+ s.add_development_dependency "rake"
28
+ end
@@ -22,7 +22,13 @@ class Chef
22
22
 
23
23
  include Chef::Provisioning::SshDriver::Helpers
24
24
 
25
+ # cluster_path is where the driver stores machine data unless use_chef_store is true
25
26
  attr_reader :cluster_path
27
+
28
+ # use_chef_store is true if the driver_url is 'ssh:chef'
29
+ # In this case, machine data is stored in chef
30
+ # under node['chef_provisioning']['reference']['machine_options']
31
+ attr_reader :use_chef_store
26
32
 
27
33
  def self.from_url(driver_url, config)
28
34
  Driver.new(driver_url, config)
@@ -32,43 +38,44 @@ class Chef
32
38
  super(driver_url, config)
33
39
  scheme, cluster_path = driver_url.split(':', 2)
34
40
  @cluster_path = cluster_path
41
+ @use_chef_store = cluster_path == 'chef'
35
42
  end
36
43
 
37
44
  def self.canonicalize_url(driver_url, config)
38
45
  scheme, cluster_path = driver_url.split(':', 2)
39
- cluster_path = File.expand_path(cluster_path || File.join(Chef::Config.config_dir, 'provisioning/ssh'))
46
+ unless cluster_path == 'chef'
47
+ cluster_path = File.expand_path(cluster_path || File.join(Chef::Config.config_dir, 'provisioning/ssh'))
48
+ end
40
49
  "ssh:#{cluster_path}"
41
50
  end
42
51
 
43
52
  def allocate_machine(action_handler, machine_spec, machine_options)
44
- existing_machine = ssh_machine_exists?(machine_spec)
45
- ssh_machine_file_updated = create_machine(action_handler, machine_spec, machine_options)
46
-
47
- if !existing_machine || !machine_spec.location
48
- machine_spec.location = {
53
+ ssh_machine_options = prepare_machine_options(action_handler, machine_spec, machine_options)
54
+ log_info("current_machine_options = #{ssh_machine_options.to_s}")
55
+
56
+ unless ssh_machine_exists?(machine_spec)
57
+ machine_spec.reference = {
49
58
  'driver_url' => driver_url,
50
59
  'driver_version' => Chef::Provisioning::SshDriver::VERSION,
51
60
  'target_name' => machine_spec.name,
52
- 'ssh_machine_file' => ssh_machine_file_updated,
53
61
  'allocated_at' => Time.now.utc.to_s,
54
- 'updated_at' => Time.now.utc.to_s,
55
62
  'host' => action_handler.host_node
56
63
  }
57
- elsif ssh_machine_file_updated
58
- machine_spec.location['updated_at'] = Time.now.utc.to_s
59
64
  end
65
+
66
+ update_ssh_machine(action_handler, machine_spec, ssh_machine_options)
60
67
 
61
- if machine_spec.location && (machine_spec.location['driver_version'] != Chef::Provisioning::SshDriver::VERSION)
62
- machine_spec.location['driver_version'] = Chef::Provisioning::SshDriver::VERSION
68
+ if machine_spec.reference &&
69
+ (machine_spec.reference['driver_version'] != Chef::Provisioning::SshDriver::VERSION)
70
+ machine_spec.reference['driver_version'] = Chef::Provisioning::SshDriver::VERSION
63
71
  end
64
-
65
72
  end
66
73
 
67
74
  def ready_machine(action_handler, machine_spec, machine_options)
68
75
  ssh_machine = existing_ssh_machine_to_sym(machine_spec)
69
76
 
70
- if !ssh_machine
71
- raise "SSH Machine #{machine_spec.name} does not have a machine file associated with it!"
77
+ unless ssh_machine
78
+ raise "SSH Machine #{machine_spec.name} does not have machine options associated with it!"
72
79
  end
73
80
 
74
81
  wait_for_transport(action_handler, ssh_machine, machine_spec, machine_options)
@@ -83,25 +90,25 @@ class Chef
83
90
  def destroy_machine(action_handler, machine_spec, machine_options)
84
91
  ssh_machine = ssh_machine_exists?(machine_spec)
85
92
 
86
- if !ssh_machine || !::File.exists?(machine_spec.location['ssh_machine_file'])
87
- raise "SSH Machine #{machine_spec.name} does not have a machine file associated with it!"
88
- else
93
+ unless ssh_machine
94
+ raise "SSH Machine #{machine_spec.name} does not have machine options associated with it!"
95
+ end
96
+
97
+ unless use_chef_store
89
98
  Chef::Provisioning.inline_resource(action_handler) do
90
- file machine_spec.location['ssh_machine_file'] do
91
- action :delete
92
- backup false
93
- end
94
- end
95
- end
96
-
97
-
99
+ file machine_spec.reference['ssh_machine_file'] do
100
+ action :delete
101
+ backup false
102
+ end
103
+ end
104
+ end
98
105
  end
99
106
 
100
107
  def stop_machine(action_handler, machine_spec, machine_options)
101
108
  ssh_machine = existing_ssh_machine_to_sym(machine_spec)
102
109
 
103
- if !ssh_machine
104
- raise "SSH Machine #{machine_spec.name} does not have a machine file associated with it!"
110
+ unless ssh_machine && machine_spec.reference['machine_options']
111
+ raise "SSH Machine #{machine_spec.name} does not have machine options associated with it!"
105
112
  end
106
113
 
107
114
  action_handler.report_progress("SSH Machine #{machine_spec.name} is existing hardware login and power off.")
@@ -110,8 +117,8 @@ class Chef
110
117
  def machine_for(machine_spec, machine_options)
111
118
  ssh_machine = existing_ssh_machine_to_sym(machine_spec)
112
119
 
113
- if !ssh_machine
114
- raise "SSH Machine #{machine_spec.name} does not have a machine file associated with it!"
120
+ unless ssh_machine
121
+ raise "SSH Machine #{machine_spec.name} does not have machine options associated with it!"
115
122
  end
116
123
 
117
124
  if ssh_machine[:transport_options][:is_windows]
@@ -189,65 +196,65 @@ class Chef
189
196
  end
190
197
  end
191
198
 
199
+ def validate_transport_fields(options, req_fields, opt_fields)
200
+ error_msgs = []
201
+ valid_fields = req_fields.flatten + opt_fields
202
+ one_of_fields = req_fields.select{ |i| i.kind_of?(Array)}
203
+
204
+ missing = req_fields.flatten - options.keys
205
+
206
+ one_of_fields.each do |oof|
207
+ if oof == oof & missing
208
+ error_msgs << ":transport_options => :#{oof.join(" or :")} required."
209
+ end
210
+ missing -= oof
211
+ end
212
+
213
+ missing.each do |missed|
214
+ error_msgs << ":transport_options => :#{missed} required."
215
+ valid = false
216
+ end
217
+
218
+ extras = options.keys - valid_fields
219
+
220
+ extras.each do |extra|
221
+ error_msgs << ":transport_options => :#{extra} not allowed."
222
+ valid = false
223
+ end
224
+
225
+ error_msgs
226
+ end
227
+
192
228
  def validate_machine_options(action_handler, machine_spec, machine_options)
193
229
  error_msgs = []
194
230
  valid = true
195
-
196
- if !machine_options[:transport_options]
231
+
232
+ unless machine_options[:transport_options]
197
233
  error_msgs << ":transport_options required."
198
234
  valid = false
199
235
  else
200
236
  if machine_options[:transport_options][:is_windows]
201
237
  # Validate Windows Options.
202
- req_and_valid_fields = [:is_windows, [:host, :ip_address], :username, :password]
203
- one_of_fields = req_and_valid_fields.select{ |i| i.kind_of?(Array)}
204
-
205
- missing = req_and_valid_fields.flatten - machine_options[:transport_options].keys
206
-
207
- one_of_fields.each do |oof|
208
- if oof == oof & missing
209
- error_msgs << ":transport_options => :#{oof.join(" or :")} required."
210
- end
211
- missing -= oof
212
- end
213
-
214
- missing.each do |missed|
215
- error_msgs << ":transport_options => :#{missed} required."
216
- valid = false
217
- end
218
-
219
- extras = machine_options[:transport_options].keys - req_and_valid_fields.flatten
220
-
221
- extras.each do |extra|
222
- error_msgs << ":transport_options => :#{extra} not allowed." unless extra == :port
238
+ field_errors = validate_transport_fields(
239
+ machine_options[:transport_options],
240
+ [:is_windows, [:host, :ip_address], :username, :password],
241
+ [:port]
242
+ )
243
+ unless field_errors.empty?
223
244
  valid = false
245
+ error_msgs << field_errors
224
246
  end
225
247
  else
226
248
  # Validate Unix Options
227
- req_fields = [[:host, :hostname, :ip_address], :username]
228
- one_of_fields = req_fields.select{ |i| i.kind_of?(Array)}
229
-
230
- missing = req_fields.flatten - machine_options[:transport_options].keys
231
-
232
- one_of_fields.each do |oof|
233
- if oof == oof & missing
234
- error_msgs << ":transport_options => :#{oof.join(" or :")} required."
235
- end
236
- missing -= oof
237
- end
238
-
239
- missing.each do |missed|
240
- error_msgs << ":transport_options => :#{missed} required."
241
- valid = false
242
- end
243
-
244
- valid_fields = [:is_windows, :host, :hostname, :ip_address, :username, :ssh_options, :options]
245
-
246
- extras = machine_options[:transport_options].keys - valid_fields
247
-
248
- extras.each do |extra|
249
- error_msgs << ":transport_options => :#{extra} not allowed."
249
+ field_errors = validate_transport_fields(
250
+ machine_options[:transport_options],
251
+ [[:host, :hostname, :ip_address], :username],
252
+ [:is_windows, :host, :hostname, :ip_address, :username, :ssh_options, :options]
253
+ )
254
+
255
+ unless field_errors.empty?
250
256
  valid = false
257
+ error_msgs << field_errors
251
258
  end
252
259
 
253
260
  if machine_options[:transport_options][:ssh_options]
@@ -262,7 +269,7 @@ class Chef
262
269
  end
263
270
 
264
271
  if machine_options[:transport_options][:options]
265
- valid_fields = [:prefix, :ssh_pty_enable, :ssh_gateway]
272
+ valid_fields = [:prefix, :ssh_pty_enable, :ssh_gateway, :scp_temp_dir]
266
273
 
267
274
  extras = machine_options[:transport_options][:options].keys - valid_fields
268
275
 
@@ -292,42 +299,14 @@ class Chef
292
299
  end
293
300
  end
294
301
 
295
- def create_machine(action_handler, machine_spec, machine_options)
302
+ def create_machine_file(action_handler, machine_spec, machine_options_hash)
296
303
  ensure_ssh_cluster(action_handler)
297
304
 
298
- machine_options_hash_for_sym = deep_hashify(machine_options)
299
- symbolized_machine_options = symbolize_keys(machine_options_hash_for_sym)
300
- validate_machine_options(action_handler, machine_spec, symbolized_machine_options)
301
- # end
302
-
303
-
304
- # def create_ssh_machine(action_handler, machine_spec, machine_options)
305
- log_info("File is = #{ssh_machine_file(machine_spec)}")
306
- log_info("current_machine_options = #{machine_options.to_s}")
307
-
308
- machine_options_hash_for_s = deep_hashify(machine_options)
309
- stringy_machine_options = stringify_keys(machine_options_hash_for_s)
310
- given_machine_options = create_machine_hash(stringy_machine_options)
311
-
312
- if ssh_machine_exists?(machine_spec)
313
- existing_machine_hash = existing_ssh_machine(machine_spec)
314
- if !existing_machine_hash.eql?(given_machine_options)
315
- create_machine_file(action_handler, machine_spec, given_machine_options)
316
- else
317
- return false
318
- end
319
- else
320
- file_updated = create_machine_file(action_handler, machine_spec, given_machine_options)
321
- file_updated
322
- end
323
- end
324
-
325
- def create_machine_file(action_handler, machine_spec, machine_options)
326
305
  file_path = ssh_machine_file(machine_spec)
327
- machine_options_hash = deep_hashify(machine_options)
328
306
  stringy_machine_options = stringify_keys(machine_options_hash)
329
307
  options_parsed = ::JSON.parse(stringy_machine_options.to_json)
330
308
  json_machine_options = ::JSON.pretty_generate(options_parsed)
309
+ log_info("File is = #{file_path}")
331
310
  Chef::Provisioning.inline_resource(action_handler) do
332
311
  file file_path do
333
312
  content json_machine_options
@@ -347,12 +326,15 @@ class Chef
347
326
  end
348
327
 
349
328
  def existing_ssh_machine(machine_spec)
350
- if ssh_machine_exists?(machine_spec)
351
- existing_machine_hash = JSON.parse(File.read(ssh_machine_file(machine_spec)))
352
- existing_machine_hash.to_hash
353
- else
329
+ unless ssh_machine_exists?(machine_spec)
354
330
  return {}
355
331
  end
332
+
333
+ if use_chef_store
334
+ machine_spec.reference['machine_options']
335
+ else
336
+ JSON.parse(File.read(ssh_machine_file(machine_spec))).to_hash
337
+ end
356
338
  end
357
339
 
358
340
  def existing_ssh_machine_to_sym(machine_spec)
@@ -365,22 +347,47 @@ class Chef
365
347
  end
366
348
 
367
349
  def ssh_machine_exists?(machine_spec)
368
- if machine_spec.location
369
- ::File.exists?(ssh_machine_file(machine_spec))
350
+ if use_chef_store
351
+ machine_spec.reference && machine_spec.reference['machine_options']
370
352
  else
371
- false
353
+ machine_spec.reference && ::File.exists?(ssh_machine_file(machine_spec))
372
354
  end
373
355
  end
374
356
 
375
357
  def ssh_machine_file(machine_spec)
376
- if machine_spec.location && machine_spec.location['ssh_machine_file']
377
- machine_spec.location['ssh_machine_file']
358
+ if machine_spec.reference && machine_spec.reference['ssh_machine_file']
359
+ machine_spec.reference['ssh_machine_file']
378
360
  else
379
361
  ssh_machine_file = ::File.join(@cluster_path, "#{machine_spec.name}.json")
380
362
  ssh_machine_file
381
363
  end
382
364
  end
383
365
 
366
+ def prepare_machine_options(action_handler, machine_spec, machine_options)
367
+ options_hash = symbolize_keys(deep_hashify(machine_options))
368
+
369
+ # if no transport options are specified, use the existing ones
370
+ unless options_hash[:transport_options]
371
+ ssh_machine = existing_ssh_machine_to_sym(machine_spec) || {}
372
+ options_hash[:transport_options] = ssh_machine[:transport_options] || {}
373
+ end
374
+
375
+ validate_machine_options(action_handler, machine_spec, options_hash)
376
+ create_machine_hash(stringify_keys(options_hash))
377
+ end
378
+
379
+ def update_ssh_machine(action_handler, machine_spec, ssh_machine_options)
380
+ unless existing_ssh_machine(machine_spec).eql? ssh_machine_options
381
+ if use_chef_store
382
+ machine_spec.reference['machine_options'] = ssh_machine_options
383
+ else
384
+ machine_spec.reference['ssh_machine_file'] =
385
+ create_machine_file(action_handler, machine_spec, ssh_machine_options)
386
+ end
387
+ machine_spec.reference['updated_at'] = Time.now.utc.to_s
388
+ end
389
+ end
390
+
384
391
  def create_machine_hash(machine_options)
385
392
  if !machine_options['transport_options']['host']
386
393
  machine_options['transport_options']['host'] = machine_options['transport_options']['ip_address'] ||
@@ -390,7 +397,7 @@ class Chef
390
397
  unless machine_options['transport_options']['is_windows']
391
398
  machine_options['transport_options']['options'] ||= {}
392
399
  unless machine_options['transport_options']['username'] == 'root'
393
- machine_options['transport_options']['options']['prefix'] = 'sudo '
400
+ machine_options['transport_options']['options']['prefix'] ||= 'sudo '
394
401
  end
395
402
  end
396
403
  ensure_has_keys_or_password(machine_options['transport_options'])
@@ -405,9 +412,11 @@ class Chef
405
412
  if transport_hash['ssh_options']
406
413
  ssh_hash = transport_hash['ssh_options']
407
414
  keys = ssh_hash['keys'] || false
415
+ key_data = ssh_hash['key_data'] || false
408
416
  password = ssh_hash['password'] || false
409
417
  has_either = ((password && password.kind_of?(String)) ||
410
- (keys && !keys.empty? && keys.kind_of?(Array)))
418
+ (keys && !keys.empty? && keys.kind_of?(Array)) ||
419
+ (key_data && !key_data.empty? && key_data.kind_of?(Array)))
411
420
  else
412
421
  has_either = false
413
422
  end
@@ -439,8 +448,6 @@ class Chef
439
448
 
440
449
  raise 'Host is not a Valid IP or Resolvable Hostname' unless ( valid_ip || in_hosts_file || in_dns )
441
450
  end
442
-
443
-
444
451
  end
445
452
  end
446
453
  end
@@ -1,7 +1,7 @@
1
1
  class Chef
2
2
  module Provisioning
3
3
  module SshDriver
4
- VERSION = '0.0.9'
4
+ VERSION = '0.1.0'
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-provisioning-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zack Zondlo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-26 00:00:00.000000000 Z
11
+ date: 2016-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-provisioning
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: '1.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -74,9 +80,11 @@ extra_rdoc_files:
74
80
  - README.md
75
81
  - LICENSE
76
82
  files:
83
+ - Gemfile
77
84
  - LICENSE
78
85
  - README.md
79
86
  - Rakefile
87
+ - chef-provisioning-ssh.gemspec
80
88
  - lib/chef/provider/ssh_cluster.rb
81
89
  - lib/chef/provisioning/driver_init/ssh.rb
82
90
  - lib/chef/provisioning/ssh_driver.rb
@@ -84,7 +92,7 @@ files:
84
92
  - lib/chef/provisioning/ssh_driver/helpers.rb
85
93
  - lib/chef/provisioning/ssh_driver/version.rb
86
94
  - lib/chef/resource/ssh_cluster.rb
87
- homepage: https://github.com/double-z/chef-provisioning-ssh
95
+ homepage: https://github.com/chef/chef-provisioning-ssh
88
96
  licenses: []
89
97
  metadata: {}
90
98
  post_install_message:
@@ -103,9 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
111
  version: '0'
104
112
  requirements: []
105
113
  rubyforge_project:
106
- rubygems_version: 2.4.4
114
+ rubygems_version: 2.6.7
107
115
  signing_key:
108
116
  specification_version: 4
109
117
  summary: Provisioner for managing servers using ssh in Chef Provisioning.
110
118
  test_files: []
111
- has_rdoc: