chef-provisioning-fog 0.14.0 → 0.15.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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +3 -3
  4. data/Rakefile +6 -6
  5. data/lib/chef/provider/fog_key_pair.rb +266 -266
  6. data/lib/chef/provisioning/driver_init/fog.rb +3 -3
  7. data/lib/chef/provisioning/fog_driver/driver.rb +736 -709
  8. data/lib/chef/provisioning/fog_driver/providers/aws.rb +492 -492
  9. data/lib/chef/provisioning/fog_driver/providers/aws/credentials.rb +115 -115
  10. data/lib/chef/provisioning/fog_driver/providers/cloudstack.rb +44 -44
  11. data/lib/chef/provisioning/fog_driver/providers/digitalocean.rb +136 -136
  12. data/lib/chef/provisioning/fog_driver/providers/google.rb +85 -84
  13. data/lib/chef/provisioning/fog_driver/providers/joyent.rb +63 -59
  14. data/lib/chef/provisioning/fog_driver/providers/openstack.rb +117 -41
  15. data/lib/chef/provisioning/fog_driver/providers/rackspace.rb +42 -42
  16. data/lib/chef/provisioning/fog_driver/providers/softlayer.rb +36 -36
  17. data/lib/chef/provisioning/fog_driver/providers/vcair.rb +409 -376
  18. data/lib/chef/provisioning/fog_driver/providers/xenserver.rb +210 -0
  19. data/lib/chef/provisioning/fog_driver/recipe_dsl.rb +32 -32
  20. data/lib/chef/provisioning/fog_driver/version.rb +7 -7
  21. data/lib/chef/resource/fog_key_pair.rb +34 -34
  22. data/spec/spec_helper.rb +18 -18
  23. data/spec/support/aws/config-file.csv +2 -2
  24. data/spec/support/aws/ini-file.ini +10 -10
  25. data/spec/support/chef_metal_fog/providers/testdriver.rb +16 -16
  26. data/spec/unit/chef/provisioning/fog_driver/driver_spec.rb +71 -0
  27. data/spec/unit/fog_driver_spec.rb +32 -32
  28. data/spec/unit/providers/aws/credentials_spec.rb +45 -45
  29. data/spec/unit/providers/rackspace_spec.rb +16 -16
  30. metadata +5 -3
@@ -1,115 +1,115 @@
1
- require 'inifile'
2
- require 'csv'
3
- require 'chef/mixin/deep_merge'
4
-
5
- class Chef
6
- module Provisioning
7
- module FogDriver
8
- module Providers
9
- class AWS
10
- # Reads in a credentials file in Amazon's download format and presents the credentials to you
11
- class Credentials
12
- def initialize
13
- @credentials = {}
14
- end
15
-
16
- include Enumerable
17
- include Chef::Mixin::DeepMerge
18
-
19
- def default
20
- if @credentials.size == 0
21
- raise "No credentials loaded! Do you have one of ~/.aws/credentials or ~/.aws/config?"
22
- end
23
- @credentials[ENV['AWS_DEFAULT_PROFILE'] || 'default'] || @credentials.first[1]
24
- end
25
-
26
- def keys
27
- @credentials.keys
28
- end
29
-
30
- def [](name)
31
- @credentials[name]
32
- end
33
-
34
- def each(&block)
35
- @credentials.each(&block)
36
- end
37
-
38
- def load_inis(config_ini_file, credentials_ini_file = nil)
39
- @credentials = load_config_ini(config_ini_file)
40
- @credentials = deep_merge!(@credentials,
41
- load_credentials_ini(credentials_ini_file)
42
- ) if credentials_ini_file
43
- end
44
-
45
- def load_config_ini(config_ini_file)
46
- inifile = IniFile.load(File.expand_path(config_ini_file))
47
- config = {}
48
- if inifile
49
- inifile.each_section do |section|
50
- if section =~ /^\s*profile\s+(.+)$/ || section =~ /^\s*(default)\s*/
51
- profile_name = $1.strip
52
- profile = inifile[section].inject({}) do |result, pair|
53
- result[pair[0].to_sym] = pair[1]
54
- result
55
- end
56
- profile[:name] = profile_name
57
- config[profile_name] = profile
58
- end
59
- end
60
- end
61
- config
62
- end
63
-
64
- def load_credentials_ini(credentials_ini_file)
65
- inifile = IniFile.load(File.expand_path(credentials_ini_file))
66
- config = {}
67
- if inifile
68
- inifile.each_section do |section|
69
- profile = inifile[section].inject({}) do |result, pair|
70
- result[pair[0].to_sym] = pair[1]
71
- result
72
- end
73
- profile[:name] = section
74
- config[section] = profile
75
- end
76
- end
77
- config
78
- end
79
-
80
- def load_csv(credentials_csv_file)
81
- CSV.new(File.open(credentials_csv_file), :headers => :first_row).each do |row|
82
- @credentials[row['User Name']] = {
83
- :name => row['User Name'],
84
- :user_name => row['User Name'],
85
- :aws_access_key_id => row['Access Key Id'],
86
- :aws_secret_access_key => row['Secret Access Key']
87
- }
88
- end
89
- end
90
-
91
- def load_default
92
- config_file = ENV['AWS_CONFIG_FILE'] || File.expand_path('~/.aws/config')
93
- credentials_file = ENV['AWS_CREDENTIAL_FILE'] || File.expand_path('~/.aws/credentials')
94
- if File.file?(config_file)
95
- if File.file?(credentials_file)
96
- load_inis(config_file, credentials_file)
97
- else
98
- load_inis(config_file)
99
- end
100
- end
101
- end
102
-
103
- def self.method_missing(name, *args, &block)
104
- singleton.send(name, *args, &block)
105
- end
106
-
107
- def self.singleton
108
- @aws_credentials ||= Credentials.new
109
- end
110
- end
111
- end
112
- end
113
- end
114
- end
115
- end
1
+ require 'inifile'
2
+ require 'csv'
3
+ require 'chef/mixin/deep_merge'
4
+
5
+ class Chef
6
+ module Provisioning
7
+ module FogDriver
8
+ module Providers
9
+ class AWS
10
+ # Reads in a credentials file in Amazon's download format and presents the credentials to you
11
+ class Credentials
12
+ def initialize
13
+ @credentials = {}
14
+ end
15
+
16
+ include Enumerable
17
+ include Chef::Mixin::DeepMerge
18
+
19
+ def default
20
+ if @credentials.size == 0
21
+ raise "No credentials loaded! Do you have one of ~/.aws/credentials or ~/.aws/config?"
22
+ end
23
+ @credentials[ENV['AWS_DEFAULT_PROFILE'] || 'default'] || @credentials.first[1]
24
+ end
25
+
26
+ def keys
27
+ @credentials.keys
28
+ end
29
+
30
+ def [](name)
31
+ @credentials[name]
32
+ end
33
+
34
+ def each(&block)
35
+ @credentials.each(&block)
36
+ end
37
+
38
+ def load_inis(config_ini_file, credentials_ini_file = nil)
39
+ @credentials = load_config_ini(config_ini_file)
40
+ @credentials = deep_merge!(@credentials,
41
+ load_credentials_ini(credentials_ini_file)
42
+ ) if credentials_ini_file
43
+ end
44
+
45
+ def load_config_ini(config_ini_file)
46
+ inifile = IniFile.load(File.expand_path(config_ini_file))
47
+ config = {}
48
+ if inifile
49
+ inifile.each_section do |section|
50
+ if section =~ /^\s*profile\s+(.+)$/ || section =~ /^\s*(default)\s*/
51
+ profile_name = $1.strip
52
+ profile = inifile[section].inject({}) do |result, pair|
53
+ result[pair[0].to_sym] = pair[1]
54
+ result
55
+ end
56
+ profile[:name] = profile_name
57
+ config[profile_name] = profile
58
+ end
59
+ end
60
+ end
61
+ config
62
+ end
63
+
64
+ def load_credentials_ini(credentials_ini_file)
65
+ inifile = IniFile.load(File.expand_path(credentials_ini_file))
66
+ config = {}
67
+ if inifile
68
+ inifile.each_section do |section|
69
+ profile = inifile[section].inject({}) do |result, pair|
70
+ result[pair[0].to_sym] = pair[1]
71
+ result
72
+ end
73
+ profile[:name] = section
74
+ config[section] = profile
75
+ end
76
+ end
77
+ config
78
+ end
79
+
80
+ def load_csv(credentials_csv_file)
81
+ CSV.new(File.open(credentials_csv_file), :headers => :first_row).each do |row|
82
+ @credentials[row['User Name']] = {
83
+ :name => row['User Name'],
84
+ :user_name => row['User Name'],
85
+ :aws_access_key_id => row['Access Key Id'],
86
+ :aws_secret_access_key => row['Secret Access Key']
87
+ }
88
+ end
89
+ end
90
+
91
+ def load_default
92
+ config_file = ENV['AWS_CONFIG_FILE'] || File.expand_path('~/.aws/config')
93
+ credentials_file = ENV['AWS_CREDENTIAL_FILE'] || File.expand_path('~/.aws/credentials')
94
+ if File.file?(config_file)
95
+ if File.file?(credentials_file)
96
+ load_inis(config_file, credentials_file)
97
+ else
98
+ load_inis(config_file)
99
+ end
100
+ end
101
+ end
102
+
103
+ def self.method_missing(name, *args, &block)
104
+ singleton.send(name, *args, &block)
105
+ end
106
+
107
+ def self.singleton
108
+ @aws_credentials ||= Credentials.new
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -1,44 +1,44 @@
1
- class Chef
2
- module Provisioning
3
- module FogDriver
4
- module Providers
5
- class CloudStack < FogDriver::Driver
6
-
7
- Driver.register_provider_class('CloudStack', FogDriver::Providers::CloudStack)
8
-
9
- def creator
10
- ''
11
- end
12
-
13
- def self.compute_options_for(provider, id, config)
14
- new_compute_options = {}
15
- new_compute_options[:provider] = provider
16
- new_config = { :driver_options => { :compute_options => new_compute_options }}
17
- new_defaults = {
18
- :driver_options => { :compute_options => {} },
19
- :machine_options => { :bootstrap_options => {} }
20
- }
21
- result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
22
-
23
- if id && id != ''
24
- cloudstack_uri = URI.parse(id)
25
- new_compute_options[:cloudstack_scheme] = cloudstack_uri.scheme
26
- new_compute_options[:cloudstack_host] = cloudstack_uri.host
27
- new_compute_options[:cloudstack_port] = cloudstack_uri.port
28
- new_compute_options[:cloudstack_path] = cloudstack_uri.path
29
- end
30
-
31
- host = result[:driver_options][:compute_options][:cloudstack_host]
32
- path = result[:driver_options][:compute_options][:cloudstack_path] || '/client/api'
33
- port = result[:driver_options][:compute_options][:cloudstack_port] || 443
34
- scheme = result[:driver_options][:compute_options][:cloudstack_scheme] || 'https'
35
- id = URI.scheme_list[scheme.upcase].build(:host => host, :port => port, :path => path).to_s
36
-
37
- [result, id]
38
- end
39
-
40
- end
41
- end
42
- end
43
- end
44
- end
1
+ class Chef
2
+ module Provisioning
3
+ module FogDriver
4
+ module Providers
5
+ class CloudStack < FogDriver::Driver
6
+
7
+ Driver.register_provider_class('CloudStack', FogDriver::Providers::CloudStack)
8
+
9
+ def creator
10
+ ''
11
+ end
12
+
13
+ def self.compute_options_for(provider, id, config)
14
+ new_compute_options = {}
15
+ new_compute_options[:provider] = provider
16
+ new_config = { :driver_options => { :compute_options => new_compute_options }}
17
+ new_defaults = {
18
+ :driver_options => { :compute_options => {} },
19
+ :machine_options => { :bootstrap_options => {} }
20
+ }
21
+ result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
22
+
23
+ if id && id != ''
24
+ cloudstack_uri = URI.parse(id)
25
+ new_compute_options[:cloudstack_scheme] = cloudstack_uri.scheme
26
+ new_compute_options[:cloudstack_host] = cloudstack_uri.host
27
+ new_compute_options[:cloudstack_port] = cloudstack_uri.port
28
+ new_compute_options[:cloudstack_path] = cloudstack_uri.path
29
+ end
30
+
31
+ host = result[:driver_options][:compute_options][:cloudstack_host]
32
+ path = result[:driver_options][:compute_options][:cloudstack_path] || '/client/api'
33
+ port = result[:driver_options][:compute_options][:cloudstack_port] || 443
34
+ scheme = result[:driver_options][:compute_options][:cloudstack_scheme] || 'https'
35
+ id = URI.scheme_list[scheme.upcase].build(:host => host, :port => port, :path => path).to_s
36
+
37
+ [result, id]
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,136 +1,136 @@
1
- # fog:DigitalOcean:<client id>
2
- class Chef
3
- module Provisioning
4
- module FogDriver
5
- module Providers
6
- class DigitalOcean < FogDriver::Driver
7
- Driver.register_provider_class('DigitalOcean', FogDriver::Providers::DigitalOcean)
8
-
9
- def creator
10
- ''
11
- end
12
-
13
- def converge_floating_ips(action_handler, machine_spec, machine_options, server)
14
- # DigitalOcean does not have floating IPs
15
- end
16
-
17
- def bootstrap_options_for(action_handler, machine_spec, machine_options)
18
- bootstrap_options = symbolize_keys(machine_options[:bootstrap_options] || {})
19
- if bootstrap_options[:key_path]
20
- bootstrap_options[:key_name] ||= File.basename(bootstrap_options[:key_path])
21
- # Verify that the provided key name and path are in line (or create the key pair if not!)
22
- driver = self
23
- Provisioning.inline_resource(action_handler) do
24
- fog_key_pair bootstrap_options[:key_name] do
25
- private_key_path bootstrap_options[:key_path]
26
- driver driver
27
- end
28
- end
29
- else
30
- bootstrap_options[:key_name] = overwrite_default_key_willy_nilly(action_handler, machine_spec)
31
- end
32
-
33
- bootstrap_options[:tags] = default_tags(machine_spec, bootstrap_options[:tags] || {})
34
-
35
- if !bootstrap_options[:image_id]
36
- if !bootstrap_options[:image_distribution] && !bootstrap_options[:image_name]
37
- bootstrap_options[:image_distribution] = 'CentOS'
38
- bootstrap_options[:image_name] = '6.5 x64'
39
- end
40
- distributions = compute.images.select { |image| image.distribution == bootstrap_options[:image_distribution] }
41
- if distributions.empty?
42
- raise "No images on DigitalOcean with distribution #{bootstrap_options[:image_distribution].inspect}"
43
- end
44
- images = distributions.select { |image| image.name == bootstrap_options[:image_name] } if bootstrap_options[:image_name]
45
- if images.empty?
46
- raise "No images on DigitalOcean with distribution #{bootstrap_options[:image_distribution].inspect} and name #{bootstrap_options[:image_name].inspect}"
47
- end
48
- bootstrap_options[:image_id] = images.first.id
49
- end
50
- if !bootstrap_options[:flavor_id]
51
- bootstrap_options[:flavor_name] ||= '512MB'
52
- flavors = compute.flavors.select do |f|
53
- f.name == bootstrap_options[:flavor_name]
54
- end
55
- if flavors.empty?
56
- raise "Could not find flavor named '#{bootstrap_options[:flavor_name]}' on #{driver_url}"
57
- end
58
- bootstrap_options[:flavor_id] = flavors.first.id
59
- end
60
- if !bootstrap_options[:region_id]
61
- bootstrap_options[:region_name] ||= 'San Francisco 1'
62
- regions = compute.regions.select { |region| region.name == bootstrap_options[:region_name] }
63
- if regions.empty?
64
- raise "Could not find region named '#{bootstrap_options[:region_name]}' on #{driver_url}"
65
- end
66
- bootstrap_options[:region_id] = regions.first.id
67
- end
68
- keys = compute.ssh_keys.select { |k| k.name == bootstrap_options[:key_name] }
69
- if keys.empty?
70
- raise "Could not find key named '#{bootstrap_options[:key_name]}' on #{driver_url}"
71
- end
72
- found_key = keys.first
73
- bootstrap_options[:ssh_key_ids] ||= [ found_key.id ]
74
-
75
- # You don't get to specify name yourself
76
- bootstrap_options[:name] = machine_spec.name
77
-
78
- bootstrap_options
79
- end
80
-
81
- def destroy_machine(action_handler, machine_spec, machine_options)
82
- server = server_for(machine_spec)
83
- if server && server.state != 'archive'
84
- action_handler.perform_action "destroy machine #{machine_spec.name} (#{machine_spec.location['server_id']} at #{driver_url})" do
85
- server.destroy
86
- end
87
- end
88
- machine_spec.location = nil
89
- strategy = convergence_strategy_for(machine_spec, machine_options)
90
- strategy.cleanup_convergence(action_handler, machine_spec)
91
- end
92
-
93
- def self.compute_options_for(provider, id, config)
94
- new_compute_options = {}
95
- new_compute_options[:provider] = provider
96
- new_config = { :driver_options => { :compute_options => new_compute_options }}
97
- new_defaults = {
98
- :driver_options => { :compute_options => {} },
99
- :machine_options => { :bootstrap_options => {}, :ssh_options => {} }
100
- }
101
- result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
102
-
103
- new_compute_options[:digitalocean_client_id] = id if (id && id != '')
104
-
105
- # This uses ~/.tugboat, generated by "tugboat authorize" - see https://github.com/pearkes/tugboat
106
- tugboat_file = File.expand_path('~/.tugboat')
107
- if File.exist?(tugboat_file)
108
- tugboat_data = YAML.load(IO.read(tugboat_file))
109
-
110
- new_bootstrap_options = new_defaults[:machine_options][:bootstrap_options]
111
- if tugboat_data['authentication']
112
- new_compute_options[:digitalocean_client_id] = tugboat_data['authentication']['client_key'] if tugboat_data['authentication']['client_key'] && tugboat_data['authentication']['client_key'].size > 0
113
- new_compute_options[:digitalocean_api_key] = tugboat_data['authentication']['api_key'] if tugboat_data['authentication']['api_key'] && tugboat_data['authentication']['api_key'].size > 0
114
- end
115
- if tugboat_data['defaults']
116
- new_bootstrap_options[:region_id] = tugboat_data['defaults']['region'].to_i if tugboat_data['defaults']['region'] && tugboat_data['defaults']['region'].size > 0
117
- new_bootstrap_options[:image_id] = tugboat_data['defaults']['image'].to_i if tugboat_data['defaults']['image'] && tugboat_data['defaults']['image'].size > 0
118
- new_bootstrap_options[:size_id] = tugboat_data['defaults']['size'].to_i if tugboat_data['defaults']['size'] && tugboat_data['defaults']['size'].size > 0
119
- new_bootstrap_options[:private_networking] = (tugboat_data['defaults']['private_networking'] == 'true') if tugboat_data['defaults']['private_networking'] && tugboat_data['defaults']['private_networking'].size > 0
120
- new_bootstrap_options[:backups_enabled] = (tugboat_data['defaults']['backups_enabled'] == 'true') if tugboat_data['defaults']['backups_enabled'] && tugboat_data['defaults']['backups_enabled'].size > 0
121
- new_bootstrap_options[:key_name] = tugboat_data['defaults']['ssh_key'] if tugboat_data['defaults']['ssh_key'] && tugboat_data['defaults']['ssh_key'].size > 0
122
- end
123
- if tugboat_data['ssh']
124
- new_bootstrap_options[:key_path] = tugboat_data['ssh']['ssh_key_path'] if tugboat_data['ssh']['ssh_key_path'] && tugboat_data['ssh']['ssh_key_path'].size > 0
125
- new_defaults[:machine_options][:ssh_options][:port] = tugboat_data['ssh']['ssh_port'] if tugboat_data['ssh']['ssh_port'] if tugboat_data['ssh']['ssh_port'].size > 0
126
- end
127
- end
128
-
129
- [result, new_compute_options[:digitalocean_client_id]]
130
- end
131
-
132
- end
133
- end
134
- end
135
- end
136
- end
1
+ # fog:DigitalOcean:<client id>
2
+ class Chef
3
+ module Provisioning
4
+ module FogDriver
5
+ module Providers
6
+ class DigitalOcean < FogDriver::Driver
7
+ Driver.register_provider_class('DigitalOcean', FogDriver::Providers::DigitalOcean)
8
+
9
+ def creator
10
+ ''
11
+ end
12
+
13
+ def converge_floating_ips(action_handler, machine_spec, machine_options, server)
14
+ # DigitalOcean does not have floating IPs
15
+ end
16
+
17
+ def bootstrap_options_for(action_handler, machine_spec, machine_options)
18
+ bootstrap_options = symbolize_keys(machine_options[:bootstrap_options] || {})
19
+ if bootstrap_options[:key_path]
20
+ bootstrap_options[:key_name] ||= File.basename(bootstrap_options[:key_path])
21
+ # Verify that the provided key name and path are in line (or create the key pair if not!)
22
+ driver = self
23
+ Provisioning.inline_resource(action_handler) do
24
+ fog_key_pair bootstrap_options[:key_name] do
25
+ private_key_path bootstrap_options[:key_path]
26
+ driver driver
27
+ end
28
+ end
29
+ else
30
+ bootstrap_options[:key_name] = overwrite_default_key_willy_nilly(action_handler, machine_spec)
31
+ end
32
+
33
+ bootstrap_options[:tags] = default_tags(machine_spec, bootstrap_options[:tags] || {})
34
+
35
+ if !bootstrap_options[:image_id]
36
+ if !bootstrap_options[:image_distribution] && !bootstrap_options[:image_name]
37
+ bootstrap_options[:image_distribution] = 'CentOS'
38
+ bootstrap_options[:image_name] = '6.5 x64'
39
+ end
40
+ distributions = compute.images.select { |image| image.distribution == bootstrap_options[:image_distribution] }
41
+ if distributions.empty?
42
+ raise "No images on DigitalOcean with distribution #{bootstrap_options[:image_distribution].inspect}"
43
+ end
44
+ images = distributions.select { |image| image.name == bootstrap_options[:image_name] } if bootstrap_options[:image_name]
45
+ if images.empty?
46
+ raise "No images on DigitalOcean with distribution #{bootstrap_options[:image_distribution].inspect} and name #{bootstrap_options[:image_name].inspect}"
47
+ end
48
+ bootstrap_options[:image_id] = images.first.id
49
+ end
50
+ if !bootstrap_options[:flavor_id]
51
+ bootstrap_options[:flavor_name] ||= '512MB'
52
+ flavors = compute.flavors.select do |f|
53
+ f.name == bootstrap_options[:flavor_name]
54
+ end
55
+ if flavors.empty?
56
+ raise "Could not find flavor named '#{bootstrap_options[:flavor_name]}' on #{driver_url}"
57
+ end
58
+ bootstrap_options[:flavor_id] = flavors.first.id
59
+ end
60
+ if !bootstrap_options[:region_id]
61
+ bootstrap_options[:region_name] ||= 'San Francisco 1'
62
+ regions = compute.regions.select { |region| region.name == bootstrap_options[:region_name] }
63
+ if regions.empty?
64
+ raise "Could not find region named '#{bootstrap_options[:region_name]}' on #{driver_url}"
65
+ end
66
+ bootstrap_options[:region_id] = regions.first.id
67
+ end
68
+ keys = compute.ssh_keys.select { |k| k.name == bootstrap_options[:key_name] }
69
+ if keys.empty?
70
+ raise "Could not find key named '#{bootstrap_options[:key_name]}' on #{driver_url}"
71
+ end
72
+ found_key = keys.first
73
+ bootstrap_options[:ssh_key_ids] ||= [ found_key.id ]
74
+
75
+ # You don't get to specify name yourself
76
+ bootstrap_options[:name] = machine_spec.name
77
+
78
+ bootstrap_options
79
+ end
80
+
81
+ def destroy_machine(action_handler, machine_spec, machine_options)
82
+ server = server_for(machine_spec)
83
+ if server && server.state != 'archive'
84
+ action_handler.perform_action "destroy machine #{machine_spec.name} (#{machine_spec.location['server_id']} at #{driver_url})" do
85
+ server.destroy
86
+ end
87
+ end
88
+ machine_spec.location = nil
89
+ strategy = convergence_strategy_for(machine_spec, machine_options)
90
+ strategy.cleanup_convergence(action_handler, machine_spec)
91
+ end
92
+
93
+ def self.compute_options_for(provider, id, config)
94
+ new_compute_options = {}
95
+ new_compute_options[:provider] = provider
96
+ new_config = { :driver_options => { :compute_options => new_compute_options }}
97
+ new_defaults = {
98
+ :driver_options => { :compute_options => {} },
99
+ :machine_options => { :bootstrap_options => {}, :ssh_options => {} }
100
+ }
101
+ result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
102
+
103
+ new_compute_options[:digitalocean_client_id] = id if (id && id != '')
104
+
105
+ # This uses ~/.tugboat, generated by "tugboat authorize" - see https://github.com/pearkes/tugboat
106
+ tugboat_file = File.expand_path('~/.tugboat')
107
+ if File.exist?(tugboat_file)
108
+ tugboat_data = YAML.load(IO.read(tugboat_file))
109
+
110
+ new_bootstrap_options = new_defaults[:machine_options][:bootstrap_options]
111
+ if tugboat_data['authentication']
112
+ new_compute_options[:digitalocean_client_id] = tugboat_data['authentication']['client_key'] if tugboat_data['authentication']['client_key'] && tugboat_data['authentication']['client_key'].size > 0
113
+ new_compute_options[:digitalocean_api_key] = tugboat_data['authentication']['api_key'] if tugboat_data['authentication']['api_key'] && tugboat_data['authentication']['api_key'].size > 0
114
+ end
115
+ if tugboat_data['defaults']
116
+ new_bootstrap_options[:region_id] = tugboat_data['defaults']['region'].to_i if tugboat_data['defaults']['region'] && tugboat_data['defaults']['region'].size > 0
117
+ new_bootstrap_options[:image_id] = tugboat_data['defaults']['image'].to_i if tugboat_data['defaults']['image'] && tugboat_data['defaults']['image'].size > 0
118
+ new_bootstrap_options[:size_id] = tugboat_data['defaults']['size'].to_i if tugboat_data['defaults']['size'] && tugboat_data['defaults']['size'].size > 0
119
+ new_bootstrap_options[:private_networking] = (tugboat_data['defaults']['private_networking'] == 'true') if tugboat_data['defaults']['private_networking'] && tugboat_data['defaults']['private_networking'].size > 0
120
+ new_bootstrap_options[:backups_enabled] = (tugboat_data['defaults']['backups_enabled'] == 'true') if tugboat_data['defaults']['backups_enabled'] && tugboat_data['defaults']['backups_enabled'].size > 0
121
+ new_bootstrap_options[:key_name] = tugboat_data['defaults']['ssh_key'] if tugboat_data['defaults']['ssh_key'] && tugboat_data['defaults']['ssh_key'].size > 0
122
+ end
123
+ if tugboat_data['ssh']
124
+ new_bootstrap_options[:key_path] = tugboat_data['ssh']['ssh_key_path'] if tugboat_data['ssh']['ssh_key_path'] && tugboat_data['ssh']['ssh_key_path'].size > 0
125
+ new_defaults[:machine_options][:ssh_options][:port] = tugboat_data['ssh']['ssh_port'] if tugboat_data['ssh']['ssh_port'] if tugboat_data['ssh']['ssh_port'].size > 0
126
+ end
127
+ end
128
+
129
+ [result, new_compute_options[:digitalocean_client_id]]
130
+ end
131
+
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end