chef-provisioning 0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +207 -0
- data/LICENSE +201 -0
- data/README.md +260 -0
- data/Rakefile +6 -0
- data/lib/chef/provider/load_balancer.rb +77 -0
- data/lib/chef/provider/machine.rb +176 -0
- data/lib/chef/provider/machine_batch.rb +191 -0
- data/lib/chef/provider/machine_execute.rb +35 -0
- data/lib/chef/provider/machine_file.rb +54 -0
- data/lib/chef/provider/machine_image.rb +60 -0
- data/lib/chef/provisioning.rb +95 -0
- data/lib/chef/provisioning/action_handler.rb +68 -0
- data/lib/chef/provisioning/add_prefix_action_handler.rb +31 -0
- data/lib/chef/provisioning/chef_image_spec.rb +108 -0
- data/lib/chef/provisioning/chef_load_balancer_spec.rb +108 -0
- data/lib/chef/provisioning/chef_machine_spec.rb +84 -0
- data/lib/chef/provisioning/chef_provider_action_handler.rb +74 -0
- data/lib/chef/provisioning/chef_run_data.rb +139 -0
- data/lib/chef/provisioning/convergence_strategy.rb +28 -0
- data/lib/chef/provisioning/convergence_strategy/install_cached.rb +156 -0
- data/lib/chef/provisioning/convergence_strategy/install_msi.rb +58 -0
- data/lib/chef/provisioning/convergence_strategy/install_sh.rb +55 -0
- data/lib/chef/provisioning/convergence_strategy/no_converge.rb +39 -0
- data/lib/chef/provisioning/convergence_strategy/precreate_chef_objects.rb +183 -0
- data/lib/chef/provisioning/driver.rb +304 -0
- data/lib/chef/provisioning/image_spec.rb +72 -0
- data/lib/chef/provisioning/load_balancer_spec.rb +86 -0
- data/lib/chef/provisioning/machine.rb +112 -0
- data/lib/chef/provisioning/machine/basic_machine.rb +84 -0
- data/lib/chef/provisioning/machine/unix_machine.rb +278 -0
- data/lib/chef/provisioning/machine/windows_machine.rb +104 -0
- data/lib/chef/provisioning/machine_spec.rb +82 -0
- data/lib/chef/provisioning/recipe_dsl.rb +103 -0
- data/lib/chef/provisioning/transport.rb +95 -0
- data/lib/chef/provisioning/transport/ssh.rb +343 -0
- data/lib/chef/provisioning/transport/winrm.rb +151 -0
- data/lib/chef/provisioning/version.rb +5 -0
- data/lib/chef/resource/chef_data_bag_resource.rb +148 -0
- data/lib/chef/resource/load_balancer.rb +57 -0
- data/lib/chef/resource/machine.rb +124 -0
- data/lib/chef/resource/machine_batch.rb +78 -0
- data/lib/chef/resource/machine_execute.rb +28 -0
- data/lib/chef/resource/machine_file.rb +34 -0
- data/lib/chef/resource/machine_image.rb +35 -0
- data/lib/chef_metal.rb +1 -0
- metadata +217 -0
data/Rakefile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'chef/provider/chef_node'
|
3
|
+
require 'openssl'
|
4
|
+
require 'chef/provisioning/chef_provider_action_handler'
|
5
|
+
require 'chef/provisioning/chef_load_balancer_spec'
|
6
|
+
|
7
|
+
class Chef
|
8
|
+
class Provider
|
9
|
+
class LoadBalancer < Chef::Provider::LWRPBase
|
10
|
+
|
11
|
+
def action_handler
|
12
|
+
@action_handler ||= Chef::Provisioning::ChefProviderActionHandler.new(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def whyrun_supported?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def new_driver
|
20
|
+
@new_driver ||= run_context.chef_provisioning.driver_for(new_resource.driver)
|
21
|
+
end
|
22
|
+
|
23
|
+
action :create do
|
24
|
+
lb_spec = Chef::Provisioning::ChefLoadBalancerSpec.get(new_resource.name, new_resource.chef_server) ||
|
25
|
+
Chef::Provisioning::ChefLoadBalancerSpec.empty(new_resource.name, new_resource.chef_server)
|
26
|
+
|
27
|
+
if lb_spec.location
|
28
|
+
# Updating
|
29
|
+
update_loadbalancer(lb_spec)
|
30
|
+
else
|
31
|
+
lb_spec.load_balancer_options = new_resource.load_balancer_options
|
32
|
+
lb_spec.machines = new_resource.machines
|
33
|
+
create_loadbalancer(lb_spec)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
action :destroy do
|
38
|
+
lb_spec = Chef::Provisioning::ChefLoadBalancerSpec.get(new_resource.name, new_resource.chef_server)
|
39
|
+
new_driver.destroy_load_balancer(@action_handler, lb_spec, lb_options)
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :lb_spec
|
43
|
+
|
44
|
+
|
45
|
+
def update_loadbalancer(lb_spec)
|
46
|
+
machines = Hash[
|
47
|
+
*(new_resource.machines).collect {
|
48
|
+
|machine_name| [machine_name, get_machine_spec(machine_name)]
|
49
|
+
}.flatten
|
50
|
+
]
|
51
|
+
new_driver.update_load_balancer(action_handler, lb_spec, lb_options, {
|
52
|
+
:machines => machines
|
53
|
+
}
|
54
|
+
)
|
55
|
+
lb_spec.load_balancer_options = new_resource.load_balancer_options
|
56
|
+
lb_spec.machines = new_resource.machines
|
57
|
+
lb_spec.save(action_handler)
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_loadbalancer(lb_spec)
|
61
|
+
new_driver.allocate_load_balancer(action_handler, lb_spec, lb_options)
|
62
|
+
lb_spec.save(action_handler)
|
63
|
+
new_driver.ready_load_balancer(action_handler, lb_spec, lb_options)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def get_machine_spec(machine_name)
|
68
|
+
Chef::Provisioning::ChefMachineSpec.get(machine_name, new_resource.chef_server)
|
69
|
+
end
|
70
|
+
|
71
|
+
def lb_options
|
72
|
+
new_resource.load_balancer_options
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'chef/provider/lwrp_base'
|
2
|
+
require 'chef/provider/chef_node'
|
3
|
+
require 'openssl'
|
4
|
+
require 'chef/provisioning/chef_provider_action_handler'
|
5
|
+
require 'chef/provisioning/chef_machine_spec'
|
6
|
+
|
7
|
+
class Chef
|
8
|
+
class Provider
|
9
|
+
class Machine < Chef::Provider::LWRPBase
|
10
|
+
|
11
|
+
def action_handler
|
12
|
+
@action_handler ||= Chef::Provisioning::ChefProviderActionHandler.new(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
use_inline_resources
|
16
|
+
|
17
|
+
def whyrun_supported?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
action :allocate do
|
22
|
+
if current_driver && current_driver.driver_url != new_driver.driver_url
|
23
|
+
raise "Cannot move '#{machine_spec.name}' from #{current_driver.driver_url} to #{new_driver.driver_url}: machine moving is not supported. Destroy and recreate."
|
24
|
+
end
|
25
|
+
if !new_driver
|
26
|
+
raise "Driver not specified for machine #{machine_spec.name}"
|
27
|
+
end
|
28
|
+
new_driver.allocate_machine(action_handler, machine_spec, new_machine_options)
|
29
|
+
machine_spec.save(action_handler)
|
30
|
+
end
|
31
|
+
|
32
|
+
action :ready do
|
33
|
+
action_allocate
|
34
|
+
machine = current_driver.ready_machine(action_handler, machine_spec, current_machine_options)
|
35
|
+
machine_spec.save(action_handler)
|
36
|
+
machine
|
37
|
+
end
|
38
|
+
|
39
|
+
action :setup do
|
40
|
+
machine = action_ready
|
41
|
+
begin
|
42
|
+
machine.setup_convergence(action_handler)
|
43
|
+
machine_spec.save(action_handler)
|
44
|
+
upload_files(machine)
|
45
|
+
ensure
|
46
|
+
machine.disconnect
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
action :converge do
|
51
|
+
machine = action_ready
|
52
|
+
begin
|
53
|
+
machine.setup_convergence(action_handler)
|
54
|
+
machine_spec.save(action_handler)
|
55
|
+
upload_files(machine)
|
56
|
+
# If we were asked to converge, or anything changed, or if a converge has never succeeded, converge.
|
57
|
+
if new_resource.converge || (new_resource.converge.nil? && resource_updated?) ||
|
58
|
+
!machine_spec.node['automatic'] || machine_spec.node['automatic'].size == 0
|
59
|
+
machine.converge(action_handler)
|
60
|
+
end
|
61
|
+
ensure
|
62
|
+
machine.disconnect
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
action :converge_only do
|
67
|
+
machine = run_context.chef_provisioning.connect_to_machine(machine_spec, current_machine_options)
|
68
|
+
begin
|
69
|
+
machine.converge(action_handler)
|
70
|
+
ensure
|
71
|
+
machine.disconnect
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
action :stop do
|
76
|
+
if current_driver
|
77
|
+
current_driver.stop_machine(action_handler, machine_spec, current_machine_options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
action :destroy do
|
82
|
+
if current_driver
|
83
|
+
current_driver.destroy_machine(action_handler, machine_spec, current_machine_options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
attr_reader :machine_spec
|
88
|
+
|
89
|
+
def new_driver
|
90
|
+
run_context.chef_provisioning.driver_for(new_resource.driver)
|
91
|
+
end
|
92
|
+
|
93
|
+
def current_driver
|
94
|
+
if machine_spec.driver_url
|
95
|
+
run_context.chef_provisioning.driver_for(machine_spec.driver_url)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def from_image_spec
|
100
|
+
@from_image_spec ||= begin
|
101
|
+
if new_resource.from_image
|
102
|
+
Chef::Provisioning::ChefImageSpec.get(new_resource.from_image, new_resource.chef_server)
|
103
|
+
else
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def new_machine_options
|
110
|
+
machine_options(new_driver)
|
111
|
+
end
|
112
|
+
|
113
|
+
def current_machine_options
|
114
|
+
machine_options(current_driver)
|
115
|
+
end
|
116
|
+
|
117
|
+
def machine_options(driver)
|
118
|
+
configs = []
|
119
|
+
|
120
|
+
if from_image_spec && from_image_spec.machine_options
|
121
|
+
configs << from_image_spec.machine_options
|
122
|
+
end
|
123
|
+
|
124
|
+
configs << {
|
125
|
+
:convergence_options =>
|
126
|
+
[ :chef_server,
|
127
|
+
:allow_overwrite_keys,
|
128
|
+
:source_key, :source_key_path, :source_key_pass_phrase,
|
129
|
+
:private_key_options,
|
130
|
+
:ohai_hints,
|
131
|
+
:public_key_path, :public_key_format,
|
132
|
+
:admin, :validator
|
133
|
+
].inject({}) do |result, key|
|
134
|
+
result[key] = new_resource.send(key)
|
135
|
+
result
|
136
|
+
end
|
137
|
+
}
|
138
|
+
|
139
|
+
configs << new_resource.machine_options if new_resource.machine_options
|
140
|
+
configs << driver.config[:machine_options] if driver.config[:machine_options]
|
141
|
+
Cheffish::MergedConfig.new(*configs)
|
142
|
+
end
|
143
|
+
|
144
|
+
def load_current_resource
|
145
|
+
node_driver = Chef::Provider::ChefNode.new(new_resource, run_context)
|
146
|
+
node_driver.load_current_resource
|
147
|
+
json = node_driver.new_json
|
148
|
+
json['normal']['chef_provisioning'] = node_driver.current_json['normal']['chef_provisioning']
|
149
|
+
@machine_spec = Chef::Provisioning::ChefMachineSpec.new(json, new_resource.chef_server)
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.upload_files(action_handler, machine, files)
|
153
|
+
if files
|
154
|
+
files.each_pair do |remote_file, local|
|
155
|
+
if local.is_a?(Hash)
|
156
|
+
if local[:local_path]
|
157
|
+
machine.upload_file(action_handler, local[:local_path], remote_file)
|
158
|
+
else
|
159
|
+
machine.write_file(action_handler, remote_file, local[:content])
|
160
|
+
end
|
161
|
+
else
|
162
|
+
machine.upload_file(action_handler, local, remote_file)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
def upload_files(machine)
|
171
|
+
Machine.upload_files(action_handler, machine, new_resource.files)
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'chef/chef_fs/parallelizer'
|
2
|
+
require 'chef/provider/lwrp_base'
|
3
|
+
require 'chef/provider/machine'
|
4
|
+
require 'chef/provisioning/chef_provider_action_handler'
|
5
|
+
require 'chef/provisioning/add_prefix_action_handler'
|
6
|
+
require 'chef/provisioning/machine_spec'
|
7
|
+
require 'chef/provisioning/chef_machine_spec'
|
8
|
+
|
9
|
+
class Chef
|
10
|
+
class Provider
|
11
|
+
class MachineBatch < Chef::Provider::LWRPBase
|
12
|
+
|
13
|
+
def action_handler
|
14
|
+
@action_handler ||= Chef::Provisioning::ChefProviderActionHandler.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
use_inline_resources
|
18
|
+
|
19
|
+
def whyrun_supported?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def parallelizer
|
24
|
+
@parallelizer ||= Chef::ChefFS::Parallelizer.new(new_resource.max_simultaneous || 100)
|
25
|
+
end
|
26
|
+
|
27
|
+
action :allocate do
|
28
|
+
by_new_driver.each do |driver, specs_and_options|
|
29
|
+
driver.allocate_machines(action_handler, specs_and_options, parallelizer) do |machine_spec|
|
30
|
+
prefixed_handler = Chef::Provisioning::AddPrefixActionHandler.new(action_handler, "[#{machine_spec.name}] ")
|
31
|
+
machine_spec.save(prefixed_handler)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
action :ready do
|
37
|
+
with_ready_machines
|
38
|
+
end
|
39
|
+
|
40
|
+
action :setup do
|
41
|
+
with_ready_machines do |m|
|
42
|
+
prefixed_handler = Chef::Provisioning::AddPrefixActionHandler.new(action_handler, "[#{m[:spec].name}] ")
|
43
|
+
m[:machine].setup_convergence(prefixed_handler)
|
44
|
+
m[:spec].save(prefixed_handler)
|
45
|
+
Chef::Provider::Machine.upload_files(prefixed_handler, m[:machine], m[:files])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
action :converge do
|
50
|
+
with_ready_machines do |m|
|
51
|
+
prefixed_handler = Chef::Provisioning::AddPrefixActionHandler.new(action_handler, "[#{m[:spec].name}] ")
|
52
|
+
m[:machine].setup_convergence(prefixed_handler)
|
53
|
+
m[:spec].save(action_handler)
|
54
|
+
Chef::Provider::Machine.upload_files(prefixed_handler, m[:machine], m[:files])
|
55
|
+
# TODO only converge if machine was modified
|
56
|
+
m[:machine].converge(prefixed_handler)
|
57
|
+
m[:spec].save(prefixed_handler)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
action :converge_only do
|
62
|
+
parallel_do(@machines) do |m|
|
63
|
+
prefixed_handler = Chef::Provisioning::AddPrefixActionHandler.new(action_handler, "[#{m[:spec].name}] ")
|
64
|
+
machine = run_context.chef_provisioning.connect_to_machine(m[:spec])
|
65
|
+
machine.converge(prefixed_handler)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
action :destroy do
|
70
|
+
parallel_do(by_current_driver) do |driver, specs_and_options|
|
71
|
+
driver.destroy_machines(action_handler, specs_and_options, parallelizer)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
action :stop do
|
76
|
+
parallel_do(by_current_driver) do |driver, specs_and_options|
|
77
|
+
driver.stop_machines(action_handler, specs_and_options, parallelizer)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def with_ready_machines
|
82
|
+
action_allocate
|
83
|
+
by_id = @machines.inject({}) { |hash,m| hash[m[:spec].id] = m; hash }
|
84
|
+
parallel_do(by_new_driver) do |driver, specs_and_options|
|
85
|
+
driver.ready_machines(action_handler, specs_and_options, parallelizer) do |machine|
|
86
|
+
machine.machine_spec.save(action_handler)
|
87
|
+
|
88
|
+
m = by_id[machine.machine_spec.id]
|
89
|
+
|
90
|
+
m[:machine] = machine
|
91
|
+
begin
|
92
|
+
yield m if block_given?
|
93
|
+
ensure
|
94
|
+
machine.disconnect
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# TODO in many of these cases, the order of the results only matters because you
|
101
|
+
# want to match it up with the input. Make a parallelize method that doesn't
|
102
|
+
# care about order and spits back results as quickly as possible.
|
103
|
+
def parallel_do(enum, options = {}, &block)
|
104
|
+
parallelizer.parallelize(enum, options, &block).to_a
|
105
|
+
end
|
106
|
+
|
107
|
+
def by_new_driver
|
108
|
+
result = {}
|
109
|
+
drivers = {}
|
110
|
+
@machines.each do |m|
|
111
|
+
if m[:desired_driver]
|
112
|
+
drivers[m[:desired_driver]] ||= run_context.chef_provisioning.driver_for(m[:desired_driver])
|
113
|
+
driver = drivers[m[:desired_driver]]
|
114
|
+
# Check whether the current driver is same or different; we disallow
|
115
|
+
# moving a machine from one place to another.
|
116
|
+
if m[:spec].driver_url
|
117
|
+
drivers[m[:spec].driver_url] ||= run_context.chef_provisioning.driver_for(m[:spec].driver_url)
|
118
|
+
current_driver = drivers[m[:spec].driver_url]
|
119
|
+
if driver.driver_url != current_driver.driver_url
|
120
|
+
raise "Cannot move '#{m[:spec].name}' from #{current_driver.driver_url} to #{driver.driver_url}: machine moving is not supported. Destroy and recreate."
|
121
|
+
end
|
122
|
+
end
|
123
|
+
result[driver] ||= {}
|
124
|
+
result[driver][m[:spec]] = m[:machine_options].call(driver)
|
125
|
+
else
|
126
|
+
raise "No driver specified for #{m[:spec].name}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
result
|
130
|
+
end
|
131
|
+
|
132
|
+
def by_current_driver
|
133
|
+
result = {}
|
134
|
+
drivers = {}
|
135
|
+
@machines.each do |m|
|
136
|
+
if m[:spec].driver_url
|
137
|
+
drivers[m[:spec].driver_url] ||= run_context.chef_provisioning.driver_for(m[:spec].driver_url)
|
138
|
+
driver = drivers[m[:spec].driver_url]
|
139
|
+
result[driver] ||= {}
|
140
|
+
result[driver][m[:spec]] = m[:machine_options].call(driver)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
result
|
144
|
+
end
|
145
|
+
|
146
|
+
def load_current_resource
|
147
|
+
# Load nodes in parallel
|
148
|
+
@machines = parallel_do(new_resource.machines) do |machine|
|
149
|
+
if machine.is_a?(Chef::Resource::Machine)
|
150
|
+
machine_resource = machine
|
151
|
+
provider = Chef::Provider::Machine.new(machine_resource, machine_resource.run_context)
|
152
|
+
provider.load_current_resource
|
153
|
+
{
|
154
|
+
:spec => provider.machine_spec,
|
155
|
+
:desired_driver => machine_resource.driver,
|
156
|
+
:files => machine_resource.files,
|
157
|
+
:machine_options => proc { |driver| provider.machine_options(driver) }
|
158
|
+
}
|
159
|
+
elsif machine.is_a?(Chef::Provisioning::MachineSpec)
|
160
|
+
machine_spec = machine
|
161
|
+
{
|
162
|
+
:spec => machine_spec,
|
163
|
+
:desired_driver => new_resource.driver,
|
164
|
+
:files => new_resource.files,
|
165
|
+
:machine_options => proc { |driver| machine_options(driver) }
|
166
|
+
}
|
167
|
+
else
|
168
|
+
name = machine
|
169
|
+
machine_spec = Chef::Provisioning::ChefMachineSpec.get(name, new_resource.chef_server) ||
|
170
|
+
Chef::Provisioning::ChefMachineSpec.empty(name, new_resource.chef_server)
|
171
|
+
{
|
172
|
+
:spec => machine_spec,
|
173
|
+
:desired_driver => new_resource.driver,
|
174
|
+
:files => new_resource.files,
|
175
|
+
:machine_options => proc { |driver| machine_options(driver) }
|
176
|
+
}
|
177
|
+
end
|
178
|
+
end.to_a
|
179
|
+
end
|
180
|
+
|
181
|
+
def machine_options(driver)
|
182
|
+
result = { :convergence_options => { :chef_server => new_resource.chef_server } }
|
183
|
+
result = Chef::Mixin::DeepMerge.hash_only_merge(result, run_context.chef_provisioning.config[:machine_options]) if run_context.chef_provisioning.config[:machine_options]
|
184
|
+
result = Chef::Mixin::DeepMerge.hash_only_merge(result, driver.config[:machine_options]) if driver.config && driver.config[:machine_options]
|
185
|
+
result = Chef::Mixin::DeepMerge.hash_only_merge(result, new_resource.machine_options)
|
186
|
+
result
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|