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.
- checksums.yaml +4 -4
- data/LICENSE +201 -201
- data/README.md +3 -3
- data/Rakefile +6 -6
- 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 -709
- 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 -84
- data/lib/chef/provisioning/fog_driver/providers/joyent.rb +63 -59
- data/lib/chef/provisioning/fog_driver/providers/openstack.rb +117 -41
- 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 -376
- data/lib/chef/provisioning/fog_driver/providers/xenserver.rb +210 -0
- 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 -0
- 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
@@ -0,0 +1,210 @@
|
|
1
|
+
#fog:XenServer:<XenServer IP>
|
2
|
+
class Chef
|
3
|
+
module Provisioning
|
4
|
+
module FogDriver
|
5
|
+
module Providers
|
6
|
+
class XenServer < FogDriver::Driver
|
7
|
+
|
8
|
+
Driver.register_provider_class('XenServer', FogDriver::Providers::XenServer)
|
9
|
+
|
10
|
+
def creator
|
11
|
+
compute_options[:xenserver_username]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.compute_options_for(provider, id, config)
|
15
|
+
new_compute_options = {}
|
16
|
+
new_compute_options[:provider] = provider
|
17
|
+
new_config = { driver_options: { compute_options: new_compute_options } }
|
18
|
+
new_defaults = {
|
19
|
+
driver_options: { compute_options: {} },
|
20
|
+
machine_options: { bootstrap_options: { affinity: id } }
|
21
|
+
}
|
22
|
+
result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
|
23
|
+
|
24
|
+
new_compute_options[:xenserver_url] = id if id && id != ''
|
25
|
+
credential = Fog.credentials
|
26
|
+
|
27
|
+
new_compute_options[:xenserver_username] ||= credential[:xenserver_username]
|
28
|
+
new_compute_options[:xenserver_password] ||= credential[:xenserver_password]
|
29
|
+
new_compute_options[:xenserver_url] ||= credential[:xenserver_url]
|
30
|
+
new_compute_options[:xenserver_timeout] ||= 300
|
31
|
+
new_compute_options[:xenserver_redirect_to_master] ||= true
|
32
|
+
|
33
|
+
id = result[:driver_options][:compute_options][:xenserver_url]
|
34
|
+
|
35
|
+
[result, id]
|
36
|
+
end
|
37
|
+
|
38
|
+
def server_for(machine_spec)
|
39
|
+
if machine_spec.reference
|
40
|
+
compute.servers.get(compute.get_by_uuid(machine_spec.reference['server_id'], 'VM'))
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def servers_for(machine_specs)
|
47
|
+
result = {}
|
48
|
+
machine_specs.each do |machine_spec|
|
49
|
+
if machine_spec.reference
|
50
|
+
if machine_spec.reference['driver_url'] != driver_url
|
51
|
+
raise "Switching a machine's driver from #{machine_spec.reference['driver_url']} to #{driver_url} for is not currently supported! Use machine :destroy and then re-create the machine on the new driver."
|
52
|
+
end
|
53
|
+
result[machine_spec] = compute.servers.get(compute.get_by_uuid(machine_spec.reference['server_id'], 'VM'))
|
54
|
+
else
|
55
|
+
result[machine_spec] = nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_many_servers(num_servers, bootstrap_options, parallelizer)
|
62
|
+
parallelizer.parallelize(1.upto(num_servers)) do |i|
|
63
|
+
server = compute.servers.new(bootstrap_options)
|
64
|
+
server.save auto_start: false
|
65
|
+
|
66
|
+
if bootstrap_options[:affinity]
|
67
|
+
host = compute.hosts.all.select { |h| h.address == bootstrap_options[:affinity] }.first
|
68
|
+
if !host
|
69
|
+
raise "Host with ID #{bootstrap_options[:affinity]} not found."
|
70
|
+
end
|
71
|
+
server.set_attribute 'affinity', host.reference
|
72
|
+
end
|
73
|
+
|
74
|
+
unless bootstrap_options[:memory].nil?
|
75
|
+
mem = (bootstrap_options[:memory].to_i * 1024 * 1024).to_s
|
76
|
+
server.set_attribute 'memory_limits', mem, mem, mem, mem
|
77
|
+
end
|
78
|
+
|
79
|
+
unless bootstrap_options[:cpus].nil?
|
80
|
+
cpus = (bootstrap_options[:cpus]).to_s
|
81
|
+
server.set_attribute 'VCPUs_max', cpus
|
82
|
+
server.set_attribute 'VCPUs_at_startup', cpus
|
83
|
+
end
|
84
|
+
|
85
|
+
# network configuration through xenstore
|
86
|
+
attrs = {}
|
87
|
+
unless bootstrap_options[:network].nil?
|
88
|
+
network = bootstrap_options[:network]
|
89
|
+
attrs['vm-data/ip'] = network[:vm_ip] if network[:vm_ip]
|
90
|
+
attrs['vm-data/gw'] = network[:vm_gateway] if network[:vm_gateway]
|
91
|
+
attrs['vm-data/nm'] = network[:vm_netmask] if network[:vm_netmask]
|
92
|
+
attrs['vm-data/ns'] = network[:vm_dns] if network[:vm_dns]
|
93
|
+
attrs['vm-data/dm'] = network[:vm_domain] if network[:vm_domain]
|
94
|
+
if !attrs.empty?
|
95
|
+
server.set_attribute 'xenstore_data', attrs
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
server.provision
|
100
|
+
yield server if block_given?
|
101
|
+
server
|
102
|
+
end.to_a
|
103
|
+
end
|
104
|
+
|
105
|
+
def start_server(action_handler, machine_spec, server)
|
106
|
+
if server.state == 'Halted'
|
107
|
+
action_handler.perform_action "start machine #{machine_spec.name} (#{server.id} on #{driver_url})" do
|
108
|
+
server.start
|
109
|
+
machine_spec.reference['started_at'] = Time.now.to_i
|
110
|
+
end
|
111
|
+
machine_spec.save(action_handler)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def converge_floating_ips(action_handler, machine_spec, machine_options, server)
|
116
|
+
# XenServer does not have floating IPs
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
# Add methods required by the fog driver to XenServer's Server class
|
126
|
+
require 'fog/compute/models/server'
|
127
|
+
module Fog
|
128
|
+
module Compute
|
129
|
+
class XenServer
|
130
|
+
class Server < Fog::Compute::Server
|
131
|
+
def id
|
132
|
+
uuid
|
133
|
+
end
|
134
|
+
|
135
|
+
def state
|
136
|
+
attributes[:power_state]
|
137
|
+
end
|
138
|
+
|
139
|
+
def public_ip_address
|
140
|
+
if xenstore_data['vm-data/ip']
|
141
|
+
xenstore_data['vm-data/ip']
|
142
|
+
else
|
143
|
+
wait_for { tools_installed? }
|
144
|
+
if tools_installed?
|
145
|
+
guest_metrics.networks.first[1]
|
146
|
+
else
|
147
|
+
fail 'Unable to return IP address. Virtual machine does not ' \
|
148
|
+
'have XenTools installed or a timeout occurred.'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def ready?
|
154
|
+
running?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Use call_async instead of call on XMLPRPC::Client
|
163
|
+
# Otherwise machine_batch will fail since parallel calls will clash.
|
164
|
+
#
|
165
|
+
# See http://ruby-doc.org//stdlib-2.1.1//libdoc/xmlrpc/rdoc/XMLRPC/Client.html
|
166
|
+
#
|
167
|
+
module Fog
|
168
|
+
module XenServer
|
169
|
+
class Connection
|
170
|
+
require 'xmlrpc/client'
|
171
|
+
attr_reader :credentials
|
172
|
+
|
173
|
+
def request(options, *params)
|
174
|
+
begin
|
175
|
+
parser = options.delete(:parser)
|
176
|
+
method = options.delete(:method)
|
177
|
+
|
178
|
+
if params.empty?
|
179
|
+
response = @factory.call_async(method, @credentials)
|
180
|
+
else
|
181
|
+
if params.length.eql?(1) and params.first.is_a?(Hash)
|
182
|
+
response = @factory.call_async(method, @credentials, params.first)
|
183
|
+
elsif params.length.eql?(2) and params.last.is_a?(Array)
|
184
|
+
response = @factory.call_async(method, @credentials, params.first, params.last)
|
185
|
+
else
|
186
|
+
response = eval("@factory.call_async('#{method}', '#{@credentials}', #{params.map { |p| p.is_a?(String) ? "'#{p}'" : p }.join(',')})")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
raise RequestFailed.new("#{method}: " + response["ErrorDescription"].to_s) unless response["Status"].eql? "Success"
|
190
|
+
if parser
|
191
|
+
parser.parse(response["Value"])
|
192
|
+
response = parser.response
|
193
|
+
end
|
194
|
+
|
195
|
+
response
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
module Fog
|
204
|
+
class Logger
|
205
|
+
def self.deprecation(message)
|
206
|
+
# Silence...ahh
|
207
|
+
Chef::Log.debug('Fog: ' + message)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -1,32 +1,32 @@
|
|
1
|
-
require 'chef/provisioning/fog_driver/driver'
|
2
|
-
require 'chef/resource/fog_key_pair'
|
3
|
-
require 'chef/provider/fog_key_pair'
|
4
|
-
|
5
|
-
class Chef
|
6
|
-
module DSL
|
7
|
-
module Recipe
|
8
|
-
def with_fog_driver(provider, driver_options = nil, &block)
|
9
|
-
config = Cheffish::MergedConfig.new({ :driver_options => driver_options }, run_context.config)
|
10
|
-
driver = Driver.from_provider(provider, config)
|
11
|
-
run_context.chef_provisioning.with_driver(driver, &block)
|
12
|
-
end
|
13
|
-
|
14
|
-
def with_fog_ec2_driver(driver_options = nil, &block)
|
15
|
-
with_fog_driver('AWS', driver_options, &block)
|
16
|
-
end
|
17
|
-
|
18
|
-
def with_fog_openstack_driver(driver_options = nil, &block)
|
19
|
-
with_fog_driver('OpenStack', driver_options, &block)
|
20
|
-
end
|
21
|
-
|
22
|
-
def with_fog_rackspace_driver(driver_options = nil, &block)
|
23
|
-
with_fog_driver('Rackspace', driver_options, &block)
|
24
|
-
end
|
25
|
-
|
26
|
-
def with_fog_vcair_driver(driver_options = nil, &block)
|
27
|
-
with_fog_driver('Vcair', driver_options, &block)
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
1
|
+
require 'chef/provisioning/fog_driver/driver'
|
2
|
+
require 'chef/resource/fog_key_pair'
|
3
|
+
require 'chef/provider/fog_key_pair'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
module DSL
|
7
|
+
module Recipe
|
8
|
+
def with_fog_driver(provider, driver_options = nil, &block)
|
9
|
+
config = Cheffish::MergedConfig.new({ :driver_options => driver_options }, run_context.config)
|
10
|
+
driver = Driver.from_provider(provider, config)
|
11
|
+
run_context.chef_provisioning.with_driver(driver, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_fog_ec2_driver(driver_options = nil, &block)
|
15
|
+
with_fog_driver('AWS', driver_options, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_fog_openstack_driver(driver_options = nil, &block)
|
19
|
+
with_fog_driver('OpenStack', driver_options, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_fog_rackspace_driver(driver_options = nil, &block)
|
23
|
+
with_fog_driver('Rackspace', driver_options, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def with_fog_vcair_driver(driver_options = nil, &block)
|
27
|
+
with_fog_driver('Vcair', driver_options, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
class Chef
|
2
|
-
module Provisioning
|
3
|
-
module FogDriver
|
4
|
-
VERSION = '0.
|
5
|
-
end
|
6
|
-
end
|
7
|
-
end
|
1
|
+
class Chef
|
2
|
+
module Provisioning
|
3
|
+
module FogDriver
|
4
|
+
VERSION = '0.15.0'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
@@ -1,34 +1,34 @@
|
|
1
|
-
require 'chef/provisioning'
|
2
|
-
|
3
|
-
class Chef::Resource::FogKeyPair < Chef::Resource::LWRPBase
|
4
|
-
self.resource_name = 'fog_key_pair'
|
5
|
-
|
6
|
-
def initialize(*args)
|
7
|
-
super
|
8
|
-
@driver = run_context.chef_provisioning.current_driver
|
9
|
-
end
|
10
|
-
|
11
|
-
actions :create, :delete, :nothing
|
12
|
-
default_action :create
|
13
|
-
|
14
|
-
attribute :driver
|
15
|
-
# Private key to use as input (will be generated if it does not exist)
|
16
|
-
attribute :private_key_path, :kind_of => String
|
17
|
-
# Public key to use as input (will be generated if it does not exist)
|
18
|
-
attribute :public_key_path, :kind_of => String
|
19
|
-
# List of parameters to the private_key resource used for generation of the key
|
20
|
-
attribute :private_key_options, :kind_of => Hash
|
21
|
-
|
22
|
-
# TODO what is the right default for this?
|
23
|
-
attribute :allow_overwrite, :kind_of => [TrueClass, FalseClass], :default => false
|
24
|
-
|
25
|
-
# Proc that runs after the resource completes. Called with (resource, private_key, public_key)
|
26
|
-
def after(&block)
|
27
|
-
block ? @after = block : @after
|
28
|
-
end
|
29
|
-
|
30
|
-
# We are not interested in Chef's cloning behavior here.
|
31
|
-
def load_prior_resource(*args)
|
32
|
-
Chef::Log.debug("Overloading #{resource_name}.load_prior_resource with NOOP")
|
33
|
-
end
|
34
|
-
end
|
1
|
+
require 'chef/provisioning'
|
2
|
+
|
3
|
+
class Chef::Resource::FogKeyPair < Chef::Resource::LWRPBase
|
4
|
+
self.resource_name = 'fog_key_pair'
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
super
|
8
|
+
@driver = run_context.chef_provisioning.current_driver
|
9
|
+
end
|
10
|
+
|
11
|
+
actions :create, :delete, :nothing
|
12
|
+
default_action :create
|
13
|
+
|
14
|
+
attribute :driver
|
15
|
+
# Private key to use as input (will be generated if it does not exist)
|
16
|
+
attribute :private_key_path, :kind_of => String
|
17
|
+
# Public key to use as input (will be generated if it does not exist)
|
18
|
+
attribute :public_key_path, :kind_of => String
|
19
|
+
# List of parameters to the private_key resource used for generation of the key
|
20
|
+
attribute :private_key_options, :kind_of => Hash
|
21
|
+
|
22
|
+
# TODO what is the right default for this?
|
23
|
+
attribute :allow_overwrite, :kind_of => [TrueClass, FalseClass], :default => false
|
24
|
+
|
25
|
+
# Proc that runs after the resource completes. Called with (resource, private_key, public_key)
|
26
|
+
def after(&block)
|
27
|
+
block ? @after = block : @after
|
28
|
+
end
|
29
|
+
|
30
|
+
# We are not interested in Chef's cloning behavior here.
|
31
|
+
def load_prior_resource(*args)
|
32
|
+
Chef::Log.debug("Overloading #{resource_name}.load_prior_resource with NOOP")
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
$:.unshift File.expand_path('../support', __FILE__)
|
3
|
-
require 'fog'
|
4
|
-
require 'chef/provisioning'
|
5
|
-
require 'chef/provisioning/fog_driver'
|
6
|
-
|
7
|
-
RSpec.configure do |config|
|
8
|
-
config.run_all_when_everything_filtered = true
|
9
|
-
config.filter_run :focus
|
10
|
-
|
11
|
-
# Run specs in random order to surface order dependencies. If you find an
|
12
|
-
# order dependency and want to debug it, you can fix the order by providing
|
13
|
-
# the seed, which is printed after each run.
|
14
|
-
# --seed 1234
|
15
|
-
config.order = 'random'
|
16
|
-
end
|
17
|
-
|
18
|
-
Fog.mock!
|
1
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
$:.unshift File.expand_path('../support', __FILE__)
|
3
|
+
require 'fog'
|
4
|
+
require 'chef/provisioning'
|
5
|
+
require 'chef/provisioning/fog_driver'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.run_all_when_everything_filtered = true
|
9
|
+
config.filter_run :focus
|
10
|
+
|
11
|
+
# Run specs in random order to surface order dependencies. If you find an
|
12
|
+
# order dependency and want to debug it, you can fix the order by providing
|
13
|
+
# the seed, which is printed after each run.
|
14
|
+
# --seed 1234
|
15
|
+
config.order = 'random'
|
16
|
+
end
|
17
|
+
|
18
|
+
Fog.mock!
|
@@ -1,2 +1,2 @@
|
|
1
|
-
User Name,Access Key Id,Secret Access Key
|
2
|
-
test,12345,abcde
|
1
|
+
User Name,Access Key Id,Secret Access Key
|
2
|
+
test,12345,abcde
|
@@ -1,10 +1,10 @@
|
|
1
|
-
[default]
|
2
|
-
aws_access_key_id = 12345
|
3
|
-
aws_secret_access_key = abcde
|
4
|
-
aws_session_token = mysecret
|
5
|
-
region = us-east-1
|
6
|
-
|
7
|
-
[profile test]
|
8
|
-
aws_access_key_id = foobar
|
9
|
-
aws_secret_access_key = canteloupe
|
10
|
-
region = us-east-1
|
1
|
+
[default]
|
2
|
+
aws_access_key_id = 12345
|
3
|
+
aws_secret_access_key = abcde
|
4
|
+
aws_session_token = mysecret
|
5
|
+
region = us-east-1
|
6
|
+
|
7
|
+
[profile test]
|
8
|
+
aws_access_key_id = foobar
|
9
|
+
aws_secret_access_key = canteloupe
|
10
|
+
region = us-east-1
|
@@ -1,16 +1,16 @@
|
|
1
|
-
class Chef
|
2
|
-
module Provisioning
|
3
|
-
class FogDriver::Providers
|
4
|
-
class TestDriver < Chef::Provisioning::FogDriver
|
5
|
-
Chef::Provisioning::FogDriver.register_provider_class('TestDriver', Chef::Provisioning::FogDriver::Providers::TestDriver)
|
6
|
-
|
7
|
-
attr_reader :config
|
8
|
-
def initialize(driver_url, config)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.compute_options_for(provider, id, config)
|
13
|
-
[config, 'test']
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
1
|
+
class Chef
|
2
|
+
module Provisioning
|
3
|
+
class FogDriver::Providers
|
4
|
+
class TestDriver < Chef::Provisioning::FogDriver
|
5
|
+
Chef::Provisioning::FogDriver.register_provider_class('TestDriver', Chef::Provisioning::FogDriver::Providers::TestDriver)
|
6
|
+
|
7
|
+
attr_reader :config
|
8
|
+
def initialize(driver_url, config)
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.compute_options_for(provider, id, config)
|
13
|
+
[config, 'test']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|