chef-provisioning-ssh 0.0.9 → 0.1.0

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 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: