chef-provisioning-fog 0.26.1 → 0.26.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +29 -8
- data/Rakefile +23 -12
- data/chef-provisioning-fog.gemspec +24 -27
- data/lib/chef/provider/fog_key_pair.rb +49 -53
- data/lib/chef/provider/scaleway_volume.rb +46 -48
- data/lib/chef/provisioning/driver_init/fog.rb +1 -1
- data/lib/chef/provisioning/fog_driver/driver.rb +646 -653
- data/lib/chef/provisioning/fog_driver/providers/aws.rb +411 -422
- data/lib/chef/provisioning/fog_driver/providers/aws/credentials.rb +88 -90
- data/lib/chef/provisioning/fog_driver/providers/cloudstack.rb +32 -34
- data/lib/chef/provisioning/fog_driver/providers/digitalocean.rb +98 -100
- data/lib/chef/provisioning/fog_driver/providers/google.rb +27 -34
- data/lib/chef/provisioning/fog_driver/providers/joyent.rb +53 -55
- data/lib/chef/provisioning/fog_driver/providers/openstack.rb +139 -146
- data/lib/chef/provisioning/fog_driver/providers/rackspace.rb +40 -44
- data/lib/chef/provisioning/fog_driver/providers/scaleway.rb +183 -189
- data/lib/chef/provisioning/fog_driver/providers/softlayer.rb +61 -64
- data/lib/chef/provisioning/fog_driver/providers/vcair.rb +72 -78
- data/lib/chef/provisioning/fog_driver/providers/xenserver.rb +56 -69
- data/lib/chef/provisioning/fog_driver/recipe_dsl.rb +11 -12
- data/lib/chef/provisioning/fog_driver/version.rb +1 -1
- data/lib/chef/resource/fog_key_pair.rb +8 -8
- data/lib/chef/resource/scaleway_volume.rb +8 -8
- data/spec/spec_helper.rb +7 -7
- data/spec/support/chef/provisioning/fog_driver/providers/testdriver.rb +3 -3
- data/spec/unit/chef/provisioning/fog_driver/driver_spec.rb +39 -38
- data/spec/unit/fog_driver_spec.rb +6 -8
- data/spec/unit/providers/aws/credentials_spec.rb +10 -10
- data/spec/unit/providers/rackspace_spec.rb +5 -6
- data/spec/unit/providers/scaleway_spec.rb +9 -9
- data/spec/unit/providers/softlayer.rb +7 -7
- metadata +6 -36
- data/README.md +0 -357
@@ -1,50 +1,46 @@
|
|
1
1
|
# fog:Rackspace:https://identity.api.rackspacecloud.com/v2.0
|
2
2
|
class Chef
|
3
|
-
module Provisioning
|
4
|
-
module FogDriver
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
[result, id]
|
3
|
+
module Provisioning
|
4
|
+
module FogDriver
|
5
|
+
module Providers
|
6
|
+
class Rackspace < FogDriver::Driver
|
7
|
+
Driver.register_provider_class("Rackspace", FogDriver::Providers::Rackspace)
|
8
|
+
|
9
|
+
def creator
|
10
|
+
compute_options[:rackspace_username]
|
11
|
+
end
|
12
|
+
|
13
|
+
def convergence_strategy_for(machine_spec, machine_options)
|
14
|
+
machine_options = Cheffish::MergedConfig.new(machine_options,
|
15
|
+
convergence_options: { ohai_hints: { "rackspace" => {} } })
|
16
|
+
super(machine_spec, machine_options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.compute_options_for(provider, id, config)
|
20
|
+
new_compute_options = {}
|
21
|
+
new_compute_options[:provider] = provider
|
22
|
+
new_config = { driver_options: { compute_options: new_compute_options } }
|
23
|
+
new_defaults = {
|
24
|
+
driver_options: { compute_options: {} },
|
25
|
+
machine_options: { bootstrap_options: {} }
|
26
|
+
}
|
27
|
+
result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
|
28
|
+
|
29
|
+
new_compute_options[:rackspace_auth_url] = id if id && id != ""
|
30
|
+
credential = Fog.credentials
|
31
|
+
|
32
|
+
new_compute_options[:rackspace_username] ||= credential[:rackspace_username]
|
33
|
+
new_compute_options[:rackspace_api_key] ||= credential[:rackspace_api_key]
|
34
|
+
new_compute_options[:rackspace_auth_url] ||= credential[:rackspace_auth_url]
|
35
|
+
new_compute_options[:rackspace_region] ||= credential[:rackspace_region]
|
36
|
+
new_compute_options[:rackspace_endpoint] ||= credential[:rackspace_endpoint]
|
37
|
+
|
38
|
+
id = result[:driver_options][:compute_options][:rackspace_auth_url]
|
39
|
+
|
40
|
+
[result, id]
|
41
|
+
end
|
42
|
+
end
|
44
43
|
end
|
45
|
-
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# fog:OpenStack:https://identifyhost:portNumber/v2.0
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "fog/scaleway"
|
4
|
+
require "fog/scaleway/models/compute/server"
|
5
5
|
|
6
6
|
#
|
7
7
|
# We're monkeypatching here to avoid overriding too much of the base
|
@@ -9,8 +9,8 @@ require 'fog/scaleway/models/compute/server'
|
|
9
9
|
# upstream
|
10
10
|
#
|
11
11
|
class Fog::Scaleway::Compute::Server
|
12
|
-
alias
|
13
|
-
alias
|
12
|
+
alias start poweron
|
13
|
+
alias stop poweroff
|
14
14
|
|
15
15
|
def disassociate_address(ip)
|
16
16
|
ip = ip.address if ip.respond_to? :address
|
@@ -23,226 +23,220 @@ class Fog::Scaleway::Compute::Server
|
|
23
23
|
end
|
24
24
|
|
25
25
|
class Chef
|
26
|
-
module Provisioning
|
27
|
-
module FogDriver
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
module Provisioning
|
27
|
+
module FogDriver
|
28
|
+
module Providers
|
29
|
+
class Scaleway < FogDriver::Driver
|
30
|
+
Driver.register_provider_class("Scaleway", FogDriver::Providers::Scaleway)
|
31
|
+
|
32
|
+
def creator
|
33
|
+
compute_options[:scaleway_organization]
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
36
|
+
def convergence_strategy_for(machine_spec, machine_options)
|
37
|
+
machine_options = Cheffish::MergedConfig.new(machine_options,
|
38
|
+
convergence_options: { ohai_hints: { "scaleway" => {} } })
|
39
|
+
super(machine_spec, machine_options)
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
42
|
+
def bootstrap_options_for(action_handler, machine_spec, machine_options)
|
43
|
+
opts = super
|
44
|
+
opts[:tags] = opts[:tags].map { |key, value| [key, value].join("=") }
|
45
|
+
|
46
|
+
# Let's fetch the id of the volumes if the user didn't provide it
|
47
|
+
# Which probably means they were created in chef
|
48
|
+
if opts[:volumes]
|
49
|
+
managed_entry_store = machine_spec.managed_entry_store
|
50
|
+
volumes = Marshal.load(Marshal.dump(opts[:volumes]))
|
51
|
+
|
52
|
+
volumes.each do |_index, volume|
|
53
|
+
next if volume[:id]
|
54
|
+
volume_spec = managed_entry_store.get(:volume, volume[:name])
|
55
|
+
unless volume_spec
|
56
|
+
raise "Volume #{volume[:name]} unknown, create it or provide its id"
|
57
|
+
end
|
58
|
+
volume[:id] = volume_spec.reference["id"]
|
58
59
|
end
|
59
|
-
|
60
|
+
opts[:volumes] = volumes
|
60
61
|
end
|
62
|
+
opts
|
61
63
|
end
|
62
|
-
opts[:volumes] = volumes
|
63
|
-
end
|
64
|
-
opts
|
65
|
-
end
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
65
|
+
def destroy_machine(action_handler, machine_spec, machine_options)
|
66
|
+
server = server_for(machine_spec)
|
67
|
+
if server
|
68
|
+
action_handler.perform_action "destroy machine #{machine_spec.name} (#{machine_spec.reference['server_id']} at #{driver_url})" do
|
69
|
+
# Scaleway's API fail if we try to stop/terminate an instance with
|
70
|
+
# certains states
|
71
|
+
if server.state == "running"
|
72
|
+
server.stop
|
73
|
+
server.wait_for { server.state != "running" }
|
74
|
+
end
|
75
|
+
%w{stopping starting}.each do |state|
|
76
|
+
server.wait_for { server.state != state } if server.state == state
|
77
|
+
end
|
78
|
+
|
79
|
+
if server.state == "stopped"
|
80
|
+
server.destroy
|
81
|
+
else
|
82
|
+
Chef.log.fatal "Server is in an unknown state (#{server.state})"
|
83
|
+
end
|
84
|
+
machine_spec.reference = nil
|
85
|
+
end
|
86
86
|
end
|
87
|
-
|
87
|
+
strategy = ConvergenceStrategy::NoConverge.new(machine_options[:convergence_options], config)
|
88
|
+
strategy.cleanup_convergence(action_handler, machine_spec)
|
88
89
|
end
|
89
|
-
end
|
90
|
-
strategy = ConvergenceStrategy::NoConverge.new(machine_options[:convergence_options], config)
|
91
|
-
strategy.cleanup_convergence(action_handler, machine_spec)
|
92
|
-
end
|
93
90
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
91
|
+
def stop_machine(action_handler, machine_spec, _machine_options)
|
92
|
+
server = server_for(machine_spec)
|
93
|
+
if server && (server.state == "running")
|
94
|
+
action_handler.perform_action "stop machine #{machine_spec.name} (#{server.id} at #{driver_url})" do
|
95
|
+
server.poweroff(true)
|
96
|
+
server.wait_for { server.state == "stopped" }
|
97
|
+
end
|
98
|
+
end
|
100
99
|
end
|
101
|
-
end
|
102
|
-
end
|
103
100
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
new_default_compute_options = {}
|
115
|
-
new_defaults = {
|
116
|
-
:driver_options => { :compute_options => new_default_compute_options },
|
117
|
-
:machine_options => { :bootstrap_options => {} }
|
118
|
-
}
|
119
|
-
|
120
|
-
result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
|
101
|
+
def self.compute_options_for(provider, id, config)
|
102
|
+
new_compute_options = {}
|
103
|
+
new_compute_options[:provider] = provider
|
104
|
+
if id && id != ""
|
105
|
+
org, region = id.split(":")
|
106
|
+
new_compute_options[:scaleway_organization] = org
|
107
|
+
new_compute_options[:scaleway_region] = region || "par1"
|
108
|
+
end
|
109
|
+
new_config = { driver_options: { compute_options: new_compute_options } }
|
121
110
|
|
122
|
-
|
123
|
-
|
124
|
-
|
111
|
+
new_default_compute_options = {}
|
112
|
+
new_defaults = {
|
113
|
+
driver_options: { compute_options: new_default_compute_options },
|
114
|
+
machine_options: { bootstrap_options: {} }
|
115
|
+
}
|
125
116
|
|
126
|
-
|
127
|
-
result[:driver_options][:compute_options][:scaleway_region]].join(':')
|
117
|
+
result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
|
128
118
|
|
129
|
-
|
130
|
-
|
119
|
+
credential = Fog.credentials
|
120
|
+
new_default_compute_options[:scaleway_organization] ||= credential[:scaleway_organization]
|
121
|
+
new_default_compute_options[:scaleway_token] ||= credential[:scaleway_token]
|
131
122
|
|
132
|
-
|
133
|
-
|
134
|
-
Chef::Log.info "Dynamic IP allocation has been enabled, not converging IPs"
|
135
|
-
else
|
136
|
-
super
|
137
|
-
end
|
138
|
-
end
|
123
|
+
id = [result[:driver_options][:compute_options][:scaleway_organization],
|
124
|
+
result[:driver_options][:compute_options][:scaleway_region]].join(":")
|
139
125
|
|
140
|
-
|
141
|
-
|
142
|
-
return server if server.public_ip
|
143
|
-
|
144
|
-
Chef::Log.info "Scaleway has only one IP pool, ignoring pool argument"
|
145
|
-
ip = server.service.ips.all.select { |ip| ip.address.nil? }.first
|
146
|
-
if ip
|
147
|
-
ip.server = server
|
148
|
-
ip.save
|
149
|
-
server.reload
|
150
|
-
else
|
151
|
-
# Allocate a new IP
|
152
|
-
ip = server.service.ips.create
|
153
|
-
ip.server = server
|
154
|
-
ip.save
|
155
|
-
server.reload
|
156
|
-
end
|
157
|
-
end
|
126
|
+
[result, id]
|
127
|
+
end
|
158
128
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
end
|
129
|
+
def converge_floating_ips(action_handler, machine_spec, machine_options, server)
|
130
|
+
if server.dynamic_ip_required
|
131
|
+
Chef::Log.info "Dynamic IP allocation has been enabled, not converging IPs"
|
132
|
+
else
|
133
|
+
super
|
134
|
+
end
|
135
|
+
end
|
167
136
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
old_ip.server = nil
|
172
|
-
old_ip.save
|
173
|
-
end
|
137
|
+
# Scaleway only has one global pool.
|
138
|
+
def attach_ip_from_pool(server, _pool)
|
139
|
+
return server if server.public_ip
|
174
140
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
141
|
+
Chef::Log.info "Scaleway has only one IP pool, ignoring pool argument"
|
142
|
+
ip = server.service.ips.all.select { |ip| ip.address.nil? }.first
|
143
|
+
if ip
|
144
|
+
ip.server = server
|
145
|
+
ip.save
|
146
|
+
server.reload
|
147
|
+
else
|
148
|
+
# Allocate a new IP
|
149
|
+
ip = server.service.ips.create
|
150
|
+
ip.server = server
|
151
|
+
ip.save
|
152
|
+
server.reload
|
153
|
+
end
|
154
|
+
end
|
179
155
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
-
public_ips
|
188
|
-
end
|
156
|
+
def attach_ip(server, floating_ip)
|
157
|
+
ip = server.service.ips.get(floating_ip)
|
158
|
+
raise "Requested IP (#{floating_ip}) not found" if ip.nil?
|
159
|
+
if ip.server && (ip.server.identity != server.identity)
|
160
|
+
raise "Requested IP (#{floating_ip}) already attached"
|
161
|
+
end
|
189
162
|
|
163
|
+
if server.public_ip
|
164
|
+
old_ip = server.public_ip
|
165
|
+
Chef::Log.info "Server #{server.identity} already has IP #{old_ip.address}, removing it"
|
166
|
+
old_ip.server = nil
|
167
|
+
old_ip.save
|
168
|
+
end
|
190
169
|
|
191
|
-
|
192
|
-
|
193
|
-
|
170
|
+
ip.server = server
|
171
|
+
ip.save
|
172
|
+
server.reload
|
173
|
+
end
|
194
174
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
175
|
+
# Get the public IP if any
|
176
|
+
def find_floating_ips(server, action_handler)
|
177
|
+
public_ips = []
|
178
|
+
Retryable.retryable(RETRYABLE_OPTIONS) do |retries, _exception|
|
179
|
+
action_handler.report_progress "Querying for public IP attached to server #{server.id}, API attempt #{retries + 1}/#{RETRYABLE_OPTIONS[:tries]} ..."
|
180
|
+
public_ips << server.public_ip.address if server.public_ip
|
181
|
+
end
|
182
|
+
public_ips
|
183
|
+
end
|
202
184
|
|
203
|
-
|
204
|
-
|
185
|
+
def create_volume(action_handler, volume_spec, volume_options)
|
186
|
+
# Prevent destructive operations on volume_options.
|
187
|
+
clean_volume_options = Marshal.load(Marshal.dump(volume_options))
|
205
188
|
|
206
|
-
|
207
|
-
|
208
|
-
|
189
|
+
volume_spec.reference ||= {}
|
190
|
+
volume_spec.reference.update(
|
191
|
+
"driver_url" => driver_url,
|
192
|
+
"driver_version" => FogDriver::VERSION,
|
193
|
+
"creator" => creator,
|
194
|
+
"allocated_at" => Time.now.to_i
|
195
|
+
)
|
209
196
|
|
210
|
-
|
197
|
+
description = ["Creating volume #{volume_spec.name}"]
|
198
|
+
volume_options.each { |k, v| description << " #{k}: #{v.inspect}" }
|
211
199
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
'size' => volume.size
|
216
|
-
)
|
217
|
-
volume_spec.save(action_handler)
|
218
|
-
action_handler.performed_action "volume #{volume_spec.name} created as #{volume.id} on #{driver_url}"
|
219
|
-
end
|
220
|
-
end
|
200
|
+
action_handler.report_progress description
|
201
|
+
if action_handler.should_perform_actions
|
202
|
+
clean_volume_options["name"] = volume_spec.name
|
221
203
|
|
222
|
-
|
223
|
-
volume = volume_for(volume_spec)
|
204
|
+
volume = compute.volumes.create(clean_volume_options)
|
224
205
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
volume_spec.reference = nil
|
206
|
+
volume_spec.reference.update(
|
207
|
+
"id" => volume.id,
|
208
|
+
"volume_type" => volume.volume_type,
|
209
|
+
"size" => volume.size
|
210
|
+
)
|
231
211
|
volume_spec.save(action_handler)
|
212
|
+
action_handler.performed_action "volume #{volume_spec.name} created as #{volume.id} on #{driver_url}"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def destroy_volume(action_handler, volume_spec, _volume_options)
|
217
|
+
volume = volume_for(volume_spec)
|
218
|
+
|
219
|
+
if volume && action_handler.should_perform_actions
|
220
|
+
begin
|
221
|
+
msg = "destroyed volume #{volume_spec.name} at #{driver_url}"
|
222
|
+
action_handler.perform_action msg do
|
223
|
+
volume.destroy
|
224
|
+
volume_spec.reference = nil
|
225
|
+
volume_spec.save(action_handler)
|
226
|
+
end
|
227
|
+
rescue Fog::Scaleway::Compute::InvalidRequestError => e
|
228
|
+
Chef::Log.error "Unable to destroy volume #{volume_spec.name} : #{e.message}"
|
229
|
+
end
|
232
230
|
end
|
233
|
-
rescue Fog::Scaleway::Compute::InvalidRequestError => e
|
234
|
-
Chef::Log.error "Unable to destroy volume #{volume_spec.name} : #{e.message}"
|
235
231
|
end
|
236
|
-
end
|
237
|
-
end
|
238
232
|
|
239
|
-
|
240
|
-
|
241
|
-
|
233
|
+
def volume_for(volume_spec)
|
234
|
+
if volume_spec.reference
|
235
|
+
compute.volumes.get(volume_spec.reference["id"])
|
236
|
+
end
|
237
|
+
end
|
242
238
|
end
|
243
239
|
end
|
244
240
|
end
|
245
241
|
end
|
246
242
|
end
|
247
|
-
end
|
248
|
-
end
|