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 +4 -4
- data/Gemfile +4 -0
- data/README.md +155 -137
- data/chef-provisioning-ssh.gemspec +28 -0
- data/lib/chef/provisioning/ssh_driver/driver.rb +127 -120
- data/lib/chef/provisioning/ssh_driver/version.rb +1 -1
- metadata +14 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69a88cd11bc933287de011039d2e16e43b4ffbc1
|
4
|
+
data.tar.gz: 5eea7c73c739a5b6927a87a3acafd1ae8e5ed9ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9dce79bf1c666461cca81e59aa0e9a3aad48aa02f5d477114b14176aa5af3679e8edded22c25fd1fc981bda1db9950f17cf1566fa41387f3adbc3e7c0700331
|
7
|
+
data.tar.gz: 7be88e2785e107272b8459b27a13a79405c20ad50c1af8d207ed57bd9de4902ec459fd81d2132dc3537a8ff0ea15a42df73ff38329e8e4171e02698185471b41
|
data/Gemfile
ADDED
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
|
-
|
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
|
-
|
10
|
+
|
11
11
|
```ruby
|
12
12
|
gem 'chef-provisioning-ssh'
|
13
13
|
```
|
14
14
|
|
15
15
|
And then execute:
|
16
16
|
|
17
|
-
|
17
|
+
```
|
18
|
+
$ bundle
|
19
|
+
```
|
18
20
|
|
19
21
|
Or install it yourself as:
|
20
22
|
|
21
|
-
|
23
|
+
```
|
24
|
+
$ gem install chef-provisioning-ssh
|
25
|
+
```
|
22
26
|
|
23
27
|
## Usage
|
24
28
|
|
25
|
-
|
29
|
+
### driver_url
|
26
30
|
|
27
|
-
|
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
|
-
|
35
|
+
### machine_options
|
30
36
|
|
31
|
-
The transport_options
|
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
|
-
|
34
|
-
|
35
|
-
The snippet from that link is:
|
39
|
+
The `transport_options` key and sub-keys may be strings or symbols.
|
36
40
|
|
37
|
-
|
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
|
-
|
43
|
+
<https://github.com/chef/chef-provisioning/blob/master/lib/chef/provisioning/transport/ssh.rb#L17-L34>
|
53
44
|
|
54
|
-
|
45
|
+
The snippet from that link is:
|
55
46
|
|
56
|
-
|
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
|
-
|
64
|
+
In addition to host, ip_address and hostname are also additional options.
|
59
65
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
'
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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/
|
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::
|
192
|
+
`chef-client -z -o vagrant::test_ssh`
|
177
193
|
|
178
|
-
NOTE: if the
|
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/
|
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
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
machine_spec.
|
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.
|
62
|
-
machine_spec.
|
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
|
-
|
71
|
-
raise "SSH Machine #{machine_spec.name} does not have
|
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
|
-
|
87
|
-
raise "SSH Machine #{machine_spec.name} does not have
|
88
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
104
|
-
raise "SSH Machine #{machine_spec.name} does not have
|
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
|
-
|
114
|
-
raise "SSH Machine #{machine_spec.name} does not have
|
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
|
-
|
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
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
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
|
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
|
-
|
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
|
369
|
-
|
350
|
+
if use_chef_store
|
351
|
+
machine_spec.reference && machine_spec.reference['machine_options']
|
370
352
|
else
|
371
|
-
|
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.
|
377
|
-
machine_spec.
|
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']
|
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
|
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
|
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:
|
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/
|
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.
|
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:
|