chef-provisioning-fog 0.10 → 0.11
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/lib/chef/provisioning/fog_driver.rb +1 -0
- data/lib/chef/provisioning/fog_driver/driver.rb +37 -18
- data/lib/chef/provisioning/fog_driver/providers/aws.rb +97 -0
- data/lib/chef/provisioning/fog_driver/version.rb +1 -1
- data/lib/chef/resource/fog_key_pair.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe71d09d45a8426eb7af5b9367aac358cf752124
|
4
|
+
data.tar.gz: 0c454ebeb8827924742c91f1c566c90f6d6f3560
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 121ff3e73fefe9f6b401727831a46d47b2a7550c07fe0f6ec71915883e7ff7da8626a0989758b674768593149046ecb3a3ba49cb55fffcd112dd2a1d7364b9e8
|
7
|
+
data.tar.gz: 34447372a2c4605cc90b4a476aef6454be76892ccfd88b27a85d93edce61d86e810888d115cadba6425f8cd7706579bad125850e8473af1ebda42b542a0f5aa2
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'chef/provisioning/fog_driver/driver'
|
@@ -10,7 +10,9 @@ require 'chef/provisioning/convergence_strategy/install_sh'
|
|
10
10
|
require 'chef/provisioning/convergence_strategy/install_cached'
|
11
11
|
require 'chef/provisioning/convergence_strategy/no_converge'
|
12
12
|
require 'chef/provisioning/transport/ssh'
|
13
|
+
require 'chef/provisioning/transport/winrm'
|
13
14
|
require 'chef/provisioning/fog_driver/version'
|
15
|
+
|
14
16
|
require 'fog'
|
15
17
|
require 'fog/core'
|
16
18
|
require 'fog/compute'
|
@@ -258,9 +260,15 @@ module FogDriver
|
|
258
260
|
end
|
259
261
|
|
260
262
|
# Not meant to be part of public interface
|
261
|
-
def transport_for(machine_spec, machine_options, server)
|
262
|
-
|
263
|
-
|
263
|
+
def transport_for(machine_spec, machine_options, server, action_handler = nil)
|
264
|
+
if machine_spec.location['is_windows']
|
265
|
+
action_handler.report_progress "Waiting for admin password on #{machine_spec.name} to be ready (may take up to 15 minutes)..." if action_handler
|
266
|
+
transport = create_winrm_transport(machine_spec, machine_options, server)
|
267
|
+
action_handler.report_progress 'Admin password available ...' if action_handler
|
268
|
+
transport
|
269
|
+
else
|
270
|
+
create_ssh_transport(machine_spec, machine_options, server)
|
271
|
+
end
|
264
272
|
end
|
265
273
|
|
266
274
|
protected
|
@@ -400,7 +408,8 @@ module FogDriver
|
|
400
408
|
end
|
401
409
|
|
402
410
|
def wait_for_transport(action_handler, machine_spec, machine_options, server)
|
403
|
-
|
411
|
+
|
412
|
+
transport = transport_for(machine_spec, machine_options, server, action_handler)
|
404
413
|
if !transport.available?
|
405
414
|
if action_handler.should_perform_actions
|
406
415
|
action_handler.report_progress "waiting for #{machine_spec.name} (#{server.id} on #{driver_url}) to be connectable (transport up and running) ..."
|
@@ -560,37 +569,43 @@ module FogDriver
|
|
560
569
|
end
|
561
570
|
end
|
562
571
|
|
563
|
-
|
564
|
-
|
565
|
-
#
|
566
|
-
#
|
567
|
-
#
|
568
|
-
|
569
|
-
:keys_only => true,
|
570
|
-
:host_key_alias => "#{server.id}.#{provider}"
|
571
|
-
}.merge(machine_options[:ssh_options] || {})
|
572
|
+
# Get the private key for a machine - prioritize the server data, fall back to the
|
573
|
+
# the machine spec data, and if that doesn't work, raise an exception.
|
574
|
+
# @param [Hash] machine_spec Machine spec data
|
575
|
+
# @param [Chef::Provisioning::Machine] server a Machine representing the server
|
576
|
+
# @return [String] PEM-encoded private key
|
577
|
+
def private_key_for(machine_spec, server)
|
572
578
|
if server.respond_to?(:private_key) && server.private_key
|
573
|
-
|
579
|
+
server.private_key
|
574
580
|
elsif server.respond_to?(:key_name) && server.key_name
|
575
581
|
key = get_private_key(server.key_name)
|
576
582
|
if !key
|
577
583
|
raise "Server has key name '#{server.key_name}', but the corresponding private key was not found locally. Check if the key is in Chef::Config.private_key_paths: #{Chef::Config.private_key_paths.join(', ')}"
|
578
584
|
end
|
579
|
-
|
585
|
+
key
|
580
586
|
elsif machine_spec.location['key_name']
|
581
587
|
key = get_private_key(machine_spec.location['key_name'])
|
582
588
|
if !key
|
583
589
|
raise "Server was created with key name '#{machine_spec.location['key_name']}', but the corresponding private key was not found locally. Check if the key is in Chef::Config.private_key_paths: #{Chef::Config.private_key_paths.join(', ')}"
|
584
590
|
end
|
585
|
-
|
591
|
+
key
|
586
592
|
elsif machine_options[:bootstrap_options][:key_path]
|
587
|
-
|
593
|
+
IO.read(machine_options[:bootstrap_options][:key_path])
|
588
594
|
elsif machine_options[:bootstrap_options][:key_name]
|
589
|
-
|
595
|
+
get_private_key(machine_options[:bootstrap_options][:key_name])
|
590
596
|
else
|
591
597
|
# TODO make a way to suggest other keys to try ...
|
592
598
|
raise "No key found to connect to #{machine_spec.name} (#{machine_spec.location.inspect})!"
|
593
599
|
end
|
600
|
+
end
|
601
|
+
|
602
|
+
def ssh_options_for(machine_spec, machine_options, server)
|
603
|
+
result = {
|
604
|
+
:auth_methods => [ 'publickey' ],
|
605
|
+
:keys_only => true,
|
606
|
+
:host_key_alias => "#{server.id}.#{provider}"
|
607
|
+
}.merge(machine_options[:ssh_options] || {})
|
608
|
+
result[:key_data] = [ private_key_for(machine_spec, server) ]
|
594
609
|
result
|
595
610
|
end
|
596
611
|
|
@@ -598,6 +613,10 @@ module FogDriver
|
|
598
613
|
'root'
|
599
614
|
end
|
600
615
|
|
616
|
+
def create_winrm_transport(machine_spec, machine_options, server)
|
617
|
+
fail "This provider doesn't know how to do that."
|
618
|
+
end
|
619
|
+
|
601
620
|
def create_ssh_transport(machine_spec, machine_options, server)
|
602
621
|
ssh_options = ssh_options_for(machine_spec, machine_options, server)
|
603
622
|
username = machine_spec.location['ssh_username'] || default_ssh_username
|
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'chef/log'
|
2
2
|
require 'fog/aws'
|
3
3
|
require 'uri'
|
4
|
+
require 'base64'
|
5
|
+
require 'openssl'
|
6
|
+
require 'pathname'
|
7
|
+
require 'chef/provisioning/transport/winrm'
|
4
8
|
|
5
9
|
# fog:AWS:<account_id>:<region>
|
6
10
|
# fog:AWS:<profile_name>
|
@@ -23,6 +27,45 @@ module FogDriver
|
|
23
27
|
'ubuntu'
|
24
28
|
end
|
25
29
|
|
30
|
+
# Create a WinRM transport for an AWS instance
|
31
|
+
# @param [Hash] machine_spec Machine-spec hash
|
32
|
+
# @param [Hash] machine_options Machine options (from the recipe)
|
33
|
+
# @param [Fog::Compute::Server] server A Fog mapping to the AWS instance
|
34
|
+
# @return [ChefMetal::Transport::WinRM] A WinRM Transport object to talk to the server
|
35
|
+
def create_winrm_transport(machine_spec, machine_options, server)
|
36
|
+
remote_host = if machine_spec.location['use_private_ip_for_ssh']
|
37
|
+
server.private_ip_address
|
38
|
+
elsif !server.public_ip_address
|
39
|
+
Chef::Log.warn("Server #{machine_spec.name} has no public ip address. Using private ip '#{server.private_ip_address}'. Set driver option 'use_private_ip_for_ssh' => true if this will always be the case ...")
|
40
|
+
server.private_ip_address
|
41
|
+
elsif server.public_ip_address
|
42
|
+
server.public_ip_address
|
43
|
+
else
|
44
|
+
fail "Server #{server.id} has no private or public IP address!"
|
45
|
+
end
|
46
|
+
|
47
|
+
port = machine_spec.location['winrm_port'] || 5985
|
48
|
+
endpoint = "http://#{remote_host}:#{port}/wsman"
|
49
|
+
type = :plaintext
|
50
|
+
pem_bytes = private_key_for(machine_spec, server)
|
51
|
+
encrypted_admin_password = wait_for_admin_password(machine_spec)
|
52
|
+
decoded = Base64.decode64(encrypted_admin_password)
|
53
|
+
private_key = OpenSSL::PKey::RSA.new(pem_bytes)
|
54
|
+
decrypted_password = private_key.private_decrypt decoded
|
55
|
+
|
56
|
+
# Use basic HTTP auth - this is required for the WinRM setup we
|
57
|
+
# are using
|
58
|
+
# TODO: Improve that.
|
59
|
+
options = {
|
60
|
+
:user => machine_spec.location['winrm.username'] || 'Administrator',
|
61
|
+
:pass => decrypted_password,
|
62
|
+
:disable_sspi => true,
|
63
|
+
:basic_auth_only => true
|
64
|
+
}
|
65
|
+
|
66
|
+
Chef::Provisioning::Transport::WinRM.new(endpoint, type, options, {})
|
67
|
+
end
|
68
|
+
|
26
69
|
def allocate_image(action_handler, image_spec, image_options, machine_spec)
|
27
70
|
if image_spec.location
|
28
71
|
image = compute.images.get(image_spec.location['image_id'])
|
@@ -87,6 +130,12 @@ module FogDriver
|
|
87
130
|
if !bootstrap_options[:key_name]
|
88
131
|
bootstrap_options[:key_name] = overwrite_default_key_willy_nilly(action_handler, machine_spec)
|
89
132
|
end
|
133
|
+
|
134
|
+
if machine_options[:is_windows]
|
135
|
+
Chef::Log.debug('Attaching WinRM data for user data.')
|
136
|
+
# Enable WinRM basic auth, HTTP and open the firewall
|
137
|
+
bootstrap_options[:user_data] = user_data
|
138
|
+
end
|
90
139
|
bootstrap_options.delete(:tags) # we handle these separately for performance reasons
|
91
140
|
bootstrap_options
|
92
141
|
end
|
@@ -351,6 +400,27 @@ module FogDriver
|
|
351
400
|
end
|
352
401
|
|
353
402
|
private
|
403
|
+
def user_data
|
404
|
+
# TODO: Make this use HTTPS at some point.
|
405
|
+
<<EOD
|
406
|
+
<powershell>
|
407
|
+
winrm quickconfig -q
|
408
|
+
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
|
409
|
+
winrm set winrm/config '@{MaxTimeoutms="1800000"}'
|
410
|
+
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
|
411
|
+
winrm set winrm/config/service/auth '@{Basic="true"}'
|
412
|
+
|
413
|
+
netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow
|
414
|
+
netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow
|
415
|
+
|
416
|
+
net stop winrm
|
417
|
+
sc config winrm start=auto
|
418
|
+
net start winrm
|
419
|
+
</powershell>
|
420
|
+
|
421
|
+
EOD
|
422
|
+
end
|
423
|
+
|
354
424
|
def self.default_ami_for_region(region)
|
355
425
|
Chef::Log.debug("Choosing default AMI for region '#{region}'")
|
356
426
|
|
@@ -374,6 +444,33 @@ module FogDriver
|
|
374
444
|
end
|
375
445
|
end
|
376
446
|
|
447
|
+
# Wait for the Windows Admin password to become available
|
448
|
+
# @param [Hash] machine_spec Machine spec data
|
449
|
+
# @return [String] encrypted admin password
|
450
|
+
def wait_for_admin_password(machine_spec)
|
451
|
+
time_elapsed = 0
|
452
|
+
sleep_time = 10
|
453
|
+
max_wait_time = 900 # 15 minutes
|
454
|
+
encrypted_admin_password = nil
|
455
|
+
instance_id = machine_spec.location['server_id']
|
456
|
+
|
457
|
+
|
458
|
+
Chef::Log.info "waiting for #{machine_spec.name}'s admin password to be available..."
|
459
|
+
while time_elapsed < max_wait_time && encrypted_admin_password.nil?
|
460
|
+
response = compute.get_password_data(instance_id)
|
461
|
+
encrypted_admin_password = response.body['passwordData']
|
462
|
+
if encrypted_admin_password.nil?
|
463
|
+
Chef::Log.info "#{time_elapsed}/#{max_wait_time}s elapsed -- sleeping #{sleep_time} seconds for #{machine_spec.name}'s admin password."
|
464
|
+
sleep(sleep_time)
|
465
|
+
time_elapsed += sleep_time
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
Chef::Log.info "#{machine_spec.name}'s admin password is available!'"
|
470
|
+
|
471
|
+
encrypted_admin_password
|
472
|
+
end
|
473
|
+
|
377
474
|
end
|
378
475
|
end
|
379
476
|
end
|
@@ -28,7 +28,7 @@ class Chef::Resource::FogKeyPair < Chef::Resource::LWRPBase
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# We are not interested in Chef's cloning behavior here.
|
31
|
-
def load_prior_resource
|
31
|
+
def load_prior_resource(*args)
|
32
32
|
Chef::Log.debug("Overloading #{resource_name}.load_prior_resource with NOOP")
|
33
33
|
end
|
34
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-provisioning-fog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.11'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- Rakefile
|
108
108
|
- lib/chef/provider/fog_key_pair.rb
|
109
109
|
- lib/chef/provisioning/driver_init/fog.rb
|
110
|
+
- lib/chef/provisioning/fog_driver.rb
|
110
111
|
- lib/chef/provisioning/fog_driver/driver.rb
|
111
112
|
- lib/chef/provisioning/fog_driver/providers/aws.rb
|
112
113
|
- lib/chef/provisioning/fog_driver/providers/aws/credentials.rb
|