chef-provisioning-fog 0.15.0 → 0.15.1
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 +4 -4
- data/Gemfile +11 -0
- data/LICENSE +201 -201
- data/README.md +208 -3
- data/Rakefile +6 -6
- data/chef-provisioning-fog.gemspec +28 -0
- data/lib/chef/provider/fog_key_pair.rb +266 -266
- data/lib/chef/provisioning/driver_init/fog.rb +3 -3
- data/lib/chef/provisioning/fog_driver/driver.rb +736 -736
- data/lib/chef/provisioning/fog_driver/providers/aws.rb +492 -492
- data/lib/chef/provisioning/fog_driver/providers/aws/credentials.rb +115 -115
- data/lib/chef/provisioning/fog_driver/providers/cloudstack.rb +44 -44
- data/lib/chef/provisioning/fog_driver/providers/digitalocean.rb +136 -136
- data/lib/chef/provisioning/fog_driver/providers/google.rb +85 -85
- data/lib/chef/provisioning/fog_driver/providers/joyent.rb +63 -63
- data/lib/chef/provisioning/fog_driver/providers/openstack.rb +117 -117
- data/lib/chef/provisioning/fog_driver/providers/rackspace.rb +42 -42
- data/lib/chef/provisioning/fog_driver/providers/softlayer.rb +36 -36
- data/lib/chef/provisioning/fog_driver/providers/vcair.rb +409 -409
- data/lib/chef/provisioning/fog_driver/providers/xenserver.rb +210 -210
- data/lib/chef/provisioning/fog_driver/recipe_dsl.rb +32 -32
- data/lib/chef/provisioning/fog_driver/version.rb +7 -7
- data/lib/chef/resource/fog_key_pair.rb +34 -34
- data/spec/spec_helper.rb +18 -18
- data/spec/support/aws/config-file.csv +2 -2
- data/spec/support/aws/ini-file.ini +10 -10
- data/spec/support/chef_metal_fog/providers/testdriver.rb +16 -16
- data/spec/unit/chef/provisioning/fog_driver/driver_spec.rb +71 -71
- data/spec/unit/fog_driver_spec.rb +32 -32
- data/spec/unit/providers/aws/credentials_spec.rb +45 -45
- data/spec/unit/providers/rackspace_spec.rb +16 -16
- metadata +5 -3
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
require 'bundler/gem_tasks'
|
3
|
-
|
4
|
-
task :spec do
|
5
|
-
require File.expand_path('spec/run')
|
6
|
-
end
|
1
|
+
require 'bundler'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
task :spec do
|
5
|
+
require File.expand_path('spec/run')
|
6
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/lib')
|
2
|
+
require 'chef/provisioning/fog_driver/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'chef-provisioning-fog'
|
6
|
+
s.version = Chef::Provisioning::FogDriver::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.extra_rdoc_files = ['README.md', 'LICENSE' ]
|
9
|
+
s.summary = 'Driver for creating Fog instances in Chef Provisioning.'
|
10
|
+
s.description = s.summary
|
11
|
+
s.authors = ['John Keiser', "Chris McClimans", "Taylor Carpenter", "Wavell Watson"]
|
12
|
+
s.email = ['jkeiser@getchef.com', 'hh@vulk.co', 't@vulk.co', 'w@vulk.co']
|
13
|
+
s.homepage = 'https://github.com/opscode/chef-provisioning-fog'
|
14
|
+
|
15
|
+
s.add_dependency 'chef-provisioning', '~> 1.0'
|
16
|
+
s.add_dependency 'fog'
|
17
|
+
s.add_dependency 'retryable'
|
18
|
+
|
19
|
+
s.add_development_dependency 'rspec'
|
20
|
+
s.add_development_dependency 'rake'
|
21
|
+
|
22
|
+
s.bindir = "bin"
|
23
|
+
s.executables = %w( )
|
24
|
+
|
25
|
+
s.require_path = 'lib'
|
26
|
+
s.files = %w(Gemfile Rakefile LICENSE README.md) + Dir.glob("*.gemspec") +
|
27
|
+
Dir.glob("{distro,lib,tasks,spec}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
|
28
|
+
end
|
@@ -1,266 +1,266 @@
|
|
1
|
-
require 'chef/provider/lwrp_base'
|
2
|
-
require 'chef/provisioning/fog_driver/driver'
|
3
|
-
|
4
|
-
class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
5
|
-
|
6
|
-
use_inline_resources
|
7
|
-
|
8
|
-
def whyrun_supported?
|
9
|
-
true
|
10
|
-
end
|
11
|
-
|
12
|
-
action :create do
|
13
|
-
create_key(:create)
|
14
|
-
end
|
15
|
-
|
16
|
-
action :delete do
|
17
|
-
if current_resource_exists?
|
18
|
-
converge_by "delete #{key_description}" do
|
19
|
-
case new_driver.compute_options[:provider]
|
20
|
-
when 'DigitalOcean'
|
21
|
-
compute.destroy_ssh_key(@current_id)
|
22
|
-
when 'Joyent'
|
23
|
-
compute.delete_key(@current_id)
|
24
|
-
when 'OpenStack', 'Rackspace'
|
25
|
-
compute.key_pairs.destroy(@current_id)
|
26
|
-
else
|
27
|
-
compute.key_pairs.delete(new_resource.name)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def key_description
|
34
|
-
"#{new_resource.name} on #{new_driver.driver_url}"
|
35
|
-
end
|
36
|
-
|
37
|
-
@@use_pkcs8 = nil # For Ruby 1.9 and below, PKCS can be run
|
38
|
-
|
39
|
-
def create_key(action)
|
40
|
-
if @should_create_directory
|
41
|
-
Cheffish.inline_resource(self, action) do
|
42
|
-
directory run_context.config[:private_key_write_path]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
if current_resource_exists?
|
47
|
-
# If the public keys are different, update the server public key
|
48
|
-
if !current_resource.private_key_path
|
49
|
-
if new_resource.allow_overwrite
|
50
|
-
ensure_keys(action)
|
51
|
-
else
|
52
|
-
raise "#{key_description} already exists on the server, but the private key #{new_private_key_path} does not exist!"
|
53
|
-
end
|
54
|
-
else
|
55
|
-
ensure_keys(action)
|
56
|
-
end
|
57
|
-
|
58
|
-
case new_driver.compute_options[:provider]
|
59
|
-
when 'DigitalOcean'
|
60
|
-
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :openssh)]
|
61
|
-
when 'Joyent'
|
62
|
-
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :rfc4716md5fingerprint)]
|
63
|
-
when 'OpenStack', 'Rackspace'
|
64
|
-
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :openssh)]
|
65
|
-
else
|
66
|
-
# “The nice thing about standards is that you have so many to
|
67
|
-
# choose from.” - Andrew S. Tanenbaum
|
68
|
-
#
|
69
|
-
# The AWS EC2 API uses a PKCS#1 MD5 fingerprint for keys that you
|
70
|
-
# import into EC2, but a PKCS#8 SHA1 fingerprint for keys that you
|
71
|
-
# generate using its web console. Both fingerprints are different
|
72
|
-
# from the familiar RFC4716 MD5 fingerprint that OpenSSH displays
|
73
|
-
# for host keys.
|
74
|
-
#
|
75
|
-
# So compute both possible AWS fingerprints and check if either of
|
76
|
-
# them matches.
|
77
|
-
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :fingerprint)]
|
78
|
-
if RUBY_VERSION.to_f < 2.0
|
79
|
-
if @@use_pkcs8.nil?
|
80
|
-
begin
|
81
|
-
require 'openssl_pkcs8'
|
82
|
-
@@use_pkcs8 = true
|
83
|
-
rescue LoadError
|
84
|
-
Chef::Log.warn("The openssl_pkcs8 gem is not loaded: you may not be able to read key fingerprints created by some cloud providers. gem install openssl_pkcs8 to fix!")
|
85
|
-
@@use_pkcs8 = false
|
86
|
-
end
|
87
|
-
end
|
88
|
-
if @@use_pkcs8
|
89
|
-
new_fingerprints << Cheffish::KeyFormatter.encode(desired_private_key,
|
90
|
-
:format => :pkcs8sha1fingerprint)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
if !new_fingerprints.any? { |f| compare_public_key f }
|
96
|
-
if new_resource.allow_overwrite
|
97
|
-
converge_by "update #{key_description} to match local key at #{new_resource.private_key_path}" do
|
98
|
-
case new_driver.compute_options[:provider]
|
99
|
-
when 'DigitalOcean'
|
100
|
-
compute.create_ssh_key(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
101
|
-
when 'Joyent'
|
102
|
-
compute.create_key(name: new_resource.name, key: Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
103
|
-
when 'OpenStack'
|
104
|
-
compute.create_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
105
|
-
when 'Rackspace'
|
106
|
-
compute.create_keypair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
107
|
-
else
|
108
|
-
compute.key_pairs.get(new_resource.name).destroy
|
109
|
-
compute.import_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
110
|
-
end
|
111
|
-
end
|
112
|
-
else
|
113
|
-
raise "#{key_description} with fingerprint #{@current_fingerprint} does not match local key fingerprint(s) #{new_fingerprints}, and allow_overwrite is false!"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
else
|
117
|
-
# Generate the private and/or public keys if they do not exist
|
118
|
-
ensure_keys(action)
|
119
|
-
|
120
|
-
# Create key
|
121
|
-
converge_by "create #{key_description} from local key at #{new_resource.private_key_path}" do
|
122
|
-
case new_driver.compute_options[:provider]
|
123
|
-
when 'DigitalOcean'
|
124
|
-
compute.create_ssh_key(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
125
|
-
when 'Joyent'
|
126
|
-
compute.create_key(name: new_resource.name, key: Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
127
|
-
when 'OpenStack'
|
128
|
-
compute.create_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
129
|
-
when 'Rackspace'
|
130
|
-
compute.create_keypair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
131
|
-
else
|
132
|
-
compute.import_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def new_driver
|
139
|
-
run_context.chef_provisioning.driver_for(new_resource.driver)
|
140
|
-
end
|
141
|
-
|
142
|
-
def ensure_keys(action)
|
143
|
-
resource = new_resource
|
144
|
-
private_key_path = new_private_key_path
|
145
|
-
Cheffish.inline_resource(self, action) do
|
146
|
-
private_key private_key_path do
|
147
|
-
public_key_path resource.public_key_path
|
148
|
-
if resource.private_key_options
|
149
|
-
resource.private_key_options.each_pair do |key,value|
|
150
|
-
send(key, value)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def desired_key
|
158
|
-
@desired_key ||= begin
|
159
|
-
if new_resource.public_key_path
|
160
|
-
public_key, format = Cheffish::KeyFormatter.decode(IO.read(new_resource.public_key_path))
|
161
|
-
public_key
|
162
|
-
else
|
163
|
-
desired_private_key.public_key
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def desired_private_key
|
169
|
-
@desired_private_key ||= begin
|
170
|
-
private_key, format = Cheffish::KeyFormatter.decode(IO.read(new_private_key_path))
|
171
|
-
private_key
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def current_resource_exists?
|
176
|
-
@current_resource.action != [ :delete ]
|
177
|
-
end
|
178
|
-
|
179
|
-
def compare_public_key(new)
|
180
|
-
c = @current_fingerprint.split[0,2].join(' ')
|
181
|
-
n = new.split[0,2].join(' ')
|
182
|
-
c == n
|
183
|
-
end
|
184
|
-
|
185
|
-
def compute
|
186
|
-
new_driver.compute
|
187
|
-
end
|
188
|
-
|
189
|
-
def current_public_key
|
190
|
-
current_resource.source_key
|
191
|
-
end
|
192
|
-
|
193
|
-
def new_private_key_path
|
194
|
-
private_key_path = new_resource.private_key_path || new_resource.name
|
195
|
-
if private_key_path.is_a?(Symbol)
|
196
|
-
private_key_path
|
197
|
-
elsif Pathname.new(private_key_path).relative? && new_driver.config[:private_key_write_path]
|
198
|
-
@should_create_directory = true
|
199
|
-
::File.join(new_driver.config[:private_key_write_path], private_key_path)
|
200
|
-
else
|
201
|
-
private_key_path
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def new_public_key_path
|
206
|
-
new_resource.public_key_path
|
207
|
-
end
|
208
|
-
|
209
|
-
def load_current_resource
|
210
|
-
if !new_driver.kind_of?(Chef::Provisioning::FogDriver::Driver)
|
211
|
-
raise 'fog_key_pair only works with fog_driver'
|
212
|
-
end
|
213
|
-
@current_resource = Chef::Resource::FogKeyPair.new(new_resource.name, run_context)
|
214
|
-
case new_driver.provider
|
215
|
-
when 'DigitalOcean'
|
216
|
-
current_key_pair = compute.ssh_keys.select { |key| key.name == new_resource.name }.first
|
217
|
-
if current_key_pair
|
218
|
-
@current_id = current_key_pair.id
|
219
|
-
@current_fingerprint = current_key_pair ? compute.ssh_keys.get(@current_id).ssh_pub_key : nil
|
220
|
-
else
|
221
|
-
current_resource.action :delete
|
222
|
-
end
|
223
|
-
when 'Joyent'
|
224
|
-
current_key_pair = begin
|
225
|
-
compute.keys.get(new_resource.name)
|
226
|
-
rescue Fog::Compute::Joyent::Errors::NotFound
|
227
|
-
nil
|
228
|
-
end
|
229
|
-
if current_key_pair
|
230
|
-
@current_id = current_key_pair.name
|
231
|
-
@current_fingerprint = if current_key_pair.respond_to?(:fingerprint)
|
232
|
-
current_key_pair.fingerprint
|
233
|
-
elsif current_key_pair.respond_to?(:key)
|
234
|
-
public_key, format = Cheffish::KeyFormatter.decode(current_key_pair.key)
|
235
|
-
public_key.fingerprint
|
236
|
-
else
|
237
|
-
nil
|
238
|
-
end
|
239
|
-
else
|
240
|
-
current_resource.action :delete
|
241
|
-
end
|
242
|
-
when 'OpenStack', 'Rackspace'
|
243
|
-
current_key_pair = compute.key_pairs.get(new_resource.name)
|
244
|
-
if current_key_pair
|
245
|
-
@current_id = current_key_pair.name
|
246
|
-
@current_fingerprint = current_key_pair ? compute.key_pairs.get(@current_id).public_key : nil
|
247
|
-
else
|
248
|
-
current_resource.action :delete
|
249
|
-
end
|
250
|
-
else
|
251
|
-
current_key_pair = compute.key_pairs.get(new_resource.name)
|
252
|
-
if current_key_pair
|
253
|
-
@current_fingerprint = current_key_pair ? current_key_pair.fingerprint : nil
|
254
|
-
else
|
255
|
-
current_resource.action :delete
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
if new_private_key_path && ::File.exist?(new_private_key_path)
|
260
|
-
current_resource.private_key_path new_private_key_path
|
261
|
-
end
|
262
|
-
if new_public_key_path && ::File.exist?(new_public_key_path)
|
263
|
-
current_resource.public_key_path new_public_key_path
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'chef/provisioning/fog_driver/driver'
|
3
|
+
|
4
|
+
class Chef::Provider::FogKeyPair < Chef::Provider::LWRPBase
|
5
|
+
|
6
|
+
use_inline_resources
|
7
|
+
|
8
|
+
def whyrun_supported?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
action :create do
|
13
|
+
create_key(:create)
|
14
|
+
end
|
15
|
+
|
16
|
+
action :delete do
|
17
|
+
if current_resource_exists?
|
18
|
+
converge_by "delete #{key_description}" do
|
19
|
+
case new_driver.compute_options[:provider]
|
20
|
+
when 'DigitalOcean'
|
21
|
+
compute.destroy_ssh_key(@current_id)
|
22
|
+
when 'Joyent'
|
23
|
+
compute.delete_key(@current_id)
|
24
|
+
when 'OpenStack', 'Rackspace'
|
25
|
+
compute.key_pairs.destroy(@current_id)
|
26
|
+
else
|
27
|
+
compute.key_pairs.delete(new_resource.name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def key_description
|
34
|
+
"#{new_resource.name} on #{new_driver.driver_url}"
|
35
|
+
end
|
36
|
+
|
37
|
+
@@use_pkcs8 = nil # For Ruby 1.9 and below, PKCS can be run
|
38
|
+
|
39
|
+
def create_key(action)
|
40
|
+
if @should_create_directory
|
41
|
+
Cheffish.inline_resource(self, action) do
|
42
|
+
directory run_context.config[:private_key_write_path]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if current_resource_exists?
|
47
|
+
# If the public keys are different, update the server public key
|
48
|
+
if !current_resource.private_key_path
|
49
|
+
if new_resource.allow_overwrite
|
50
|
+
ensure_keys(action)
|
51
|
+
else
|
52
|
+
raise "#{key_description} already exists on the server, but the private key #{new_private_key_path} does not exist!"
|
53
|
+
end
|
54
|
+
else
|
55
|
+
ensure_keys(action)
|
56
|
+
end
|
57
|
+
|
58
|
+
case new_driver.compute_options[:provider]
|
59
|
+
when 'DigitalOcean'
|
60
|
+
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :openssh)]
|
61
|
+
when 'Joyent'
|
62
|
+
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :rfc4716md5fingerprint)]
|
63
|
+
when 'OpenStack', 'Rackspace'
|
64
|
+
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :openssh)]
|
65
|
+
else
|
66
|
+
# “The nice thing about standards is that you have so many to
|
67
|
+
# choose from.” - Andrew S. Tanenbaum
|
68
|
+
#
|
69
|
+
# The AWS EC2 API uses a PKCS#1 MD5 fingerprint for keys that you
|
70
|
+
# import into EC2, but a PKCS#8 SHA1 fingerprint for keys that you
|
71
|
+
# generate using its web console. Both fingerprints are different
|
72
|
+
# from the familiar RFC4716 MD5 fingerprint that OpenSSH displays
|
73
|
+
# for host keys.
|
74
|
+
#
|
75
|
+
# So compute both possible AWS fingerprints and check if either of
|
76
|
+
# them matches.
|
77
|
+
new_fingerprints = [Cheffish::KeyFormatter.encode(desired_key, :format => :fingerprint)]
|
78
|
+
if RUBY_VERSION.to_f < 2.0
|
79
|
+
if @@use_pkcs8.nil?
|
80
|
+
begin
|
81
|
+
require 'openssl_pkcs8'
|
82
|
+
@@use_pkcs8 = true
|
83
|
+
rescue LoadError
|
84
|
+
Chef::Log.warn("The openssl_pkcs8 gem is not loaded: you may not be able to read key fingerprints created by some cloud providers. gem install openssl_pkcs8 to fix!")
|
85
|
+
@@use_pkcs8 = false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
if @@use_pkcs8
|
89
|
+
new_fingerprints << Cheffish::KeyFormatter.encode(desired_private_key,
|
90
|
+
:format => :pkcs8sha1fingerprint)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
if !new_fingerprints.any? { |f| compare_public_key f }
|
96
|
+
if new_resource.allow_overwrite
|
97
|
+
converge_by "update #{key_description} to match local key at #{new_resource.private_key_path}" do
|
98
|
+
case new_driver.compute_options[:provider]
|
99
|
+
when 'DigitalOcean'
|
100
|
+
compute.create_ssh_key(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
101
|
+
when 'Joyent'
|
102
|
+
compute.create_key(name: new_resource.name, key: Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
103
|
+
when 'OpenStack'
|
104
|
+
compute.create_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
105
|
+
when 'Rackspace'
|
106
|
+
compute.create_keypair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
107
|
+
else
|
108
|
+
compute.key_pairs.get(new_resource.name).destroy
|
109
|
+
compute.import_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
else
|
113
|
+
raise "#{key_description} with fingerprint #{@current_fingerprint} does not match local key fingerprint(s) #{new_fingerprints}, and allow_overwrite is false!"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
else
|
117
|
+
# Generate the private and/or public keys if they do not exist
|
118
|
+
ensure_keys(action)
|
119
|
+
|
120
|
+
# Create key
|
121
|
+
converge_by "create #{key_description} from local key at #{new_resource.private_key_path}" do
|
122
|
+
case new_driver.compute_options[:provider]
|
123
|
+
when 'DigitalOcean'
|
124
|
+
compute.create_ssh_key(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
125
|
+
when 'Joyent'
|
126
|
+
compute.create_key(name: new_resource.name, key: Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
127
|
+
when 'OpenStack'
|
128
|
+
compute.create_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
129
|
+
when 'Rackspace'
|
130
|
+
compute.create_keypair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
131
|
+
else
|
132
|
+
compute.import_key_pair(new_resource.name, Cheffish::KeyFormatter.encode(desired_key, :format => :openssh))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def new_driver
|
139
|
+
run_context.chef_provisioning.driver_for(new_resource.driver)
|
140
|
+
end
|
141
|
+
|
142
|
+
def ensure_keys(action)
|
143
|
+
resource = new_resource
|
144
|
+
private_key_path = new_private_key_path
|
145
|
+
Cheffish.inline_resource(self, action) do
|
146
|
+
private_key private_key_path do
|
147
|
+
public_key_path resource.public_key_path
|
148
|
+
if resource.private_key_options
|
149
|
+
resource.private_key_options.each_pair do |key,value|
|
150
|
+
send(key, value)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def desired_key
|
158
|
+
@desired_key ||= begin
|
159
|
+
if new_resource.public_key_path
|
160
|
+
public_key, format = Cheffish::KeyFormatter.decode(IO.read(new_resource.public_key_path))
|
161
|
+
public_key
|
162
|
+
else
|
163
|
+
desired_private_key.public_key
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def desired_private_key
|
169
|
+
@desired_private_key ||= begin
|
170
|
+
private_key, format = Cheffish::KeyFormatter.decode(IO.read(new_private_key_path))
|
171
|
+
private_key
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def current_resource_exists?
|
176
|
+
@current_resource.action != [ :delete ]
|
177
|
+
end
|
178
|
+
|
179
|
+
def compare_public_key(new)
|
180
|
+
c = @current_fingerprint.split[0,2].join(' ')
|
181
|
+
n = new.split[0,2].join(' ')
|
182
|
+
c == n
|
183
|
+
end
|
184
|
+
|
185
|
+
def compute
|
186
|
+
new_driver.compute
|
187
|
+
end
|
188
|
+
|
189
|
+
def current_public_key
|
190
|
+
current_resource.source_key
|
191
|
+
end
|
192
|
+
|
193
|
+
def new_private_key_path
|
194
|
+
private_key_path = new_resource.private_key_path || new_resource.name
|
195
|
+
if private_key_path.is_a?(Symbol)
|
196
|
+
private_key_path
|
197
|
+
elsif Pathname.new(private_key_path).relative? && new_driver.config[:private_key_write_path]
|
198
|
+
@should_create_directory = true
|
199
|
+
::File.join(new_driver.config[:private_key_write_path], private_key_path)
|
200
|
+
else
|
201
|
+
private_key_path
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def new_public_key_path
|
206
|
+
new_resource.public_key_path
|
207
|
+
end
|
208
|
+
|
209
|
+
def load_current_resource
|
210
|
+
if !new_driver.kind_of?(Chef::Provisioning::FogDriver::Driver)
|
211
|
+
raise 'fog_key_pair only works with fog_driver'
|
212
|
+
end
|
213
|
+
@current_resource = Chef::Resource::FogKeyPair.new(new_resource.name, run_context)
|
214
|
+
case new_driver.provider
|
215
|
+
when 'DigitalOcean'
|
216
|
+
current_key_pair = compute.ssh_keys.select { |key| key.name == new_resource.name }.first
|
217
|
+
if current_key_pair
|
218
|
+
@current_id = current_key_pair.id
|
219
|
+
@current_fingerprint = current_key_pair ? compute.ssh_keys.get(@current_id).ssh_pub_key : nil
|
220
|
+
else
|
221
|
+
current_resource.action :delete
|
222
|
+
end
|
223
|
+
when 'Joyent'
|
224
|
+
current_key_pair = begin
|
225
|
+
compute.keys.get(new_resource.name)
|
226
|
+
rescue Fog::Compute::Joyent::Errors::NotFound
|
227
|
+
nil
|
228
|
+
end
|
229
|
+
if current_key_pair
|
230
|
+
@current_id = current_key_pair.name
|
231
|
+
@current_fingerprint = if current_key_pair.respond_to?(:fingerprint)
|
232
|
+
current_key_pair.fingerprint
|
233
|
+
elsif current_key_pair.respond_to?(:key)
|
234
|
+
public_key, format = Cheffish::KeyFormatter.decode(current_key_pair.key)
|
235
|
+
public_key.fingerprint
|
236
|
+
else
|
237
|
+
nil
|
238
|
+
end
|
239
|
+
else
|
240
|
+
current_resource.action :delete
|
241
|
+
end
|
242
|
+
when 'OpenStack', 'Rackspace'
|
243
|
+
current_key_pair = compute.key_pairs.get(new_resource.name)
|
244
|
+
if current_key_pair
|
245
|
+
@current_id = current_key_pair.name
|
246
|
+
@current_fingerprint = current_key_pair ? compute.key_pairs.get(@current_id).public_key : nil
|
247
|
+
else
|
248
|
+
current_resource.action :delete
|
249
|
+
end
|
250
|
+
else
|
251
|
+
current_key_pair = compute.key_pairs.get(new_resource.name)
|
252
|
+
if current_key_pair
|
253
|
+
@current_fingerprint = current_key_pair ? current_key_pair.fingerprint : nil
|
254
|
+
else
|
255
|
+
current_resource.action :delete
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
if new_private_key_path && ::File.exist?(new_private_key_path)
|
260
|
+
current_resource.private_key_path new_private_key_path
|
261
|
+
end
|
262
|
+
if new_public_key_path && ::File.exist?(new_public_key_path)
|
263
|
+
current_resource.public_key_path new_public_key_path
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|