dev-lxc 2.6.1 → 2.6.2

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.
@@ -1,1211 +1,1211 @@
1
- require "dev-lxc/server"
2
- require "mixlib/install"
3
- require "open-uri"
4
-
5
- module DevLXC
6
- class Cluster
7
- attr_reader :config
8
-
9
- def initialize(cluster_config)
10
- FileUtils.mkdir_p('/var/dev-lxc') unless Dir.exist?('/var/dev-lxc')
11
-
12
- @config = Hash.new { |hash, key| hash[key] = {} }
13
- @server_configs = Hash.new
14
-
15
- %w(adhoc analytics automate build-nodes chef-backend chef-server compliance nodes runners supermarket).each do |server_type|
16
- if cluster_config[server_type]
17
- if cluster_config[server_type]["servers"]
18
- cluster_config[server_type]["servers"].each do |server_name, server_config|
19
- server_config ||= Hash.new
20
-
21
- products = server_config['products']
22
- products ||= Hash.new
23
-
24
- enable_build_snapshots = cluster_config[server_type]["enable_build_snapshots"]
25
- enable_build_snapshots = cluster_config["enable_build_snapshots"] if enable_build_snapshots.nil?
26
- enable_build_snapshots = server_config["enable_build_snapshots"] if server_config.key?("enable_build_snapshots")
27
- enable_build_snapshots = true if enable_build_snapshots.nil?
28
-
29
- memory_per_server = cluster_config[server_type]["memory_per_server"]
30
- memory_per_server ||= cluster_config["memory_per_server"]
31
- memory_per_server = server_config["memory_per_server"] if server_config["memory_per_server"]
32
-
33
- mounts = ["/var/dev-lxc var/dev-lxc"]
34
- if cluster_config[server_type]["mounts"]
35
- mounts.concat(cluster_config[server_type]["mounts"])
36
- elsif cluster_config["mounts"]
37
- mounts.concat(cluster_config["mounts"])
38
- end
39
- mounts = ["/var/dev-lxc var/dev-lxc"] + server_config["mounts"] if server_config["mounts"]
40
-
41
- ssh_keys = cluster_config[server_type]["ssh-keys"]
42
- ssh_keys ||= cluster_config["ssh-keys"]
43
- ssh_keys = server_config["ssh-keys"] if server_config["ssh-keys"]
44
-
45
- base_container_name = cluster_config[server_type]["base_container"]
46
- base_container_name ||= cluster_config["base_container"]
47
- base_container_name = server_config["base_container"] if server_config["base_container"]
48
-
49
- @server_configs[server_name] = {
50
- server_type: server_type,
51
- products: products,
52
- ipaddress: server_config['ipaddress'],
53
- additional_fqdn: nil,
54
- enable_build_snapshots: enable_build_snapshots,
55
- first_run: false,
56
- memory_per_server: memory_per_server,
57
- mounts: mounts,
58
- ssh_keys: ssh_keys,
59
- base_container_name: base_container_name
60
- }
61
- # gather configuration from only the first "automate", "compliance" or "supermarket" server
62
- break if %w(automate compliance supermarket).include?(server_type)
63
- end
64
- end
65
-
66
- case server_type
67
- when "analytics"
68
- @config[server_type][:topology] = cluster_config[server_type]["topology"]
69
- @config[server_type][:topology] ||= 'standalone'
70
- @config[server_type][:fqdn] = cluster_config[server_type]["analytics_fqdn"]
71
- @config[server_type][:frontends] = Array.new
72
-
73
- if cluster_config[server_type]["servers"]
74
- cluster_config[server_type]["servers"].each do |server_name, server_config|
75
- server_config ||= Hash.new
76
- additional_fqdn = nil
77
- case @config[server_type][:topology]
78
- when 'standalone'
79
- @config[server_type][:bootstrap_backend] = server_name if server_config["role"].nil?
80
- @config[server_type][:fqdn] ||= @config[server_type][:bootstrap_backend]
81
- when 'tier'
82
- @config[server_type][:bootstrap_backend] = server_name if server_config["role"] == "backend" && server_config["bootstrap"] == true
83
- if server_config["role"] == "frontend"
84
- additional_fqdn = @config[server_type][:fqdn]
85
- @config[server_type][:frontends] << server_name
86
- end
87
- end
88
- @server_configs[server_name].merge!({
89
- additional_fqdn: additional_fqdn
90
- })
91
- end
92
- end
93
- when "chef-backend"
94
- @config[server_type][:fqdn] = cluster_config[server_type]["api_fqdn"]
95
- @config[server_type][:users] = cluster_config[server_type]["users"]
96
- @config[server_type][:users] ||= Array.new
97
- @config[server_type][:orgs] = cluster_config[server_type]["orgs"]
98
- @config[server_type][:orgs] ||= Hash.new
99
- @config[server_type][:backends] = Array.new
100
- @config[server_type][:frontends] = Array.new
101
-
102
- servers = cluster_config[server_type]["servers"]
103
- if servers
104
- @config[server_type][:leader_backend] = servers.select { |s,sc| sc['role'] == 'backend' && sc['leader'] == true }.keys.first
105
- @config[server_type][:bootstrap_frontend] = servers.select { |s,sc| sc['role'] == 'frontend' && sc['bootstrap'] == true }.keys.first
106
- @config[server_type][:backends] << @config[server_type][:leader_backend]
107
- @config[server_type][:frontends] << @config[server_type][:bootstrap_frontend]
108
- servers.each do |server_name, server_config|
109
- server_config ||= Hash.new
110
- additional_fqdn = nil
111
- case server_config["role"]
112
- when "backend"
113
- @config[server_type][:backends] << server_name unless server_name == @config[server_type][:leader_backend]
114
- when "frontend"
115
- additional_fqdn = @config[server_type][:fqdn]
116
- @config[server_type][:frontends] << server_name unless server_name == @config[server_type][:bootstrap_frontend]
117
- end
118
- @server_configs[server_name].merge!({
119
- additional_fqdn: additional_fqdn,
120
- chef_server_type: 'chef-server'
121
- })
122
- end
123
- end
124
- when "chef-server"
125
- @config[server_type][:topology] = cluster_config[server_type]["topology"]
126
- @config[server_type][:topology] ||= 'standalone'
127
- @config[server_type][:fqdn] = cluster_config[server_type]["api_fqdn"]
128
- @config[server_type][:users] = cluster_config[server_type]["users"]
129
- @config[server_type][:users] ||= Array.new
130
- @config[server_type][:orgs] = cluster_config[server_type]["orgs"]
131
- @config[server_type][:orgs] ||= Hash.new
132
- @config[server_type][:frontends] = Array.new
133
-
134
- if cluster_config[server_type]["servers"]
135
- cluster_config[server_type]["servers"].each do |server_name, server_config|
136
- server_config ||= Hash.new
137
- additional_fqdn = nil
138
- chef_server_type = 'private-chef' if @server_configs[server_name][:products].has_key?('private-chef')
139
- chef_server_type = 'chef-server' if @server_configs[server_name][:products].has_key?('chef-server')
140
- case @config[server_type][:topology]
141
- when 'standalone'
142
- @config[server_type][:bootstrap_backend] = server_name if server_config["role"].nil?
143
- @config[server_type][:fqdn] ||= @config[server_type][:bootstrap_backend]
144
- when 'tier'
145
- @config[server_type][:bootstrap_backend] = server_name if server_config["role"] == "backend" && server_config["bootstrap"] == true
146
- if server_config["role"] == "frontend"
147
- additional_fqdn = @config[server_type][:fqdn]
148
- @config[server_type][:frontends] << server_name
149
- end
150
- end
151
- @server_configs[server_name].merge!({
152
- additional_fqdn: additional_fqdn,
153
- chef_server_type: chef_server_type
154
- })
155
- end
156
- end
157
- when "supermarket"
158
- unless cluster_config[server_type]["servers"].first.nil?
159
- (server_name, server_config) = cluster_config[server_type]["servers"].first
160
- @config[server_type][:fqdn] = server_name
161
- end
162
- when "compliance"
163
- unless cluster_config[server_type]["servers"].first.nil?
164
- (server_name, server_config) = cluster_config[server_type]["servers"].first
165
- @server_configs[server_name][:admin_user] = cluster_config[server_type]["admin_user"]
166
- end
167
- when "automate"
168
- unless cluster_config[server_type]["servers"].first.nil?
169
- (server_name, server_config) = cluster_config[server_type]["servers"].first
170
- server_config ||= Hash.new
171
- @server_configs[server_name].merge!({
172
- license_path: server_config['license_path'],
173
- chef_org: server_config['chef_org'],
174
- enterprise_name: server_config['enterprise_name']
175
- })
176
- end
177
- when "nodes"
178
- chef_server_url = cluster_config[server_type]['chef_server_url']
179
- validation_client_name = cluster_config[server_type]['validation_client_name']
180
- validation_key = cluster_config[server_type]['validation_key']
181
- if cluster_config[server_type]["servers"]
182
- cluster_config[server_type]["servers"].each do |server_name, server_config|
183
- server_config ||= Hash.new
184
- chef_server_url = server_config['chef_server_url'] if server_config['chef_server_url']
185
- validation_client_name = server_config['validation_client_name'] if server_config['validation_client_name']
186
- validation_key = server_config['validation_key'] if server_config['validation_key']
187
- @server_configs[server_name].merge!({
188
- chef_server_url: chef_server_url,
189
- validation_client_name: validation_client_name,
190
- validation_key: validation_key
191
- })
192
- end
193
- end
194
- end
195
- end
196
- end
197
- validate_cluster_config
198
- end
199
-
200
- def validate_cluster_config
201
- base_container_names = Array.new
202
- mounts = Array.new
203
- ssh_keys = Array.new
204
- hostnames = Array.new
205
-
206
- @config.map { |server_type, config| hostnames.push(config[:fqdn]) }
207
-
208
- @server_configs.each do |server_name, server_config|
209
- base_container_names.push(server_config[:base_container_name]).uniq! if server_config[:base_container_name]
210
- mounts.concat(server_config[:mounts]).uniq! if server_config[:mounts]
211
- ssh_keys.concat(server_config[:ssh_keys]).uniq! if server_config[:ssh_keys]
212
- hostnames.push(server_name)
213
- case server_config[:server_type]
214
- when "automate"
215
- if server_config[:license_path] && !File.file?(server_config[:license_path])
216
- puts "ERROR: Automate license #{server_config[:license_path]} does not exist or is not a file."
217
- exit 1
218
- end
219
- when "nodes"
220
- if server_config[:validation_key] && !File.file?(server_config[:validation_key])
221
- puts "ERROR: Validation key #{server_config[:validation_key]} does not exist or is not a file."
222
- exit 1
223
- end
224
- end
225
- end
226
-
227
- unless base_container_names.empty?
228
- base_container_names.each do |base_container_name|
229
- unless ::DevLXC::Container.new(base_container_name).defined?
230
- puts "ERROR: Base container #{base_container_name} does not exist."
231
- exit 1
232
- end
233
- end
234
- end
235
- unless hostnames.empty?
236
- hostnames.each do |hostname|
237
- unless hostname.end_with?(".lxc")
238
- puts "ERROR: Hostname #{hostname} does not end with '.lxc'."
239
- exit 1
240
- end
241
- end
242
- end
243
- unless mounts.empty?
244
- mounts.each do |mount|
245
- unless File.exists?(mount.split.first)
246
- puts "ERROR: Mount source #{mount.split.first} does not exist."
247
- exit 1
248
- end
249
- end
250
- end
251
- unless ssh_keys.empty?
252
- ssh_keys.each do |ssh_key|
253
- unless File.exists?(ssh_key)
254
- puts "ERROR: SSH key #{ssh_key} does not exist."
255
- exit 1
256
- end
257
- end
258
- end
259
- end
260
-
261
- def show_config(include_products=false)
262
- require 'pp'
263
- calculate_required_products(get_sorted_servers, true) if include_products
264
- puts "Cluster config:"
265
- pp @config
266
- puts
267
- puts "Server configs:"
268
- pp @server_configs
269
- end
270
-
271
- def get_server(server_name)
272
- ipaddress = @server_configs[server_name][:ipaddress]
273
- additional_fqdn = @server_configs[server_name][:additional_fqdn]
274
- memory_per_server = @server_configs[server_name][:memory_per_server]
275
- mounts = @server_configs[server_name][:mounts]
276
- ssh_keys = @server_configs[server_name][:ssh_keys]
277
- Server.new(server_name, ipaddress, additional_fqdn, memory_per_server, mounts, ssh_keys)
278
- end
279
-
280
- def get_sorted_servers(server_name_regex=nil)
281
- servers = Array.new
282
-
283
- # the order of this list of server_types matters
284
- # it determines the order in which actions are applied to each server_type
285
- %w(chef-backend chef-server analytics compliance supermarket automate build-nodes runners nodes adhoc).each do |server_type|
286
- unless @config[server_type].empty?
287
- case server_type
288
- when "chef-backend"
289
- @config[server_type][:backends].each do |backend_name|
290
- servers << get_server(backend_name)
291
- end
292
- @config[server_type][:frontends].each do |frontend_name|
293
- servers << get_server(frontend_name)
294
- end
295
- when "analytics", "chef-server"
296
- if @config[server_type][:bootstrap_backend]
297
- server_name = @config[server_type][:bootstrap_backend]
298
- servers << get_server(server_name)
299
- end
300
- @config[server_type][:frontends].each do |frontend_name|
301
- servers << get_server(frontend_name)
302
- end
303
- end
304
- end
305
- if %w(adhoc automate build-nodes compliance nodes runners supermarket).include?(server_type)
306
- server_configs = @server_configs.select { |server_name, server_config| server_config[:server_type] == server_type }
307
- server_configs.each_key { |server_name| servers << get_server(server_name) }
308
- end
309
- end
310
- servers.select { |s| s.name =~ /#{server_name_regex}/ }
311
- end
312
-
313
- def destroy(server_name_regex=nil)
314
- servers = get_sorted_servers(server_name_regex)
315
- servers.reverse_each { |s| s.destroy; puts }
316
- delete_dns_records unless get_sorted_servers.any? { |s| s.container.state != :stopped }
317
- end
318
-
319
- def halt(server_name_regex=nil)
320
- servers = get_sorted_servers(server_name_regex)
321
- servers.reverse_each { |s| s.shutdown; puts }
322
- delete_dns_records unless get_sorted_servers.any? { |s| s.container.state != :stopped }
323
- end
324
-
325
- def delete_dns_records
326
- @server_configs.keys.each { |server_name| DevLXC::search_file_delete_line("/etc/lxc/addn-hosts.conf", /\s#{server_name}/) }
327
- DevLXC::reload_dnsmasq
328
- end
329
-
330
- def up(server_name_regex=nil)
331
- configured_servers = Array.new
332
- servers = get_sorted_servers(server_name_regex)
333
- exit 1 if abort_up(servers)
334
- servers.each do |server|
335
- unless server.container.defined?
336
- clone_from_base_container(server)
337
- @server_configs[server.name][:first_run] = true
338
- end
339
- end
340
- prep_product_cache(servers)
341
- # get_sorted_servers is called again in order to ensure the container objects are initialized properly in case they were just cloned from the base container
342
- servers = get_sorted_servers(server_name_regex)
343
- create_dns_records unless servers.empty?
344
- servers.each do |server|
345
- next if ! @server_configs[server.name][:enable_build_snapshots] && ! @server_configs[server.name][:first_run]
346
- if %w(build-nodes runners).include?(@server_configs[server.name][:server_type])
347
- next if @server_configs[server.name][:required_products]["chefdk"] && @server_configs[server.name][:required_products].length == 1
348
- end
349
- install_products(server) unless @server_configs[server.name][:required_products].empty?
350
- end
351
- servers.each do |server|
352
- if server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
353
- if server.name == @config["chef-backend"][:bootstrap_frontend]
354
- running_backends = Array.new
355
- @config["chef-backend"][:backends].reverse_each do |server_name|
356
- next unless @server_configs[server_name][:enable_build_snapshots]
357
- backend = get_server(server_name)
358
- if backend.container.defined? && backend.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: backend cluster configured but frontend not bootstrapped") }.empty?
359
- if backend.container.running?
360
- running_backends << backend.name
361
- backend.shutdown
362
- end
363
- backend.snapshot("dev-lxc build: backend cluster configured but frontend not bootstrapped")
364
- snapshot = backend.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.first
365
- backend.snapshot_destroy(snapshot.first) if snapshot
366
- end
367
- end
368
- @config["chef-backend"][:backends].each do |server_name|
369
- next unless @server_configs[server_name][:enable_build_snapshots]
370
- if running_backends.include?(server_name)
371
- get_server(server_name).start
372
- configured_servers << server_name unless configured_servers.include?(server_name)
373
- end
374
- end
375
- end
376
- if @server_configs[server.name][:enable_build_snapshots] || @server_configs[server.name][:first_run]
377
- configure_products(server)
378
- configured_servers << server.name
379
- end
380
- end
381
- if server.container.running?
382
- puts "Container '#{server.name}' is already running"
383
- puts
384
- else
385
- server.start
386
- end
387
- end
388
- configured_servers.reverse_each do |server_name|
389
- next unless @server_configs[server_name][:enable_build_snapshots]
390
- server = get_server(server_name)
391
- server.shutdown if server.container.running?
392
- server.snapshot("dev-lxc build: completed")
393
- end
394
- configured_servers.each do |server_name|
395
- next unless @server_configs[server_name][:enable_build_snapshots]
396
- server = get_server(server_name)
397
- server.start if server.container.defined?
398
- end
399
- end
400
-
401
- def abort_up(servers)
402
- abort_up = false
403
- servers.each do |server|
404
- next if server.container.defined? && !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
405
- next if ! @server_configs[server.name][:enable_build_snapshots] && ! @server_configs[server.name][:first_run]
406
- if @server_configs[server.name][:server_type] == 'compliance' && @config["chef-server"][:topology] == "standalone"
407
- if @config['chef-server'][:bootstrap_backend].nil?
408
- puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
409
- abort_up = true
410
- elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.running? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
411
- puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be running first."
412
- abort_up = true
413
- end
414
- end
415
- if (@config['chef-server'][:frontends] && @config['chef-server'][:frontends].include?(server.name)) || server.name == @config['analytics'][:bootstrap_backend]
416
- if @config['chef-server'][:bootstrap_backend].nil?
417
- puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
418
- abort_up = true
419
- elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
420
- puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
421
- abort_up = true
422
- end
423
- end
424
- if @config['chef-server'][:bootstrap_backend] && @server_configs[server.name][:server_type] == 'supermarket'
425
- if !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
426
- puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
427
- abort_up = true
428
- end
429
- end
430
- if @config['analytics'][:frontends] && @config['analytics'][:frontends].include?(server.name)
431
- if @config['analytics'][:bootstrap_backend].nil?
432
- puts "ERROR: '#{server.name}' requires an Analytics Server bootstrap backend to be configured first."
433
- abort_up = true
434
- elsif !get_server(@config['analytics'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['analytics'][:bootstrap_backend] }.empty?
435
- puts "ERROR: '#{server.name}' requires '#{@config['analytics'][:bootstrap_backend]}' to be configured first."
436
- abort_up = true
437
- end
438
- end
439
- if @config['chef-backend'][:frontends] && @config['chef-backend'][:frontends].include?(server.name) && server.name != @config['chef-backend'][:bootstrap_frontend]
440
- if @config['chef-backend'][:bootstrap_frontend].nil?
441
- puts "ERROR: '#{server.name}' requires a Chef Server bootstrap frontend to be configured first."
442
- abort_up = true
443
- elsif !get_server(@config['chef-backend'][:bootstrap_frontend]).container.defined? && servers.select { |s| s.name == @config['chef-backend'][:bootstrap_frontend] }.empty?
444
- puts "ERROR: '#{server.name}' requires '#{@config['chef-backend'][:bootstrap_frontend]}' to be configured first."
445
- abort_up = true
446
- end
447
- end
448
- if server.name == @config['chef-backend'][:bootstrap_frontend]
449
- if (@config['chef-backend'][:backends].select { |s| get_server(s).container.running? }.length + servers.select { |s| @config['chef-backend'][:backends].include?(s.name) }.length) < 2
450
- puts "ERROR: '#{server.name}' requires at least two nodes in the backend cluster to be running first."
451
- abort_up = true
452
- end
453
- end
454
- if @config['chef-backend'][:backends] && @config['chef-backend'][:backends].include?(server.name) && server.name != @config['chef-backend'][:leader_backend]
455
- if !get_server(@config['chef-backend'][:leader_backend]).container.running? && servers.select { |s| s.name == @config['chef-backend'][:leader_backend] }.empty?
456
- puts "ERROR: '#{server.name}' requires '#{@config['chef-backend'][:leader_backend]}' to be running first."
457
- abort_up = true
458
- end
459
- end
460
- if @server_configs[server.name][:server_type] == 'nodes'
461
- if @server_configs[server.name][:chef_server_url] && @server_configs[server.name][:validation_client_name] && @server_configs[server.name][:validation_key].nil?
462
- if @config['chef-server'][:bootstrap_backend] && !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
463
- puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
464
- abort_up = true
465
- elsif @config['chef-backend'][:bootstrap_frontend] && !get_server(@config['chef-backend'][:bootstrap_frontend]).container.defined? && servers.select { |s| s.name == @config['chef-backend'][:bootstrap_frontend] }.empty?
466
- puts "ERROR: '#{server.name}' requires '#{@config['chef-backend'][:bootstrap_frontend]}' to be configured first."
467
- abort_up = true
468
- end
469
- end
470
- end
471
- if @server_configs[server.name][:server_type] == 'automate'
472
- if @config['chef-server'][:bootstrap_backend].nil?
473
- puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
474
- abort_up = true
475
- elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
476
- puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
477
- abort_up = true
478
- end
479
- end
480
- if %w(build-nodes runners).include?(@server_configs[server.name][:server_type])
481
- if @config['chef-server'][:bootstrap_backend].nil?
482
- puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
483
- abort_up = true
484
- elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.running? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
485
- puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be running first."
486
- abort_up = true
487
- end
488
- if @config['chef-server'][:topology] == 'tier'
489
- if @config[server_type][:frontends].empty?
490
- puts "ERROR: '#{server.name}' requires at least one Chef Server frontend to be configured first."
491
- abort_up = true
492
- elsif (@config['chef-server'][:frontends].select { |s| get_server(s).container.running? }.length + servers.select { |s| @config['chef-server'][:frontends].include?(s.name) }.length) < 1
493
- puts "ERROR: '#{server.name}' requires at least one Chef Server frontend to be running first."
494
- abort_up = true
495
- end
496
- end
497
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
498
- if automate_server_name
499
- if !get_server(automate_server_name).container.running? && servers.select { |s| s.name == automate_server_name }.empty?
500
- puts "ERROR: '#{server.name}' requires '#{automate_server_name}' to be running first."
501
- abort_up = true
502
- end
503
- else
504
- puts "ERROR: '#{server.name}' requires an Automate Server to be configured first."
505
- abort_up = true
506
- end
507
- end
508
- end
509
- return abort_up
510
- end
511
-
512
- def create_dns_records
513
- get_sorted_servers.each do |server|
514
- ipaddress = server.container.ip_addresses.first
515
- ipaddress ||= @server_configs[server.name][:ipaddress]
516
- next unless ipaddress
517
- additional_fqdn = @server_configs[server.name][:additional_fqdn]
518
- dns_record = "#{ipaddress} #{server.name}"
519
- dns_record += " #{additional_fqdn}\n" if additional_fqdn
520
- DevLXC::search_file_delete_line("/etc/lxc/addn-hosts.conf", /\s#{server.name}/)
521
- DevLXC::append_line_to_file("/etc/lxc/addn-hosts.conf", dns_record)
522
- end
523
- DevLXC::reload_dnsmasq
524
- end
525
-
526
- def clone_from_base_container(server)
527
- server_type = @server_configs[server.name][:server_type]
528
- base_container = DevLXC::Container.new(@server_configs[server.name][:base_container_name])
529
- puts "Cloning base container '#{base_container.name}' into container '#{server.name}'"
530
- base_container.clone(server.name, {:flags => LXC::LXC_CLONE_SNAPSHOT})
531
- server.container.load_config
532
- puts "Deleting SSH Server Host Keys"
533
- FileUtils.rm_f(Dir.glob("#{server.container.config_item('lxc.rootfs')}/etc/ssh/ssh_host*_key*"))
534
- end
535
-
536
- def get_product_download_info(server, product_name, product_options)
537
- server_type = @server_configs[server.name][:server_type]
538
- base_container = DevLXC::Container.new(@server_configs[server.name][:base_container_name])
539
- mixlib_install_platform_detection_path = "#{base_container.config_item('lxc.rootfs')}/mixlib-install-platform-detection"
540
- IO.write(mixlib_install_platform_detection_path, Mixlib::Install::Generator::Bourne.detect_platform_sh)
541
- platform_results = `chroot #{base_container.config_item('lxc.rootfs')} bash mixlib-install-platform-detection`
542
- File.unlink(mixlib_install_platform_detection_path)
543
- if platform_results.empty?
544
- puts "ERROR: Unable to detect the platform of container '#{base_container.name}'"
545
- exit 1
546
- end
547
- (platform, platform_version, architecture) = platform_results.split
548
- product_version = product_options['version'] if product_options
549
- product_version ||= 'latest'
550
- channel = product_options['channel'] if product_options
551
- channel ||= 'stable'
552
- channel = channel.to_sym
553
- options = {
554
- product_name: product_name,
555
- product_version: product_version,
556
- channel: channel,
557
- platform: platform,
558
- platform_version: platform_version,
559
- architecture: architecture
560
- }
561
- artifact = Mixlib::Install.new(options).artifact_info
562
- if artifact.class != Mixlib::Install::ArtifactInfo
563
- puts "ERROR: Unable to find download URL for the following product"
564
- puts JSON.pretty_generate(options)
565
- exit 1
566
- end
567
- [artifact.url, artifact.sha256]
568
- end
569
-
570
- def calculate_required_products(servers, force=false)
571
- all_required_products = Hash.new
572
- servers.each do |server|
573
- products = @server_configs[server.name][:products]
574
- @server_configs[server.name][:required_products] = Hash.new
575
- if !force && !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: products installed") }.empty?
576
- # Skipping product cache preparation for container because it has a 'products installed' snapshot
577
- next
578
- elsif !force && !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
579
- # Skipping product cache preparation for container because it has a 'build: completed' snapshot
580
- next
581
- elsif ! @server_configs[server.name][:enable_build_snapshots] && ! @server_configs[server.name][:first_run]
582
- # Skipping product cache preparation for container because it build snapshots are disabled and this is not the container's first run
583
- next
584
- end
585
- products.each do |product_name, product_options|
586
- if product_options && product_options['package_source']
587
- package_source = product_options['package_source']
588
- all_required_products[package_source] = [product_name, nil]
589
- @server_configs[server.name][:required_products][product_name] = package_source
590
- else
591
- package_source, package_sha256 = get_product_download_info(server, product_name, product_options)
592
- all_required_products[package_source] = [product_name, package_sha256]
593
- product_cache_path = "/var/dev-lxc/cache/chef-products/#{product_name}/#{File.basename(package_source)}"
594
- @server_configs[server.name][:required_products][product_name] = product_cache_path
595
- end
596
- end
597
- end
598
- all_required_products
599
- end
600
-
601
- def prep_product_cache(servers, force=false)
602
- all_required_products = calculate_required_products(servers, force)
603
- all_required_products.each do |package_source, v|
604
- product_name, package_sha256 = v
605
- if package_source.start_with?('http')
606
- product_cache_path = "/var/dev-lxc/cache/chef-products/#{product_name}/#{File.basename(package_source)}"
607
- if !File.exist?(product_cache_path)
608
- FileUtils.mkdir_p(File.dirname(product_cache_path)) unless Dir.exist?(File.dirname(product_cache_path))
609
- puts "Downloading #{package_source} to #{product_cache_path}"
610
- open(package_source) { |url| File.open(product_cache_path, 'wb') { |f| f.write(url.read) } }
611
- end
612
- if package_sha256 != Digest::SHA256.file(product_cache_path).hexdigest
613
- puts "ERROR: Incorrect SHA256 for #{product_cache_path}"
614
- exit 1
615
- end
616
- elsif !File.exist?(package_source)
617
- puts "ERROR: Package source #{package_source} does not exist."
618
- exit 1
619
- end
620
- end
621
- end
622
-
623
- def install_products(server)
624
- if !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: products installed") }.empty?
625
- puts "Skipping product installation for container '#{server.name}' because it already has a 'products installed' snapshot"
626
- return
627
- elsif !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
628
- puts "Skipping product installation for container '#{server.name}' because it already has a 'build: completed' snapshot"
629
- return
630
- end
631
- if server.container.running?
632
- server_was_running = true
633
- else
634
- server_was_running = false
635
- server.start
636
- end
637
- @server_configs[server.name][:required_products].each do |product_name, package_source|
638
- next if %w(build-nodes runners).include?(@server_configs[server.name][:server_type]) && product_name == "chefdk"
639
- server.install_package(package_source)
640
- end
641
- if @server_configs[server.name][:enable_build_snapshots]
642
- server.shutdown
643
- server.snapshot("dev-lxc build: products installed")
644
- server.start if server_was_running
645
- end
646
- end
647
-
648
- def configure_products(server)
649
- puts "Configuring container '#{server.name}'"
650
- server.start
651
- installed_products = @server_configs[server.name][:products].keys if @server_configs[server.name][:products]
652
- installed_products ||= Array.new
653
- server_type = @server_configs[server.name][:server_type]
654
- dot_chef_path = "/root/chef-repo/.chef"
655
- case server_type
656
- when 'adhoc'
657
- # Allow adhoc servers time to generate SSH Server Host Keys
658
- sleep 5
659
- when 'analytics'
660
- configure_analytics(server) if installed_products.include?('analytics')
661
- when 'build-nodes'
662
- sleep 5 # give time for DNS resolution to be available
663
- configure_build_node(server)
664
- when 'runners'
665
- sleep 5 # give time for DNS resolution to be available
666
- configure_runner(server)
667
- when 'chef-backend'
668
- configure_chef_backend(server) if installed_products.include?('chef-backend')
669
- if installed_products.include?('chef-server')
670
- configure_chef_frontend(server)
671
- if server.name == @config['chef-backend'][:bootstrap_frontend]
672
- create_users_orgs_knife_configs(server, dot_chef_path)
673
- end
674
- end
675
- configure_manage(server) if installed_products.include?('manage')
676
- when 'chef-server'
677
- if installed_products.include?('chef-server') || installed_products.include?('private-chef')
678
- configure_chef_server(server)
679
- if server.name == @config['chef-server'][:bootstrap_backend]
680
- create_users_orgs_knife_configs(server, dot_chef_path)
681
-
682
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
683
- if automate_server_name
684
- automate_user = "delivery"
685
- automate_chef_org = @server_configs[automate_server_name][:chef_org]
686
- create_user(server, automate_user, dot_chef_path)
687
- create_org(server, automate_chef_org, dot_chef_path)
688
- org_add_user(server, automate_chef_org, automate_user, true, dot_chef_path)
689
- end
690
- end
691
- end
692
- configure_reporting(server) if installed_products.include?('reporting')
693
- configure_push_jobs_server(server) if installed_products.include?('push-jobs-server')
694
- configure_manage(server) if installed_products.include?('manage')
695
- when 'compliance'
696
- configure_compliance(server) if installed_products.include?('compliance')
697
- when 'automate'
698
- configure_automate(server) if installed_products.include?('delivery')
699
- when 'nodes'
700
- # Allow servers time to generate SSH Server Host Keys
701
- sleep 5
702
- configure_chef_client(server, dot_chef_path) if installed_products.include?('chef') || installed_products.include?('chefdk')
703
- when 'supermarket'
704
- configure_supermarket(server) if installed_products.include?('supermarket')
705
- end
706
- end
707
-
708
- def configure_automate(server)
709
- license_path = @server_configs[server.name][:license_path]
710
- chef_org = @server_configs[server.name][:chef_org]
711
- enterprise_name = @server_configs[server.name][:enterprise_name]
712
- chef_server_url = @config['chef-server'][:fqdn]
713
- supermarket_fqdn = @config['supermarket'][:fqdn]
714
-
715
- FileUtils.cp(license_path, "#{server.container.config_item('lxc.rootfs')}/root/automate.license")
716
-
717
- chef_server = get_server(@config['chef-server'][:bootstrap_backend])
718
- automate_chef_user_key = "#{chef_server.container.config_item('lxc.rootfs')}/root/chef-repo/.chef/delivery.pem"
719
- FileUtils.cp(automate_chef_user_key, "#{server.container.config_item('lxc.rootfs')}/root/automate_chef_user_key.pem")
720
-
721
- setup_cmd = "setup"
722
- setup_cmd += " --license /root/automate.license"
723
- setup_cmd += " --fqdn #{server.name}"
724
- setup_cmd += " --key /root/automate_chef_user_key.pem"
725
- setup_cmd += " --server-url https://#{chef_server_url}/organizations/#{chef_org}"
726
- setup_cmd += " --supermarket-fqdn #{supermarket_fqdn}" if supermarket_fqdn
727
- setup_cmd += " --enterprise #{enterprise_name}"
728
- setup_cmd += " --no-build-node"
729
- setup_cmd += " --no-configure"
730
- server.run_command("delivery-ctl #{setup_cmd}")
731
-
732
- # enable Compliance profiles asset store
733
- DevLXC::append_line_to_file("#{server.container.config_item('lxc.rootfs')}/etc/delivery/delivery.rb", "compliance_profiles['enable'] = true\n")
734
-
735
- server.run_command("delivery-ctl reconfigure")
736
-
737
- # give time for all services to come up completely
738
- sleep 10
739
-
740
- server.run_command("delivery-ctl create-enterprise #{enterprise_name} --ssh-pub-key-file /etc/delivery/builder_key.pub", "#{server.container.config_item('lxc.rootfs')}/etc/delivery/#{enterprise_name}-admin-credentials")
741
- end
742
-
743
- def print_automate_credentials
744
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
745
- if automate_server_name
746
- automate_server = get_server(automate_server_name)
747
- automate_credentials_files = Dir.glob("#{automate_server.container.config_item('lxc.rootfs')}/etc/delivery/*-credentials")
748
- automate_credentials_files.each_with_index do |automate_credentials_file, index|
749
- puts IO.read(automate_credentials_file)
750
- puts if index + 1 < automate_credentials_files.length
751
- end
752
- else
753
- puts "WARNING: An Automate server is not defined."
754
- exit 1
755
- end
756
- end
757
-
758
- def configure_build_node(server)
759
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
760
- if automate_server_name
761
- automate_server = get_server(automate_server_name)
762
- install_build_node_cmd = "install-build-node"
763
- install_build_node_cmd += " --fqdn #{server.name}"
764
- install_build_node_cmd += " --username dev-lxc"
765
- install_build_node_cmd += " --password dev-lxc"
766
- install_build_node_cmd += " --installer #{@server_configs[server.name][:required_products]["chefdk"]}"
767
- install_build_node_cmd += " --overwrite-registration"
768
- automate_server.run_command("delivery-ctl #{install_build_node_cmd}")
769
- end
770
- end
771
-
772
- def configure_runner(server)
773
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
774
- if automate_server_name
775
- automate_server = get_server(automate_server_name)
776
- install_runner_cmd = "install-runner #{server.name} dev-lxc"
777
- install_runner_cmd += " --password dev-lxc"
778
- install_runner_cmd += " --installer #{@server_configs[server.name][:required_products]["chefdk"]}"
779
- install_runner_cmd += " --yes"
780
- automate_server.run_command("delivery-ctl #{install_runner_cmd}")
781
- end
782
- end
783
-
784
- def configure_chef_client(server, dot_chef_path)
785
- puts "Configuring Chef Client in container '#{server.name}'"
786
-
787
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/chef")
788
-
789
- chef_server_url = @server_configs[server.name][:chef_server_url]
790
- validation_client_name = @server_configs[server.name][:validation_client_name]
791
- validation_key = @server_configs[server.name][:validation_key]
792
- if validation_key.nil?
793
- chef_server_name = @config['chef-server'][:bootstrap_backend]
794
- chef_server_name ||= @config['chef-backend'][:bootstrap_frontend]
795
- if chef_server_name
796
- chef_server = get_server(chef_server_name)
797
- if chef_server.container.defined?
798
- validator_pem_files = Dir.glob("#{chef_server.container.config_item('lxc.rootfs')}#{dot_chef_path}/*-validator.pem")
799
- FileUtils.cp(validator_pem_files, "#{server.container.config_item('lxc.rootfs')}/etc/chef/") unless validator_pem_files.empty?
800
- end
801
- end
802
- else
803
- FileUtils.cp(validation_key, "#{server.container.config_item('lxc.rootfs')}/etc/chef/") if File.exists?(validation_key)
804
- end
805
-
806
- client_rb = %Q(#http_proxy 'http://10.0.3.1:8080'
807
- #https_proxy 'http://10.0.3.1:8080'
808
-
809
- chef_server_url '#{chef_server_url}'
810
- validation_client_name '#{validation_client_name}'
811
- validation_key '/etc/chef/#{validation_client_name}.pem'
812
- ssl_verify_mode :verify_none
813
- )
814
-
815
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
816
- if automate_server_name
817
- client_rb += %Q(
818
- # data_collector.server_url "https://#{automate_server_name}/data-collector/v0/"
819
- # data_collector.token "93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506"
820
- )
821
- end
822
-
823
- IO.write("#{server.container.config_item('lxc.rootfs')}/etc/chef/client.rb", client_rb)
824
- end
825
-
826
- def configure_chef_backend(server)
827
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-backend")
828
- FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-backend/.license.accepted")
829
- if server.name == @config['chef-backend'][:leader_backend]
830
- puts "Creating /etc/chef-backend/chef-backend.rb"
831
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/chef-backend")
832
- chef_backend_config = "publish_address '#{@server_configs[server.name][:ipaddress]}'\n"
833
- IO.write("#{server.container.config_item('lxc.rootfs')}/etc/chef-backend/chef-backend.rb", chef_backend_config)
834
- server.run_command("chef-backend-ctl bootstrap --yes")
835
- else
836
- puts "Joining #{server.name} to the chef-backend cluster"
837
- leader_backend = get_server(@config['chef-backend'][:leader_backend])
838
- FileUtils.cp("#{leader_backend.container.config_item('lxc.rootfs')}/etc/chef-backend/chef-backend-secrets.json",
839
- "#{server.container.config_item('lxc.rootfs')}/root/")
840
- server.run_command("chef-backend-ctl join-cluster #{@server_configs[leader_backend.name][:ipaddress]} -p #{@server_configs[server.name][:ipaddress]} -s /root/chef-backend-secrets.json --yes")
841
- end
842
- end
843
-
844
- def configure_chef_frontend(server)
845
- puts "Creating /etc/opscode/chef-server.rb"
846
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/opscode")
847
- leader_backend = get_server(@config['chef-backend'][:leader_backend])
848
- leader_backend.run_command("chef-backend-ctl gen-server-config #{server.name} --filename /tmp/#{server.name}.rb")
849
- FileUtils.cp("#{leader_backend.container.config_item('lxc.rootfs')}/tmp/#{server.name}.rb",
850
- "#{server.container.config_item('lxc.rootfs')}/etc/opscode/chef-server.rb")
851
- unless server.name == @config['chef-backend'][:bootstrap_frontend]
852
- bootstrap_frontend = get_server(@config['chef-backend'][:bootstrap_frontend])
853
- puts "Copying /etc/opscode/private-chef-secrets.json from bootstrap frontend '#{bootstrap_frontend.name}'"
854
- FileUtils.cp("#{bootstrap_frontend.container.config_item('lxc.rootfs')}/etc/opscode/private-chef-secrets.json",
855
- "#{server.container.config_item('lxc.rootfs')}/etc/opscode/")
856
- puts "Copying /etc/opscode/pivotal.pem from bootstrap frontend '#{bootstrap_frontend.name}'"
857
- FileUtils.cp("#{bootstrap_frontend.container.config_item('lxc.rootfs')}/etc/opscode/pivotal.pem",
858
- "#{server.container.config_item('lxc.rootfs')}/etc/opscode/")
859
- end
860
- server.run_command("chef-server-ctl reconfigure")
861
- end
862
-
863
- def configure_chef_server(server)
864
- if @config['chef-server'][:topology] == "standalone" || @config['chef-server'][:bootstrap_backend] == server.name
865
- case @server_configs[server.name][:chef_server_type]
866
- when 'private-chef'
867
- puts "Creating /etc/opscode/private-chef.rb"
868
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/opscode")
869
- IO.write("#{server.container.config_item('lxc.rootfs')}/etc/opscode/private-chef.rb", chef_server_config)
870
- when 'chef-server'
871
- puts "Creating /etc/opscode/chef-server.rb"
872
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/opscode")
873
- IO.write("#{server.container.config_item('lxc.rootfs')}/etc/opscode/chef-server.rb", chef_server_config)
874
- end
875
- elsif @config['chef-server'][:frontends].include?(server.name)
876
- puts "Copying /etc/opscode from bootstrap backend '#{@config['chef-server'][:bootstrap_backend]}'"
877
- FileUtils.cp_r("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode",
878
- "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
879
- end
880
- server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
881
- end
882
-
883
- def configure_reporting(server)
884
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-reporting")
885
- FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-reporting/.license.accepted")
886
- if @config['chef-server'][:frontends].include?(server.name)
887
- puts "Copying /etc/opscode-reporting from bootstrap backend '#{@config['chef-server'][:bootstrap_backend]}'"
888
- FileUtils.cp_r("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode-reporting",
889
- "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
890
- end
891
- server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
892
- server.run_command("opscode-reporting-ctl reconfigure")
893
- end
894
-
895
- def configure_push_jobs_server(server)
896
- server.run_command("opscode-push-jobs-server-ctl reconfigure")
897
- server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
898
- end
899
-
900
- def configure_manage(server)
901
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-manage")
902
- FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-manage/.license.accepted")
903
- if @server_configs[server.name][:chef_server_type] == 'private-chef'
904
- puts "Disabling old opscode-webui in /etc/opscode/private-chef.rb"
905
- DevLXC.search_file_delete_line("#{server.container.config_item('lxc.rootfs')}/etc/opscode/private-chef.rb", /opscode_webui[.enable.]/)
906
- DevLXC.append_line_to_file("#{server.container.config_item('lxc.rootfs')}/etc/opscode/private-chef.rb", "\nopscode_webui['enable'] = false\n")
907
- server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
908
- end
909
- server.run_command("opscode-manage-ctl reconfigure")
910
- end
911
-
912
- def configure_analytics(server)
913
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-analytics")
914
- FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-analytics/.license.accepted")
915
- if @config['analytics'][:topology] == "standalone" || @config['analytics'][:bootstrap_backend] == server.name
916
- puts "Copying /etc/opscode-analytics from Chef Server bootstrap backend '#{@config['chef-server'][:bootstrap_backend]}'"
917
- FileUtils.cp_r("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode-analytics",
918
- "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
919
-
920
- IO.write("#{server.container.config_item('lxc.rootfs')}/etc/opscode-analytics/opscode-analytics.rb", analytics_config)
921
- elsif @config['analytics'][:frontends].include?(server.name)
922
- puts "Copying /etc/opscode-analytics from Analytics bootstrap backend '#{@config['analytics'][:bootstrap_backend]}'"
923
- FileUtils.cp_r("#{get_server(@config['analytics'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode-analytics",
924
- "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
925
- end
926
- server.run_command("opscode-analytics-ctl reconfigure")
927
- end
928
-
929
- def configure_compliance(server)
930
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-compliance")
931
- FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-compliance/.license.accepted")
932
- server.run_command("chef-compliance-ctl reconfigure")
933
- admin_user = @server_configs[server.name][:admin_user]
934
- if admin_user
935
- server.run_command("chef-compliance-ctl user-create #{admin_user} #{admin_user}")
936
- server.run_command("chef-compliance-ctl restart core")
937
- end
938
-
939
- if @config["chef-server"][:topology] == "standalone"
940
- chef_server = get_server(@config['chef-server'][:bootstrap_backend])
941
- FileUtils.mkdir_p("#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server")
942
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server")
943
- IO.write("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/prepare-chef-compliance",
944
- "chef-compliance-ctl connect chef-server --non-interactive true --chef-app-id 'compliance_server' --auth-id 'Chef Server' --insecure true --compliance-url 'https://#{server.name}'"
945
- )
946
- server.run_command("bash /root/integrate-compliance-with-chef-server/prepare-chef-compliance", "#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/prepare-chef-compliance-output")
947
- server.run_command("chef-compliance-ctl reconfigure")
948
- server.run_command("chef-compliance-ctl restart core")
949
- prepare_chef_compliance_output = IO.read("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/prepare-chef-compliance-output")
950
- delimited_chef_server_command = prepare_chef_compliance_output.match(/\n---\n(.+)\n---/m)
951
- if delimited_chef_server_command
952
- IO.write("#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-server", delimited_chef_server_command[1])
953
- chef_server.run_command("bash /root/integrate-compliance-with-chef-server/configure-chef-server", "#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-server-output")
954
- end
955
- configure_chef_server_output = IO.read("#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-server-output")
956
- compliance_command = configure_chef_server_output.match(/^chef-compliance-ctl .+$/)
957
- if compliance_command
958
- IO.write("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-compliance", compliance_command)
959
- server.run_command("bash /root/integrate-compliance-with-chef-server/configure-chef-compliance")
960
- server.run_command("chef-compliance-ctl reconfigure")
961
- end
962
- end
963
- end
964
-
965
- def configure_supermarket(server)
966
- if @config['chef-server'][:bootstrap_backend] && get_server(@config['chef-server'][:bootstrap_backend]).container.defined?
967
- chef_server_supermarket_config = JSON.parse(IO.read("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode/oc-id-applications/supermarket.json"))
968
- supermarket_config = {
969
- 'chef_server_url' => "https://#{@config['chef-server'][:fqdn]}/",
970
- 'chef_oauth2_app_id' => chef_server_supermarket_config['uid'],
971
- 'chef_oauth2_secret' => chef_server_supermarket_config['secret'],
972
- 'chef_oauth2_verify_ssl' => false
973
- }
974
- FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/supermarket")
975
- IO.write("#{server.container.config_item('lxc.rootfs')}/etc/supermarket/supermarket.json", JSON.pretty_generate(supermarket_config))
976
- end
977
- server.run_command("supermarket-ctl reconfigure")
978
- end
979
-
980
- def create_users_orgs_knife_configs(server, dot_chef_path)
981
- server_type = @server_configs[server.name][:server_type]
982
- # give time for all services to come up completely
983
- sleep 10
984
- if @server_configs[server.name][:chef_server_type] == 'private-chef'
985
- # give more time for all services to come up completely
986
- sleep 50
987
- server.run_command("/opt/opscode/embedded/bin/gem install knife-opc --no-ri --no-rdoc -v 0.3.1")
988
- end
989
- chef_server_dot_chef_path = "#{server.container.config_item('lxc.rootfs')}#{dot_chef_path}"
990
- FileUtils.mkdir_p(chef_server_dot_chef_path)
991
- FileUtils.cp( "#{server.container.config_item('lxc.rootfs')}/etc/opscode/pivotal.pem", chef_server_dot_chef_path )
992
- create_pivotal_knife_config('127.0.0.1', chef_server_dot_chef_path)
993
- create_knife_config('127.0.0.1', chef_server_dot_chef_path)
994
- @config[server_type][:users].each do |username|
995
- create_user(server, username, dot_chef_path)
996
- end
997
- @config[server_type][:orgs].each do |orgname, org_users|
998
- create_org(server, orgname, dot_chef_path)
999
- if org_users
1000
- if org_users['admins']
1001
- org_users['admins'].each do |username|
1002
- org_add_user(server, orgname, username, true, dot_chef_path)
1003
- end
1004
- end
1005
- if org_users['non-admins']
1006
- org_users['non-admins'].each do |username|
1007
- org_add_user(server, orgname, username, false, dot_chef_path)
1008
- end
1009
- end
1010
- end
1011
- end
1012
- end
1013
-
1014
- def create_pivotal_knife_config(fqdn, dot_chef_path)
1015
- pivotal_rb = %Q(
1016
- current_dir = File.dirname(__FILE__)
1017
-
1018
- chef_server_root "https://#{fqdn}"
1019
- chef_server_url "https://#{fqdn}"
1020
-
1021
- node_name "pivotal"
1022
- client_key "\#{current_dir}/pivotal.pem"
1023
-
1024
- cookbook_path Dir.pwd + "/cookbooks"
1025
- knife[:chef_repo_path] = Dir.pwd
1026
-
1027
- ssl_verify_mode :verify_none
1028
- )
1029
- IO.write("#{dot_chef_path}/pivotal.rb", pivotal_rb)
1030
- end
1031
-
1032
- def create_knife_config(fqdn, dot_chef_path)
1033
- knife_rb = %Q(#http_proxy 'http://127.0.0.1:8080'
1034
- #https_proxy 'http://127.0.0.1:8080'
1035
-
1036
- username = "CHANGEME"
1037
- orgname = "CHANGEME"
1038
-
1039
- if [username, orgname].include?("CHANGEME")
1040
- puts "ERROR: Please set 'username' and 'orgname' to proper values in knife.rb"
1041
- exit!
1042
- end
1043
-
1044
- current_dir = File.dirname(__FILE__)
1045
-
1046
- chef_server_url "https://#{fqdn}/organizations/\#{orgname}"
1047
-
1048
- node_name username
1049
- client_key "\#{current_dir}/\#{username}.pem"
1050
-
1051
- validation_client_name "\#{orgname}-validator"
1052
- validation_key "\#{current_dir}/\#{orgname}-validator.pem"
1053
-
1054
- cookbook_path Dir.pwd + "/cookbooks"
1055
- knife[:chef_repo_path] = Dir.pwd
1056
-
1057
- ssl_verify_mode :verify_none
1058
- )
1059
- IO.write("#{dot_chef_path}/knife.rb", knife_rb)
1060
- end
1061
-
1062
- def create_user(server, username, dot_chef_path)
1063
- create_user_string = "#{username} #{username} #{username} #{username}@noreply.com #{username} --filename #{dot_chef_path}/#{username}.pem"
1064
- case @server_configs[server.name][:chef_server_type]
1065
- when 'private-chef'
1066
- server.run_command("/opt/opscode/embedded/bin/knife opc user create #{create_user_string} -c #{dot_chef_path}/pivotal.rb")
1067
- when 'chef-server'
1068
- server.run_command("chef-server-ctl user-create #{create_user_string}")
1069
- end
1070
- end
1071
-
1072
- def create_org(server, orgname, dot_chef_path)
1073
- create_org_string = "#{orgname} #{orgname} --filename #{dot_chef_path}/#{orgname}-validator.pem"
1074
- case @server_configs[server.name][:chef_server_type]
1075
- when 'private-chef'
1076
- server.run_command("/opt/opscode/embedded/bin/knife opc org create #{create_org_string} -c #{dot_chef_path}/pivotal.rb")
1077
- when 'chef-server'
1078
- server.run_command("chef-server-ctl org-create #{create_org_string}")
1079
- end
1080
- end
1081
-
1082
- def org_add_user(server, orgname, username, admin, dot_chef_path)
1083
- org_add_user_string = "#{orgname} #{username}"
1084
- org_add_user_string += " --admin" if admin
1085
- case @server_configs[server.name][:chef_server_type]
1086
- when 'private-chef'
1087
- server.run_command("/opt/opscode/embedded/bin/knife opc org user add #{org_add_user_string} -c #{dot_chef_path}/pivotal.rb")
1088
- when 'chef-server'
1089
- server.run_command("chef-server-ctl org-user-add #{org_add_user_string}")
1090
- end
1091
- end
1092
-
1093
- def chef_repo(force=false, pivotal=false)
1094
- chef_server_dot_chef_path = "/root/chef-repo/.chef"
1095
- dot_chef_path = "./chef-repo/.chef"
1096
-
1097
- if @config['chef-server'][:bootstrap_backend]
1098
- chef_server = get_server(@config['chef-server'][:bootstrap_backend])
1099
- chef_server_fqdn = @config['chef-server'][:fqdn]
1100
- elsif @config['chef-backend'][:bootstrap_frontend]
1101
- chef_server = get_server(@config['chef-backend'][:bootstrap_frontend])
1102
- chef_server_fqdn = @config['chef-backend'][:fqdn]
1103
- else
1104
- puts "ERROR: A Chef Server is not defined in the cluster's config. Please define it first."
1105
- exit 1
1106
- end
1107
- unless chef_server.container.defined?
1108
- puts "ERROR: The '#{chef_server.name}' Chef Server does not exist."
1109
- exit 1
1110
- end
1111
-
1112
- puts "Creating chef-repo with pem files and knife.rb in the current directory"
1113
- FileUtils.mkdir_p(dot_chef_path)
1114
-
1115
- pem_files = Dir.glob("#{chef_server.container.config_item('lxc.rootfs')}#{chef_server_dot_chef_path}/*.pem")
1116
- pem_files.delete_if { |pem_file| pem_file.end_with?("/pivotal.pem") } unless pivotal
1117
- FileUtils.cp(pem_files, dot_chef_path) unless pem_files.empty?
1118
-
1119
- if pivotal
1120
- if File.exists?("#{dot_chef_path}/pivotal.rb") && ! force
1121
- puts "Skipping pivotal.rb because it already exists in `#{dot_chef_path}`"
1122
- else
1123
- create_pivotal_knife_config(chef_server_fqdn, dot_chef_path)
1124
- end
1125
- end
1126
-
1127
- if File.exists?("./chef-repo/.chef/knife.rb") && ! force
1128
- puts "Skipping knife.rb because it already exists in `#{dot_chef_path}`"
1129
- else
1130
- create_knife_config(chef_server_fqdn, dot_chef_path)
1131
- end
1132
- end
1133
-
1134
- def chef_server_config
1135
- chef_server_config = %Q(api_fqdn "#{@config['chef-server'][:fqdn]}"\n)
1136
- if @config['chef-server'][:topology] == 'tier'
1137
- chef_server_config += %Q(
1138
- topology "#{@config['chef-server'][:topology]}"
1139
-
1140
- server "#{@config['chef-server'][:bootstrap_backend]}",
1141
- :ipaddress => "#{@server_configs[@config['chef-server'][:bootstrap_backend]][:ipaddress]}",
1142
- :role => "backend",
1143
- :bootstrap => true
1144
-
1145
- backend_vip "#{@config['chef-server'][:bootstrap_backend]}",
1146
- :ipaddress => "#{@server_configs[@config['chef-server'][:bootstrap_backend]][:ipaddress]}"
1147
- )
1148
- @config['chef-server'][:frontends].each do |frontend_name|
1149
- chef_server_config += %Q(
1150
- server "#{frontend_name}",
1151
- :ipaddress => "#{@server_configs[frontend_name][:ipaddress]}",
1152
- :role => "frontend"
1153
- )
1154
- end
1155
- end
1156
- if @config['analytics'][:fqdn]
1157
- chef_server_config += %Q(
1158
- oc_id['applications'] ||= {}
1159
- oc_id['applications']['analytics'] = {
1160
- 'redirect_uri' => 'https://#{@config['analytics'][:fqdn]}/'
1161
- }
1162
- rabbitmq['vip'] = '#{@config['chef-server'][:bootstrap_backend]}'
1163
- rabbitmq['node_ip_address'] = '0.0.0.0'
1164
- )
1165
- end
1166
- if @config['supermarket'][:fqdn]
1167
- chef_server_config += %Q(
1168
- oc_id['applications'] ||= {}
1169
- oc_id['applications']['supermarket'] = {
1170
- 'redirect_uri' => 'https://#{@config['supermarket'][:fqdn]}/auth/chef_oauth2/callback'
1171
- }
1172
- )
1173
- end
1174
- automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
1175
- if automate_server_name
1176
- chef_server_config += %Q(
1177
- data_collector['root_url'] = "https://#{automate_server_name}/data-collector/v0/"
1178
- data_collector['token'] = "93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506"
1179
- profiles['root_url'] = "https://#{automate_server_name}"
1180
- )
1181
- end
1182
- return chef_server_config
1183
- end
1184
-
1185
- def analytics_config
1186
- analytics_config = %Q(analytics_fqdn "#{@config['analytics'][:fqdn]}"
1187
- topology "#{@config['analytics'][:topology]}"
1188
- )
1189
- if @config['analytics'][:topology] == 'tier'
1190
- analytics_config += %Q(
1191
- server "#{@config['analytics'][:bootstrap_backend]}",
1192
- :ipaddress => "#{@server_configs[@config['analytics'][:bootstrap_backend]][:ipaddress]}",
1193
- :role => "backend",
1194
- :bootstrap => true
1195
-
1196
- backend_vip "#{@config['analytics'][:bootstrap_backend]}",
1197
- :ipaddress => "#{@server_configs[@config['analytics'][:bootstrap_backend]][:ipaddress]}"
1198
- )
1199
- @config['analytics'][:frontends].each do |frontend_name|
1200
- analytics_config += %Q(
1201
- server "#{frontend_name}",
1202
- :ipaddress => "#{@server_configs[frontend_name][:ipaddress]}",
1203
- :role => "frontend"
1204
- )
1205
- end
1206
- end
1207
- return analytics_config
1208
- end
1209
-
1210
- end
1211
- end
1
+ require "dev-lxc/server"
2
+ require "mixlib/install"
3
+ require "open-uri"
4
+
5
+ module DevLXC
6
+ class Cluster
7
+ attr_reader :config
8
+
9
+ def initialize(cluster_config)
10
+ FileUtils.mkdir_p('/var/dev-lxc') unless Dir.exist?('/var/dev-lxc')
11
+
12
+ @config = Hash.new { |hash, key| hash[key] = {} }
13
+ @server_configs = Hash.new
14
+
15
+ %w(adhoc analytics automate build-nodes chef-backend chef-server compliance nodes runners supermarket).each do |server_type|
16
+ if cluster_config[server_type]
17
+ if cluster_config[server_type]["servers"]
18
+ cluster_config[server_type]["servers"].each do |server_name, server_config|
19
+ server_config ||= Hash.new
20
+
21
+ products = server_config['products']
22
+ products ||= Hash.new
23
+
24
+ enable_build_snapshots = cluster_config[server_type]["enable_build_snapshots"]
25
+ enable_build_snapshots = cluster_config["enable_build_snapshots"] if enable_build_snapshots.nil?
26
+ enable_build_snapshots = server_config["enable_build_snapshots"] if server_config.key?("enable_build_snapshots")
27
+ enable_build_snapshots = true if enable_build_snapshots.nil?
28
+
29
+ memory_per_server = cluster_config[server_type]["memory_per_server"]
30
+ memory_per_server ||= cluster_config["memory_per_server"]
31
+ memory_per_server = server_config["memory_per_server"] if server_config["memory_per_server"]
32
+
33
+ mounts = ["/var/dev-lxc var/dev-lxc"]
34
+ if cluster_config[server_type]["mounts"]
35
+ mounts.concat(cluster_config[server_type]["mounts"])
36
+ elsif cluster_config["mounts"]
37
+ mounts.concat(cluster_config["mounts"])
38
+ end
39
+ mounts = ["/var/dev-lxc var/dev-lxc"] + server_config["mounts"] if server_config["mounts"]
40
+
41
+ ssh_keys = cluster_config[server_type]["ssh-keys"]
42
+ ssh_keys ||= cluster_config["ssh-keys"]
43
+ ssh_keys = server_config["ssh-keys"] if server_config["ssh-keys"]
44
+
45
+ base_container_name = cluster_config[server_type]["base_container"]
46
+ base_container_name ||= cluster_config["base_container"]
47
+ base_container_name = server_config["base_container"] if server_config["base_container"]
48
+
49
+ @server_configs[server_name] = {
50
+ server_type: server_type,
51
+ products: products,
52
+ ipaddress: server_config['ipaddress'],
53
+ additional_fqdn: nil,
54
+ enable_build_snapshots: enable_build_snapshots,
55
+ first_run: false,
56
+ memory_per_server: memory_per_server,
57
+ mounts: mounts,
58
+ ssh_keys: ssh_keys,
59
+ base_container_name: base_container_name
60
+ }
61
+ # gather configuration from only the first "automate", "compliance" or "supermarket" server
62
+ break if %w(automate compliance supermarket).include?(server_type)
63
+ end
64
+ end
65
+
66
+ case server_type
67
+ when "analytics"
68
+ @config[server_type][:topology] = cluster_config[server_type]["topology"]
69
+ @config[server_type][:topology] ||= 'standalone'
70
+ @config[server_type][:fqdn] = cluster_config[server_type]["analytics_fqdn"]
71
+ @config[server_type][:frontends] = Array.new
72
+
73
+ if cluster_config[server_type]["servers"]
74
+ cluster_config[server_type]["servers"].each do |server_name, server_config|
75
+ server_config ||= Hash.new
76
+ additional_fqdn = nil
77
+ case @config[server_type][:topology]
78
+ when 'standalone'
79
+ @config[server_type][:bootstrap_backend] = server_name if server_config["role"].nil?
80
+ @config[server_type][:fqdn] ||= @config[server_type][:bootstrap_backend]
81
+ when 'tier'
82
+ @config[server_type][:bootstrap_backend] = server_name if server_config["role"] == "backend" && server_config["bootstrap"] == true
83
+ if server_config["role"] == "frontend"
84
+ additional_fqdn = @config[server_type][:fqdn]
85
+ @config[server_type][:frontends] << server_name
86
+ end
87
+ end
88
+ @server_configs[server_name].merge!({
89
+ additional_fqdn: additional_fqdn
90
+ })
91
+ end
92
+ end
93
+ when "chef-backend"
94
+ @config[server_type][:fqdn] = cluster_config[server_type]["api_fqdn"]
95
+ @config[server_type][:users] = cluster_config[server_type]["users"]
96
+ @config[server_type][:users] ||= Array.new
97
+ @config[server_type][:orgs] = cluster_config[server_type]["orgs"]
98
+ @config[server_type][:orgs] ||= Hash.new
99
+ @config[server_type][:backends] = Array.new
100
+ @config[server_type][:frontends] = Array.new
101
+
102
+ servers = cluster_config[server_type]["servers"]
103
+ if servers
104
+ @config[server_type][:leader_backend] = servers.select { |s,sc| sc['role'] == 'backend' && sc['leader'] == true }.keys.first
105
+ @config[server_type][:bootstrap_frontend] = servers.select { |s,sc| sc['role'] == 'frontend' && sc['bootstrap'] == true }.keys.first
106
+ @config[server_type][:backends] << @config[server_type][:leader_backend]
107
+ @config[server_type][:frontends] << @config[server_type][:bootstrap_frontend]
108
+ servers.each do |server_name, server_config|
109
+ server_config ||= Hash.new
110
+ additional_fqdn = nil
111
+ case server_config["role"]
112
+ when "backend"
113
+ @config[server_type][:backends] << server_name unless server_name == @config[server_type][:leader_backend]
114
+ when "frontend"
115
+ additional_fqdn = @config[server_type][:fqdn]
116
+ @config[server_type][:frontends] << server_name unless server_name == @config[server_type][:bootstrap_frontend]
117
+ end
118
+ @server_configs[server_name].merge!({
119
+ additional_fqdn: additional_fqdn,
120
+ chef_server_type: 'chef-server'
121
+ })
122
+ end
123
+ end
124
+ when "chef-server"
125
+ @config[server_type][:topology] = cluster_config[server_type]["topology"]
126
+ @config[server_type][:topology] ||= 'standalone'
127
+ @config[server_type][:fqdn] = cluster_config[server_type]["api_fqdn"]
128
+ @config[server_type][:users] = cluster_config[server_type]["users"]
129
+ @config[server_type][:users] ||= Array.new
130
+ @config[server_type][:orgs] = cluster_config[server_type]["orgs"]
131
+ @config[server_type][:orgs] ||= Hash.new
132
+ @config[server_type][:frontends] = Array.new
133
+
134
+ if cluster_config[server_type]["servers"]
135
+ cluster_config[server_type]["servers"].each do |server_name, server_config|
136
+ server_config ||= Hash.new
137
+ additional_fqdn = nil
138
+ chef_server_type = 'private-chef' if @server_configs[server_name][:products].has_key?('private-chef')
139
+ chef_server_type = 'chef-server' if @server_configs[server_name][:products].has_key?('chef-server')
140
+ case @config[server_type][:topology]
141
+ when 'standalone'
142
+ @config[server_type][:bootstrap_backend] = server_name if server_config["role"].nil?
143
+ @config[server_type][:fqdn] ||= @config[server_type][:bootstrap_backend]
144
+ when 'tier'
145
+ @config[server_type][:bootstrap_backend] = server_name if server_config["role"] == "backend" && server_config["bootstrap"] == true
146
+ if server_config["role"] == "frontend"
147
+ additional_fqdn = @config[server_type][:fqdn]
148
+ @config[server_type][:frontends] << server_name
149
+ end
150
+ end
151
+ @server_configs[server_name].merge!({
152
+ additional_fqdn: additional_fqdn,
153
+ chef_server_type: chef_server_type
154
+ })
155
+ end
156
+ end
157
+ when "supermarket"
158
+ unless cluster_config[server_type]["servers"].first.nil?
159
+ (server_name, server_config) = cluster_config[server_type]["servers"].first
160
+ @config[server_type][:fqdn] = server_name
161
+ end
162
+ when "compliance"
163
+ unless cluster_config[server_type]["servers"].first.nil?
164
+ (server_name, server_config) = cluster_config[server_type]["servers"].first
165
+ @server_configs[server_name][:admin_user] = cluster_config[server_type]["admin_user"]
166
+ end
167
+ when "automate"
168
+ unless cluster_config[server_type]["servers"].first.nil?
169
+ (server_name, server_config) = cluster_config[server_type]["servers"].first
170
+ server_config ||= Hash.new
171
+ @server_configs[server_name].merge!({
172
+ license_path: server_config['license_path'],
173
+ chef_org: server_config['chef_org'],
174
+ enterprise_name: server_config['enterprise_name']
175
+ })
176
+ end
177
+ when "nodes"
178
+ chef_server_url = cluster_config[server_type]['chef_server_url']
179
+ validation_client_name = cluster_config[server_type]['validation_client_name']
180
+ validation_key = cluster_config[server_type]['validation_key']
181
+ if cluster_config[server_type]["servers"]
182
+ cluster_config[server_type]["servers"].each do |server_name, server_config|
183
+ server_config ||= Hash.new
184
+ chef_server_url = server_config['chef_server_url'] if server_config['chef_server_url']
185
+ validation_client_name = server_config['validation_client_name'] if server_config['validation_client_name']
186
+ validation_key = server_config['validation_key'] if server_config['validation_key']
187
+ @server_configs[server_name].merge!({
188
+ chef_server_url: chef_server_url,
189
+ validation_client_name: validation_client_name,
190
+ validation_key: validation_key
191
+ })
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+ validate_cluster_config
198
+ end
199
+
200
+ def validate_cluster_config
201
+ base_container_names = Array.new
202
+ mounts = Array.new
203
+ ssh_keys = Array.new
204
+ hostnames = Array.new
205
+
206
+ @config.map { |server_type, config| hostnames.push(config[:fqdn]) }
207
+
208
+ @server_configs.each do |server_name, server_config|
209
+ base_container_names.push(server_config[:base_container_name]).uniq! if server_config[:base_container_name]
210
+ mounts.concat(server_config[:mounts]).uniq! if server_config[:mounts]
211
+ ssh_keys.concat(server_config[:ssh_keys]).uniq! if server_config[:ssh_keys]
212
+ hostnames.push(server_name)
213
+ case server_config[:server_type]
214
+ when "automate"
215
+ if server_config[:license_path] && !File.file?(server_config[:license_path])
216
+ puts "ERROR: Automate license #{server_config[:license_path]} does not exist or is not a file."
217
+ exit 1
218
+ end
219
+ when "nodes"
220
+ if server_config[:validation_key] && !File.file?(server_config[:validation_key])
221
+ puts "ERROR: Validation key #{server_config[:validation_key]} does not exist or is not a file."
222
+ exit 1
223
+ end
224
+ end
225
+ end
226
+
227
+ unless base_container_names.empty?
228
+ base_container_names.each do |base_container_name|
229
+ unless ::DevLXC::Container.new(base_container_name).defined?
230
+ puts "ERROR: Base container #{base_container_name} does not exist."
231
+ exit 1
232
+ end
233
+ end
234
+ end
235
+ unless hostnames.empty?
236
+ hostnames.each do |hostname|
237
+ unless hostname.end_with?(".lxc")
238
+ puts "ERROR: Hostname #{hostname} does not end with '.lxc'."
239
+ exit 1
240
+ end
241
+ end
242
+ end
243
+ unless mounts.empty?
244
+ mounts.each do |mount|
245
+ unless File.exists?(mount.split.first)
246
+ puts "ERROR: Mount source #{mount.split.first} does not exist."
247
+ exit 1
248
+ end
249
+ end
250
+ end
251
+ unless ssh_keys.empty?
252
+ ssh_keys.each do |ssh_key|
253
+ unless File.exists?(ssh_key)
254
+ puts "ERROR: SSH key #{ssh_key} does not exist."
255
+ exit 1
256
+ end
257
+ end
258
+ end
259
+ end
260
+
261
+ def show_config(include_products=false)
262
+ require 'pp'
263
+ calculate_required_products(get_sorted_servers, true) if include_products
264
+ puts "Cluster config:"
265
+ pp @config
266
+ puts
267
+ puts "Server configs:"
268
+ pp @server_configs
269
+ end
270
+
271
+ def get_server(server_name)
272
+ ipaddress = @server_configs[server_name][:ipaddress]
273
+ additional_fqdn = @server_configs[server_name][:additional_fqdn]
274
+ memory_per_server = @server_configs[server_name][:memory_per_server]
275
+ mounts = @server_configs[server_name][:mounts]
276
+ ssh_keys = @server_configs[server_name][:ssh_keys]
277
+ Server.new(server_name, ipaddress, additional_fqdn, memory_per_server, mounts, ssh_keys)
278
+ end
279
+
280
+ def get_sorted_servers(server_name_regex=nil)
281
+ servers = Array.new
282
+
283
+ # the order of this list of server_types matters
284
+ # it determines the order in which actions are applied to each server_type
285
+ %w(chef-backend chef-server analytics compliance supermarket automate build-nodes runners nodes adhoc).each do |server_type|
286
+ unless @config[server_type].empty?
287
+ case server_type
288
+ when "chef-backend"
289
+ @config[server_type][:backends].each do |backend_name|
290
+ servers << get_server(backend_name)
291
+ end
292
+ @config[server_type][:frontends].each do |frontend_name|
293
+ servers << get_server(frontend_name)
294
+ end
295
+ when "analytics", "chef-server"
296
+ if @config[server_type][:bootstrap_backend]
297
+ server_name = @config[server_type][:bootstrap_backend]
298
+ servers << get_server(server_name)
299
+ end
300
+ @config[server_type][:frontends].each do |frontend_name|
301
+ servers << get_server(frontend_name)
302
+ end
303
+ end
304
+ end
305
+ if %w(adhoc automate build-nodes compliance nodes runners supermarket).include?(server_type)
306
+ server_configs = @server_configs.select { |server_name, server_config| server_config[:server_type] == server_type }
307
+ server_configs.each_key { |server_name| servers << get_server(server_name) }
308
+ end
309
+ end
310
+ servers.select { |s| s.name =~ /#{server_name_regex}/ }
311
+ end
312
+
313
+ def destroy(server_name_regex=nil)
314
+ servers = get_sorted_servers(server_name_regex)
315
+ servers.reverse_each { |s| s.destroy; puts }
316
+ delete_dns_records unless get_sorted_servers.any? { |s| s.container.state != :stopped }
317
+ end
318
+
319
+ def halt(server_name_regex=nil)
320
+ servers = get_sorted_servers(server_name_regex)
321
+ servers.reverse_each { |s| s.shutdown; puts }
322
+ delete_dns_records unless get_sorted_servers.any? { |s| s.container.state != :stopped }
323
+ end
324
+
325
+ def delete_dns_records
326
+ @server_configs.keys.each { |server_name| DevLXC::search_file_delete_line("/etc/lxc/addn-hosts.conf", /\s#{server_name}/) }
327
+ DevLXC::reload_dnsmasq
328
+ end
329
+
330
+ def up(server_name_regex=nil)
331
+ configured_servers = Array.new
332
+ servers = get_sorted_servers(server_name_regex)
333
+ exit 1 if abort_up(servers)
334
+ servers.each do |server|
335
+ unless server.container.defined?
336
+ clone_from_base_container(server)
337
+ @server_configs[server.name][:first_run] = true
338
+ end
339
+ end
340
+ prep_product_cache(servers)
341
+ # get_sorted_servers is called again in order to ensure the container objects are initialized properly in case they were just cloned from the base container
342
+ servers = get_sorted_servers(server_name_regex)
343
+ create_dns_records unless servers.empty?
344
+ servers.each do |server|
345
+ next if ! @server_configs[server.name][:enable_build_snapshots] && ! @server_configs[server.name][:first_run]
346
+ if %w(build-nodes runners).include?(@server_configs[server.name][:server_type])
347
+ next if @server_configs[server.name][:required_products]["chefdk"] && @server_configs[server.name][:required_products].length == 1
348
+ end
349
+ install_products(server) unless @server_configs[server.name][:required_products].empty?
350
+ end
351
+ servers.each do |server|
352
+ if server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
353
+ if server.name == @config["chef-backend"][:bootstrap_frontend]
354
+ running_backends = Array.new
355
+ @config["chef-backend"][:backends].reverse_each do |server_name|
356
+ next unless @server_configs[server_name][:enable_build_snapshots]
357
+ backend = get_server(server_name)
358
+ if backend.container.defined? && backend.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: backend cluster configured but frontend not bootstrapped") }.empty?
359
+ if backend.container.running?
360
+ running_backends << backend.name
361
+ backend.shutdown
362
+ end
363
+ backend.snapshot("dev-lxc build: backend cluster configured but frontend not bootstrapped")
364
+ snapshot = backend.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.first
365
+ backend.snapshot_destroy(snapshot.first) if snapshot
366
+ end
367
+ end
368
+ @config["chef-backend"][:backends].each do |server_name|
369
+ next unless @server_configs[server_name][:enable_build_snapshots]
370
+ if running_backends.include?(server_name)
371
+ get_server(server_name).start
372
+ configured_servers << server_name unless configured_servers.include?(server_name)
373
+ end
374
+ end
375
+ end
376
+ if @server_configs[server.name][:enable_build_snapshots] || @server_configs[server.name][:first_run]
377
+ configure_products(server)
378
+ configured_servers << server.name
379
+ end
380
+ end
381
+ if server.container.running?
382
+ puts "Container '#{server.name}' is already running"
383
+ puts
384
+ else
385
+ server.start
386
+ end
387
+ end
388
+ configured_servers.reverse_each do |server_name|
389
+ next unless @server_configs[server_name][:enable_build_snapshots]
390
+ server = get_server(server_name)
391
+ server.shutdown if server.container.running?
392
+ server.snapshot("dev-lxc build: completed")
393
+ end
394
+ configured_servers.each do |server_name|
395
+ next unless @server_configs[server_name][:enable_build_snapshots]
396
+ server = get_server(server_name)
397
+ server.start if server.container.defined?
398
+ end
399
+ end
400
+
401
+ def abort_up(servers)
402
+ abort_up = false
403
+ servers.each do |server|
404
+ next if server.container.defined? && !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
405
+ next if ! @server_configs[server.name][:enable_build_snapshots] && ! @server_configs[server.name][:first_run]
406
+ if @server_configs[server.name][:server_type] == 'compliance' && @config["chef-server"][:topology] == "standalone"
407
+ if @config['chef-server'][:bootstrap_backend].nil?
408
+ puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
409
+ abort_up = true
410
+ elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.running? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
411
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be running first."
412
+ abort_up = true
413
+ end
414
+ end
415
+ if (@config['chef-server'][:frontends] && @config['chef-server'][:frontends].include?(server.name)) || server.name == @config['analytics'][:bootstrap_backend]
416
+ if @config['chef-server'][:bootstrap_backend].nil?
417
+ puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
418
+ abort_up = true
419
+ elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
420
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
421
+ abort_up = true
422
+ end
423
+ end
424
+ if @config['chef-server'][:bootstrap_backend] && @server_configs[server.name][:server_type] == 'supermarket'
425
+ if !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
426
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
427
+ abort_up = true
428
+ end
429
+ end
430
+ if @config['analytics'][:frontends] && @config['analytics'][:frontends].include?(server.name)
431
+ if @config['analytics'][:bootstrap_backend].nil?
432
+ puts "ERROR: '#{server.name}' requires an Analytics Server bootstrap backend to be configured first."
433
+ abort_up = true
434
+ elsif !get_server(@config['analytics'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['analytics'][:bootstrap_backend] }.empty?
435
+ puts "ERROR: '#{server.name}' requires '#{@config['analytics'][:bootstrap_backend]}' to be configured first."
436
+ abort_up = true
437
+ end
438
+ end
439
+ if @config['chef-backend'][:frontends] && @config['chef-backend'][:frontends].include?(server.name) && server.name != @config['chef-backend'][:bootstrap_frontend]
440
+ if @config['chef-backend'][:bootstrap_frontend].nil?
441
+ puts "ERROR: '#{server.name}' requires a Chef Server bootstrap frontend to be configured first."
442
+ abort_up = true
443
+ elsif !get_server(@config['chef-backend'][:bootstrap_frontend]).container.defined? && servers.select { |s| s.name == @config['chef-backend'][:bootstrap_frontend] }.empty?
444
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-backend'][:bootstrap_frontend]}' to be configured first."
445
+ abort_up = true
446
+ end
447
+ end
448
+ if server.name == @config['chef-backend'][:bootstrap_frontend]
449
+ if (@config['chef-backend'][:backends].select { |s| get_server(s).container.running? }.length + servers.select { |s| @config['chef-backend'][:backends].include?(s.name) }.length) < 2
450
+ puts "ERROR: '#{server.name}' requires at least two nodes in the backend cluster to be running first."
451
+ abort_up = true
452
+ end
453
+ end
454
+ if @config['chef-backend'][:backends] && @config['chef-backend'][:backends].include?(server.name) && server.name != @config['chef-backend'][:leader_backend]
455
+ if !get_server(@config['chef-backend'][:leader_backend]).container.running? && servers.select { |s| s.name == @config['chef-backend'][:leader_backend] }.empty?
456
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-backend'][:leader_backend]}' to be running first."
457
+ abort_up = true
458
+ end
459
+ end
460
+ if @server_configs[server.name][:server_type] == 'nodes'
461
+ if @server_configs[server.name][:chef_server_url] && @server_configs[server.name][:validation_client_name] && @server_configs[server.name][:validation_key].nil?
462
+ if @config['chef-server'][:bootstrap_backend] && !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
463
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
464
+ abort_up = true
465
+ elsif @config['chef-backend'][:bootstrap_frontend] && !get_server(@config['chef-backend'][:bootstrap_frontend]).container.defined? && servers.select { |s| s.name == @config['chef-backend'][:bootstrap_frontend] }.empty?
466
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-backend'][:bootstrap_frontend]}' to be configured first."
467
+ abort_up = true
468
+ end
469
+ end
470
+ end
471
+ if @server_configs[server.name][:server_type] == 'automate'
472
+ if @config['chef-server'][:bootstrap_backend].nil?
473
+ puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
474
+ abort_up = true
475
+ elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.defined? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
476
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be configured first."
477
+ abort_up = true
478
+ end
479
+ end
480
+ if %w(build-nodes runners).include?(@server_configs[server.name][:server_type])
481
+ if @config['chef-server'][:bootstrap_backend].nil?
482
+ puts "ERROR: '#{server.name}' requires a Chef Server bootstrap backend to be configured first."
483
+ abort_up = true
484
+ elsif !get_server(@config['chef-server'][:bootstrap_backend]).container.running? && servers.select { |s| s.name == @config['chef-server'][:bootstrap_backend] }.empty?
485
+ puts "ERROR: '#{server.name}' requires '#{@config['chef-server'][:bootstrap_backend]}' to be running first."
486
+ abort_up = true
487
+ end
488
+ if @config['chef-server'][:topology] == 'tier'
489
+ if @config[server_type][:frontends].empty?
490
+ puts "ERROR: '#{server.name}' requires at least one Chef Server frontend to be configured first."
491
+ abort_up = true
492
+ elsif (@config['chef-server'][:frontends].select { |s| get_server(s).container.running? }.length + servers.select { |s| @config['chef-server'][:frontends].include?(s.name) }.length) < 1
493
+ puts "ERROR: '#{server.name}' requires at least one Chef Server frontend to be running first."
494
+ abort_up = true
495
+ end
496
+ end
497
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
498
+ if automate_server_name
499
+ if !get_server(automate_server_name).container.running? && servers.select { |s| s.name == automate_server_name }.empty?
500
+ puts "ERROR: '#{server.name}' requires '#{automate_server_name}' to be running first."
501
+ abort_up = true
502
+ end
503
+ else
504
+ puts "ERROR: '#{server.name}' requires an Automate Server to be configured first."
505
+ abort_up = true
506
+ end
507
+ end
508
+ end
509
+ return abort_up
510
+ end
511
+
512
+ def create_dns_records
513
+ get_sorted_servers.each do |server|
514
+ ipaddress = server.container.ip_addresses.first
515
+ ipaddress ||= @server_configs[server.name][:ipaddress]
516
+ next unless ipaddress
517
+ additional_fqdn = @server_configs[server.name][:additional_fqdn]
518
+ dns_record = "#{ipaddress} #{server.name}"
519
+ dns_record += " #{additional_fqdn}\n" if additional_fqdn
520
+ DevLXC::search_file_delete_line("/etc/lxc/addn-hosts.conf", /\s#{server.name}/)
521
+ DevLXC::append_line_to_file("/etc/lxc/addn-hosts.conf", dns_record)
522
+ end
523
+ DevLXC::reload_dnsmasq
524
+ end
525
+
526
+ def clone_from_base_container(server)
527
+ server_type = @server_configs[server.name][:server_type]
528
+ base_container = DevLXC::Container.new(@server_configs[server.name][:base_container_name])
529
+ puts "Cloning base container '#{base_container.name}' into container '#{server.name}'"
530
+ base_container.clone(server.name, {:flags => LXC::LXC_CLONE_SNAPSHOT})
531
+ server.container.load_config
532
+ puts "Deleting SSH Server Host Keys"
533
+ FileUtils.rm_f(Dir.glob("#{server.container.config_item('lxc.rootfs')}/etc/ssh/ssh_host*_key*"))
534
+ end
535
+
536
+ def get_product_download_info(server, product_name, product_options)
537
+ server_type = @server_configs[server.name][:server_type]
538
+ base_container = DevLXC::Container.new(@server_configs[server.name][:base_container_name])
539
+ mixlib_install_platform_detection_path = "#{base_container.config_item('lxc.rootfs')}/mixlib-install-platform-detection"
540
+ IO.write(mixlib_install_platform_detection_path, Mixlib::Install::Generator::Bourne.detect_platform_sh)
541
+ platform_results = `chroot #{base_container.config_item('lxc.rootfs')} bash mixlib-install-platform-detection`
542
+ File.unlink(mixlib_install_platform_detection_path)
543
+ if platform_results.empty?
544
+ puts "ERROR: Unable to detect the platform of container '#{base_container.name}'"
545
+ exit 1
546
+ end
547
+ (platform, platform_version, architecture) = platform_results.split
548
+ product_version = product_options['version'] if product_options
549
+ product_version ||= 'latest'
550
+ channel = product_options['channel'] if product_options
551
+ channel ||= 'stable'
552
+ channel = channel.to_sym
553
+ options = {
554
+ product_name: product_name,
555
+ product_version: product_version,
556
+ channel: channel,
557
+ platform: platform,
558
+ platform_version: platform_version,
559
+ architecture: architecture
560
+ }
561
+ artifact = Mixlib::Install.new(options).artifact_info
562
+ if artifact.class != Mixlib::Install::ArtifactInfo
563
+ puts "ERROR: Unable to find download URL for the following product"
564
+ puts JSON.pretty_generate(options)
565
+ exit 1
566
+ end
567
+ [artifact.url, artifact.sha256]
568
+ end
569
+
570
+ def calculate_required_products(servers, force=false)
571
+ all_required_products = Hash.new
572
+ servers.each do |server|
573
+ products = @server_configs[server.name][:products]
574
+ @server_configs[server.name][:required_products] = Hash.new
575
+ if !force && !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: products installed") }.empty?
576
+ # Skipping product cache preparation for container because it has a 'products installed' snapshot
577
+ next
578
+ elsif !force && !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
579
+ # Skipping product cache preparation for container because it has a 'build: completed' snapshot
580
+ next
581
+ elsif ! @server_configs[server.name][:enable_build_snapshots] && ! @server_configs[server.name][:first_run]
582
+ # Skipping product cache preparation for container because it build snapshots are disabled and this is not the container's first run
583
+ next
584
+ end
585
+ products.each do |product_name, product_options|
586
+ if product_options && product_options['package_source']
587
+ package_source = product_options['package_source']
588
+ all_required_products[package_source] = [product_name, nil]
589
+ @server_configs[server.name][:required_products][product_name] = package_source
590
+ else
591
+ package_source, package_sha256 = get_product_download_info(server, product_name, product_options)
592
+ all_required_products[package_source] = [product_name, package_sha256]
593
+ product_cache_path = "/var/dev-lxc/cache/chef-products/#{product_name}/#{File.basename(package_source)}"
594
+ @server_configs[server.name][:required_products][product_name] = product_cache_path
595
+ end
596
+ end
597
+ end
598
+ all_required_products
599
+ end
600
+
601
+ def prep_product_cache(servers, force=false)
602
+ all_required_products = calculate_required_products(servers, force)
603
+ all_required_products.each do |package_source, v|
604
+ product_name, package_sha256 = v
605
+ if package_source.start_with?('http')
606
+ product_cache_path = "/var/dev-lxc/cache/chef-products/#{product_name}/#{File.basename(package_source)}"
607
+ if !File.exist?(product_cache_path)
608
+ FileUtils.mkdir_p(File.dirname(product_cache_path)) unless Dir.exist?(File.dirname(product_cache_path))
609
+ puts "Downloading #{package_source} to #{product_cache_path}"
610
+ open(package_source) { |url| File.open(product_cache_path, 'wb') { |f| f.write(url.read) } }
611
+ end
612
+ if package_sha256 != Digest::SHA256.file(product_cache_path).hexdigest
613
+ puts "ERROR: Incorrect SHA256 for #{product_cache_path}"
614
+ exit 1
615
+ end
616
+ elsif !File.exist?(package_source)
617
+ puts "ERROR: Package source #{package_source} does not exist."
618
+ exit 1
619
+ end
620
+ end
621
+ end
622
+
623
+ def install_products(server)
624
+ if !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: products installed") }.empty?
625
+ puts "Skipping product installation for container '#{server.name}' because it already has a 'products installed' snapshot"
626
+ return
627
+ elsif !server.snapshot_list.select { |sn| sn[2].to_s.start_with?("dev-lxc build: completed") }.empty?
628
+ puts "Skipping product installation for container '#{server.name}' because it already has a 'build: completed' snapshot"
629
+ return
630
+ end
631
+ if server.container.running?
632
+ server_was_running = true
633
+ else
634
+ server_was_running = false
635
+ server.start
636
+ end
637
+ @server_configs[server.name][:required_products].each do |product_name, package_source|
638
+ next if %w(build-nodes runners).include?(@server_configs[server.name][:server_type]) && product_name == "chefdk"
639
+ server.install_package(package_source)
640
+ end
641
+ if @server_configs[server.name][:enable_build_snapshots]
642
+ server.shutdown
643
+ server.snapshot("dev-lxc build: products installed")
644
+ server.start if server_was_running
645
+ end
646
+ end
647
+
648
+ def configure_products(server)
649
+ puts "Configuring container '#{server.name}'"
650
+ server.start
651
+ installed_products = @server_configs[server.name][:products].keys if @server_configs[server.name][:products]
652
+ installed_products ||= Array.new
653
+ server_type = @server_configs[server.name][:server_type]
654
+ dot_chef_path = "/root/chef-repo/.chef"
655
+ case server_type
656
+ when 'adhoc'
657
+ # Allow adhoc servers time to generate SSH Server Host Keys
658
+ sleep 5
659
+ when 'analytics'
660
+ configure_analytics(server) if installed_products.include?('analytics')
661
+ when 'build-nodes'
662
+ sleep 5 # give time for DNS resolution to be available
663
+ configure_build_node(server)
664
+ when 'runners'
665
+ sleep 5 # give time for DNS resolution to be available
666
+ configure_runner(server)
667
+ when 'chef-backend'
668
+ configure_chef_backend(server) if installed_products.include?('chef-backend')
669
+ if installed_products.include?('chef-server')
670
+ configure_chef_frontend(server)
671
+ if server.name == @config['chef-backend'][:bootstrap_frontend]
672
+ create_users_orgs_knife_configs(server, dot_chef_path)
673
+ end
674
+ end
675
+ configure_manage(server) if installed_products.include?('manage')
676
+ when 'chef-server'
677
+ if installed_products.include?('chef-server') || installed_products.include?('private-chef')
678
+ configure_chef_server(server)
679
+ if server.name == @config['chef-server'][:bootstrap_backend]
680
+ create_users_orgs_knife_configs(server, dot_chef_path)
681
+
682
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
683
+ if automate_server_name
684
+ automate_user = "delivery"
685
+ automate_chef_org = @server_configs[automate_server_name][:chef_org]
686
+ create_user(server, automate_user, dot_chef_path)
687
+ create_org(server, automate_chef_org, dot_chef_path)
688
+ org_add_user(server, automate_chef_org, automate_user, true, dot_chef_path)
689
+ end
690
+ end
691
+ end
692
+ configure_reporting(server) if installed_products.include?('reporting')
693
+ configure_push_jobs_server(server) if installed_products.include?('push-jobs-server')
694
+ configure_manage(server) if installed_products.include?('manage')
695
+ when 'compliance'
696
+ configure_compliance(server) if installed_products.include?('compliance')
697
+ when 'automate'
698
+ configure_automate(server) if installed_products.include?('delivery')
699
+ when 'nodes'
700
+ # Allow servers time to generate SSH Server Host Keys
701
+ sleep 5
702
+ configure_chef_client(server, dot_chef_path) if installed_products.include?('chef') || installed_products.include?('chefdk')
703
+ when 'supermarket'
704
+ configure_supermarket(server) if installed_products.include?('supermarket')
705
+ end
706
+ end
707
+
708
+ def configure_automate(server)
709
+ license_path = @server_configs[server.name][:license_path]
710
+ chef_org = @server_configs[server.name][:chef_org]
711
+ enterprise_name = @server_configs[server.name][:enterprise_name]
712
+ chef_server_url = @config['chef-server'][:fqdn]
713
+ supermarket_fqdn = @config['supermarket'][:fqdn]
714
+
715
+ FileUtils.cp(license_path, "#{server.container.config_item('lxc.rootfs')}/root/automate.license")
716
+
717
+ chef_server = get_server(@config['chef-server'][:bootstrap_backend])
718
+ automate_chef_user_key = "#{chef_server.container.config_item('lxc.rootfs')}/root/chef-repo/.chef/delivery.pem"
719
+ FileUtils.cp(automate_chef_user_key, "#{server.container.config_item('lxc.rootfs')}/root/automate_chef_user_key.pem")
720
+
721
+ setup_cmd = "setup"
722
+ setup_cmd += " --license /root/automate.license"
723
+ setup_cmd += " --fqdn #{server.name}"
724
+ setup_cmd += " --key /root/automate_chef_user_key.pem"
725
+ setup_cmd += " --server-url https://#{chef_server_url}/organizations/#{chef_org}"
726
+ setup_cmd += " --supermarket-fqdn #{supermarket_fqdn}" if supermarket_fqdn
727
+ setup_cmd += " --enterprise #{enterprise_name}"
728
+ setup_cmd += " --no-build-node"
729
+ setup_cmd += " --no-configure"
730
+ server.run_command("delivery-ctl #{setup_cmd}")
731
+
732
+ # enable Compliance profiles asset store
733
+ DevLXC::append_line_to_file("#{server.container.config_item('lxc.rootfs')}/etc/delivery/delivery.rb", "compliance_profiles['enable'] = true\n")
734
+
735
+ server.run_command("delivery-ctl reconfigure")
736
+
737
+ # give time for all services to come up completely
738
+ sleep 10
739
+
740
+ server.run_command("delivery-ctl create-enterprise #{enterprise_name} --ssh-pub-key-file /etc/delivery/builder_key.pub", "#{server.container.config_item('lxc.rootfs')}/etc/delivery/#{enterprise_name}-admin-credentials")
741
+ end
742
+
743
+ def print_automate_credentials
744
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
745
+ if automate_server_name
746
+ automate_server = get_server(automate_server_name)
747
+ automate_credentials_files = Dir.glob("#{automate_server.container.config_item('lxc.rootfs')}/etc/delivery/*-credentials")
748
+ automate_credentials_files.each_with_index do |automate_credentials_file, index|
749
+ puts IO.read(automate_credentials_file)
750
+ puts if index + 1 < automate_credentials_files.length
751
+ end
752
+ else
753
+ puts "WARNING: An Automate server is not defined."
754
+ exit 1
755
+ end
756
+ end
757
+
758
+ def configure_build_node(server)
759
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
760
+ if automate_server_name
761
+ automate_server = get_server(automate_server_name)
762
+ install_build_node_cmd = "install-build-node"
763
+ install_build_node_cmd += " --fqdn #{server.name}"
764
+ install_build_node_cmd += " --username dev-lxc"
765
+ install_build_node_cmd += " --password dev-lxc"
766
+ install_build_node_cmd += " --installer #{@server_configs[server.name][:required_products]["chefdk"]}"
767
+ install_build_node_cmd += " --overwrite-registration"
768
+ automate_server.run_command("delivery-ctl #{install_build_node_cmd}")
769
+ end
770
+ end
771
+
772
+ def configure_runner(server)
773
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
774
+ if automate_server_name
775
+ automate_server = get_server(automate_server_name)
776
+ install_runner_cmd = "install-runner #{server.name} dev-lxc"
777
+ install_runner_cmd += " --password dev-lxc"
778
+ install_runner_cmd += " --installer #{@server_configs[server.name][:required_products]["chefdk"]}"
779
+ install_runner_cmd += " --yes"
780
+ automate_server.run_command("delivery-ctl #{install_runner_cmd}")
781
+ end
782
+ end
783
+
784
+ def configure_chef_client(server, dot_chef_path)
785
+ puts "Configuring Chef Client in container '#{server.name}'"
786
+
787
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/chef")
788
+
789
+ chef_server_url = @server_configs[server.name][:chef_server_url]
790
+ validation_client_name = @server_configs[server.name][:validation_client_name]
791
+ validation_key = @server_configs[server.name][:validation_key]
792
+ if validation_key.nil?
793
+ chef_server_name = @config['chef-server'][:bootstrap_backend]
794
+ chef_server_name ||= @config['chef-backend'][:bootstrap_frontend]
795
+ if chef_server_name
796
+ chef_server = get_server(chef_server_name)
797
+ if chef_server.container.defined?
798
+ validator_pem_files = Dir.glob("#{chef_server.container.config_item('lxc.rootfs')}#{dot_chef_path}/*-validator.pem")
799
+ FileUtils.cp(validator_pem_files, "#{server.container.config_item('lxc.rootfs')}/etc/chef/") unless validator_pem_files.empty?
800
+ end
801
+ end
802
+ else
803
+ FileUtils.cp(validation_key, "#{server.container.config_item('lxc.rootfs')}/etc/chef/") if File.exists?(validation_key)
804
+ end
805
+
806
+ client_rb = %Q(#http_proxy 'http://10.0.3.1:8080'
807
+ #https_proxy 'http://10.0.3.1:8080'
808
+
809
+ chef_server_url '#{chef_server_url}'
810
+ validation_client_name '#{validation_client_name}'
811
+ validation_key '/etc/chef/#{validation_client_name}.pem'
812
+ ssl_verify_mode :verify_none
813
+ )
814
+
815
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
816
+ if automate_server_name
817
+ client_rb += %Q(
818
+ # data_collector.server_url "https://#{automate_server_name}/data-collector/v0/"
819
+ # data_collector.token "93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506"
820
+ )
821
+ end
822
+
823
+ IO.write("#{server.container.config_item('lxc.rootfs')}/etc/chef/client.rb", client_rb)
824
+ end
825
+
826
+ def configure_chef_backend(server)
827
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-backend")
828
+ FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-backend/.license.accepted")
829
+ if server.name == @config['chef-backend'][:leader_backend]
830
+ puts "Creating /etc/chef-backend/chef-backend.rb"
831
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/chef-backend")
832
+ chef_backend_config = "publish_address '#{@server_configs[server.name][:ipaddress]}'\n"
833
+ IO.write("#{server.container.config_item('lxc.rootfs')}/etc/chef-backend/chef-backend.rb", chef_backend_config)
834
+ server.run_command("chef-backend-ctl bootstrap --yes")
835
+ else
836
+ puts "Joining #{server.name} to the chef-backend cluster"
837
+ leader_backend = get_server(@config['chef-backend'][:leader_backend])
838
+ FileUtils.cp("#{leader_backend.container.config_item('lxc.rootfs')}/etc/chef-backend/chef-backend-secrets.json",
839
+ "#{server.container.config_item('lxc.rootfs')}/root/")
840
+ server.run_command("chef-backend-ctl join-cluster #{@server_configs[leader_backend.name][:ipaddress]} -p #{@server_configs[server.name][:ipaddress]} -s /root/chef-backend-secrets.json --yes")
841
+ end
842
+ end
843
+
844
+ def configure_chef_frontend(server)
845
+ puts "Creating /etc/opscode/chef-server.rb"
846
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/opscode")
847
+ leader_backend = get_server(@config['chef-backend'][:leader_backend])
848
+ leader_backend.run_command("chef-backend-ctl gen-server-config #{server.name} --filename /tmp/#{server.name}.rb")
849
+ FileUtils.cp("#{leader_backend.container.config_item('lxc.rootfs')}/tmp/#{server.name}.rb",
850
+ "#{server.container.config_item('lxc.rootfs')}/etc/opscode/chef-server.rb")
851
+ unless server.name == @config['chef-backend'][:bootstrap_frontend]
852
+ bootstrap_frontend = get_server(@config['chef-backend'][:bootstrap_frontend])
853
+ puts "Copying /etc/opscode/private-chef-secrets.json from bootstrap frontend '#{bootstrap_frontend.name}'"
854
+ FileUtils.cp("#{bootstrap_frontend.container.config_item('lxc.rootfs')}/etc/opscode/private-chef-secrets.json",
855
+ "#{server.container.config_item('lxc.rootfs')}/etc/opscode/")
856
+ puts "Copying /etc/opscode/pivotal.pem from bootstrap frontend '#{bootstrap_frontend.name}'"
857
+ FileUtils.cp("#{bootstrap_frontend.container.config_item('lxc.rootfs')}/etc/opscode/pivotal.pem",
858
+ "#{server.container.config_item('lxc.rootfs')}/etc/opscode/")
859
+ end
860
+ server.run_command("chef-server-ctl reconfigure")
861
+ end
862
+
863
+ def configure_chef_server(server)
864
+ if @config['chef-server'][:topology] == "standalone" || @config['chef-server'][:bootstrap_backend] == server.name
865
+ case @server_configs[server.name][:chef_server_type]
866
+ when 'private-chef'
867
+ puts "Creating /etc/opscode/private-chef.rb"
868
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/opscode")
869
+ IO.write("#{server.container.config_item('lxc.rootfs')}/etc/opscode/private-chef.rb", chef_server_config)
870
+ when 'chef-server'
871
+ puts "Creating /etc/opscode/chef-server.rb"
872
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/opscode")
873
+ IO.write("#{server.container.config_item('lxc.rootfs')}/etc/opscode/chef-server.rb", chef_server_config)
874
+ end
875
+ elsif @config['chef-server'][:frontends].include?(server.name)
876
+ puts "Copying /etc/opscode from bootstrap backend '#{@config['chef-server'][:bootstrap_backend]}'"
877
+ FileUtils.cp_r("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode",
878
+ "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
879
+ end
880
+ server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
881
+ end
882
+
883
+ def configure_reporting(server)
884
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-reporting")
885
+ FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-reporting/.license.accepted")
886
+ if @config['chef-server'][:frontends].include?(server.name)
887
+ puts "Copying /etc/opscode-reporting from bootstrap backend '#{@config['chef-server'][:bootstrap_backend]}'"
888
+ FileUtils.cp_r("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode-reporting",
889
+ "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
890
+ end
891
+ server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
892
+ server.run_command("opscode-reporting-ctl reconfigure")
893
+ end
894
+
895
+ def configure_push_jobs_server(server)
896
+ server.run_command("opscode-push-jobs-server-ctl reconfigure")
897
+ server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
898
+ end
899
+
900
+ def configure_manage(server)
901
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-manage")
902
+ FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-manage/.license.accepted")
903
+ if @server_configs[server.name][:chef_server_type] == 'private-chef'
904
+ puts "Disabling old opscode-webui in /etc/opscode/private-chef.rb"
905
+ DevLXC.search_file_delete_line("#{server.container.config_item('lxc.rootfs')}/etc/opscode/private-chef.rb", /opscode_webui[.enable.]/)
906
+ DevLXC.append_line_to_file("#{server.container.config_item('lxc.rootfs')}/etc/opscode/private-chef.rb", "\nopscode_webui['enable'] = false\n")
907
+ server.run_command("#{@server_configs[server.name][:chef_server_type]}-ctl reconfigure")
908
+ end
909
+ server.run_command("opscode-manage-ctl reconfigure")
910
+ end
911
+
912
+ def configure_analytics(server)
913
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-analytics")
914
+ FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/opscode-analytics/.license.accepted")
915
+ if @config['analytics'][:topology] == "standalone" || @config['analytics'][:bootstrap_backend] == server.name
916
+ puts "Copying /etc/opscode-analytics from Chef Server bootstrap backend '#{@config['chef-server'][:bootstrap_backend]}'"
917
+ FileUtils.cp_r("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode-analytics",
918
+ "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
919
+
920
+ IO.write("#{server.container.config_item('lxc.rootfs')}/etc/opscode-analytics/opscode-analytics.rb", analytics_config)
921
+ elsif @config['analytics'][:frontends].include?(server.name)
922
+ puts "Copying /etc/opscode-analytics from Analytics bootstrap backend '#{@config['analytics'][:bootstrap_backend]}'"
923
+ FileUtils.cp_r("#{get_server(@config['analytics'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode-analytics",
924
+ "#{server.container.config_item('lxc.rootfs')}/etc", preserve: true)
925
+ end
926
+ server.run_command("opscode-analytics-ctl reconfigure")
927
+ end
928
+
929
+ def configure_compliance(server)
930
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-compliance")
931
+ FileUtils.touch("#{server.container.config_item('lxc.rootfs')}/var/opt/chef-compliance/.license.accepted")
932
+ server.run_command("chef-compliance-ctl reconfigure")
933
+ admin_user = @server_configs[server.name][:admin_user]
934
+ if admin_user
935
+ server.run_command("chef-compliance-ctl user-create #{admin_user} #{admin_user}")
936
+ server.run_command("chef-compliance-ctl restart core")
937
+ end
938
+
939
+ if @config["chef-server"][:topology] == "standalone"
940
+ chef_server = get_server(@config['chef-server'][:bootstrap_backend])
941
+ FileUtils.mkdir_p("#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server")
942
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server")
943
+ IO.write("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/prepare-chef-compliance",
944
+ "chef-compliance-ctl connect chef-server --non-interactive true --chef-app-id 'compliance_server' --auth-id 'Chef Server' --insecure true --compliance-url 'https://#{server.name}'"
945
+ )
946
+ server.run_command("bash /root/integrate-compliance-with-chef-server/prepare-chef-compliance", "#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/prepare-chef-compliance-output")
947
+ server.run_command("chef-compliance-ctl reconfigure")
948
+ server.run_command("chef-compliance-ctl restart core")
949
+ prepare_chef_compliance_output = IO.read("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/prepare-chef-compliance-output")
950
+ delimited_chef_server_command = prepare_chef_compliance_output.match(/\n---\n(.+)\n---/m)
951
+ if delimited_chef_server_command
952
+ IO.write("#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-server", delimited_chef_server_command[1])
953
+ chef_server.run_command("bash /root/integrate-compliance-with-chef-server/configure-chef-server", "#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-server-output")
954
+ end
955
+ configure_chef_server_output = IO.read("#{chef_server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-server-output")
956
+ compliance_command = configure_chef_server_output.match(/^chef-compliance-ctl .+$/)
957
+ if compliance_command
958
+ IO.write("#{server.container.config_item('lxc.rootfs')}/root/integrate-compliance-with-chef-server/configure-chef-compliance", compliance_command)
959
+ server.run_command("bash /root/integrate-compliance-with-chef-server/configure-chef-compliance")
960
+ server.run_command("chef-compliance-ctl reconfigure")
961
+ end
962
+ end
963
+ end
964
+
965
+ def configure_supermarket(server)
966
+ if @config['chef-server'][:bootstrap_backend] && get_server(@config['chef-server'][:bootstrap_backend]).container.defined?
967
+ chef_server_supermarket_config = JSON.parse(IO.read("#{get_server(@config['chef-server'][:bootstrap_backend]).container.config_item('lxc.rootfs')}/etc/opscode/oc-id-applications/supermarket.json"))
968
+ supermarket_config = {
969
+ 'chef_server_url' => "https://#{@config['chef-server'][:fqdn]}/",
970
+ 'chef_oauth2_app_id' => chef_server_supermarket_config['uid'],
971
+ 'chef_oauth2_secret' => chef_server_supermarket_config['secret'],
972
+ 'chef_oauth2_verify_ssl' => false
973
+ }
974
+ FileUtils.mkdir_p("#{server.container.config_item('lxc.rootfs')}/etc/supermarket")
975
+ IO.write("#{server.container.config_item('lxc.rootfs')}/etc/supermarket/supermarket.json", JSON.pretty_generate(supermarket_config))
976
+ end
977
+ server.run_command("supermarket-ctl reconfigure")
978
+ end
979
+
980
+ def create_users_orgs_knife_configs(server, dot_chef_path)
981
+ server_type = @server_configs[server.name][:server_type]
982
+ # give time for all services to come up completely
983
+ sleep 10
984
+ if @server_configs[server.name][:chef_server_type] == 'private-chef'
985
+ # give more time for all services to come up completely
986
+ sleep 50
987
+ server.run_command("/opt/opscode/embedded/bin/gem install knife-opc --no-ri --no-rdoc -v 0.3.1")
988
+ end
989
+ chef_server_dot_chef_path = "#{server.container.config_item('lxc.rootfs')}#{dot_chef_path}"
990
+ FileUtils.mkdir_p(chef_server_dot_chef_path)
991
+ FileUtils.cp( "#{server.container.config_item('lxc.rootfs')}/etc/opscode/pivotal.pem", chef_server_dot_chef_path )
992
+ create_pivotal_knife_config('127.0.0.1', chef_server_dot_chef_path)
993
+ create_knife_config('127.0.0.1', chef_server_dot_chef_path)
994
+ @config[server_type][:users].each do |username|
995
+ create_user(server, username, dot_chef_path)
996
+ end
997
+ @config[server_type][:orgs].each do |orgname, org_users|
998
+ create_org(server, orgname, dot_chef_path)
999
+ if org_users
1000
+ if org_users['admins']
1001
+ org_users['admins'].each do |username|
1002
+ org_add_user(server, orgname, username, true, dot_chef_path)
1003
+ end
1004
+ end
1005
+ if org_users['non-admins']
1006
+ org_users['non-admins'].each do |username|
1007
+ org_add_user(server, orgname, username, false, dot_chef_path)
1008
+ end
1009
+ end
1010
+ end
1011
+ end
1012
+ end
1013
+
1014
+ def create_pivotal_knife_config(fqdn, dot_chef_path)
1015
+ pivotal_rb = %Q(
1016
+ current_dir = File.dirname(__FILE__)
1017
+
1018
+ chef_server_root "https://#{fqdn}"
1019
+ chef_server_url "https://#{fqdn}"
1020
+
1021
+ node_name "pivotal"
1022
+ client_key "\#{current_dir}/pivotal.pem"
1023
+
1024
+ cookbook_path Dir.pwd + "/cookbooks"
1025
+ knife[:chef_repo_path] = Dir.pwd
1026
+
1027
+ ssl_verify_mode :verify_none
1028
+ )
1029
+ IO.write("#{dot_chef_path}/pivotal.rb", pivotal_rb)
1030
+ end
1031
+
1032
+ def create_knife_config(fqdn, dot_chef_path)
1033
+ knife_rb = %Q(#http_proxy 'http://127.0.0.1:8080'
1034
+ #https_proxy 'http://127.0.0.1:8080'
1035
+
1036
+ username = "CHANGEME"
1037
+ orgname = "CHANGEME"
1038
+
1039
+ if [username, orgname].include?("CHANGEME")
1040
+ puts "ERROR: Please set 'username' and 'orgname' to proper values in knife.rb"
1041
+ exit!
1042
+ end
1043
+
1044
+ current_dir = File.dirname(__FILE__)
1045
+
1046
+ chef_server_url "https://#{fqdn}/organizations/\#{orgname}"
1047
+
1048
+ node_name username
1049
+ client_key "\#{current_dir}/\#{username}.pem"
1050
+
1051
+ validation_client_name "\#{orgname}-validator"
1052
+ validation_key "\#{current_dir}/\#{orgname}-validator.pem"
1053
+
1054
+ cookbook_path Dir.pwd + "/cookbooks"
1055
+ knife[:chef_repo_path] = Dir.pwd
1056
+
1057
+ ssl_verify_mode :verify_none
1058
+ )
1059
+ IO.write("#{dot_chef_path}/knife.rb", knife_rb)
1060
+ end
1061
+
1062
+ def create_user(server, username, dot_chef_path)
1063
+ create_user_string = "#{username} #{username} #{username} #{username}@noreply.com #{username} --filename #{dot_chef_path}/#{username}.pem"
1064
+ case @server_configs[server.name][:chef_server_type]
1065
+ when 'private-chef'
1066
+ server.run_command("/opt/opscode/embedded/bin/knife opc user create #{create_user_string} -c #{dot_chef_path}/pivotal.rb")
1067
+ when 'chef-server'
1068
+ server.run_command("chef-server-ctl user-create #{create_user_string}")
1069
+ end
1070
+ end
1071
+
1072
+ def create_org(server, orgname, dot_chef_path)
1073
+ create_org_string = "#{orgname} #{orgname} --filename #{dot_chef_path}/#{orgname}-validator.pem"
1074
+ case @server_configs[server.name][:chef_server_type]
1075
+ when 'private-chef'
1076
+ server.run_command("/opt/opscode/embedded/bin/knife opc org create #{create_org_string} -c #{dot_chef_path}/pivotal.rb")
1077
+ when 'chef-server'
1078
+ server.run_command("chef-server-ctl org-create #{create_org_string}")
1079
+ end
1080
+ end
1081
+
1082
+ def org_add_user(server, orgname, username, admin, dot_chef_path)
1083
+ org_add_user_string = "#{orgname} #{username}"
1084
+ org_add_user_string += " --admin" if admin
1085
+ case @server_configs[server.name][:chef_server_type]
1086
+ when 'private-chef'
1087
+ server.run_command("/opt/opscode/embedded/bin/knife opc org user add #{org_add_user_string} -c #{dot_chef_path}/pivotal.rb")
1088
+ when 'chef-server'
1089
+ server.run_command("chef-server-ctl org-user-add #{org_add_user_string}")
1090
+ end
1091
+ end
1092
+
1093
+ def chef_repo(force=false, pivotal=false)
1094
+ chef_server_dot_chef_path = "/root/chef-repo/.chef"
1095
+ dot_chef_path = "./chef-repo/.chef"
1096
+
1097
+ if @config['chef-server'][:bootstrap_backend]
1098
+ chef_server = get_server(@config['chef-server'][:bootstrap_backend])
1099
+ chef_server_fqdn = @config['chef-server'][:fqdn]
1100
+ elsif @config['chef-backend'][:bootstrap_frontend]
1101
+ chef_server = get_server(@config['chef-backend'][:bootstrap_frontend])
1102
+ chef_server_fqdn = @config['chef-backend'][:fqdn]
1103
+ else
1104
+ puts "ERROR: A Chef Server is not defined in the cluster's config. Please define it first."
1105
+ exit 1
1106
+ end
1107
+ unless chef_server.container.defined?
1108
+ puts "ERROR: The '#{chef_server.name}' Chef Server does not exist."
1109
+ exit 1
1110
+ end
1111
+
1112
+ puts "Creating chef-repo with pem files and knife.rb in the current directory"
1113
+ FileUtils.mkdir_p(dot_chef_path)
1114
+
1115
+ pem_files = Dir.glob("#{chef_server.container.config_item('lxc.rootfs')}#{chef_server_dot_chef_path}/*.pem")
1116
+ pem_files.delete_if { |pem_file| pem_file.end_with?("/pivotal.pem") } unless pivotal
1117
+ FileUtils.cp(pem_files, dot_chef_path) unless pem_files.empty?
1118
+
1119
+ if pivotal
1120
+ if File.exists?("#{dot_chef_path}/pivotal.rb") && ! force
1121
+ puts "Skipping pivotal.rb because it already exists in `#{dot_chef_path}`"
1122
+ else
1123
+ create_pivotal_knife_config(chef_server_fqdn, dot_chef_path)
1124
+ end
1125
+ end
1126
+
1127
+ if File.exists?("./chef-repo/.chef/knife.rb") && ! force
1128
+ puts "Skipping knife.rb because it already exists in `#{dot_chef_path}`"
1129
+ else
1130
+ create_knife_config(chef_server_fqdn, dot_chef_path)
1131
+ end
1132
+ end
1133
+
1134
+ def chef_server_config
1135
+ chef_server_config = %Q(api_fqdn "#{@config['chef-server'][:fqdn]}"\n)
1136
+ if @config['chef-server'][:topology] == 'tier'
1137
+ chef_server_config += %Q(
1138
+ topology "#{@config['chef-server'][:topology]}"
1139
+
1140
+ server "#{@config['chef-server'][:bootstrap_backend]}",
1141
+ :ipaddress => "#{@server_configs[@config['chef-server'][:bootstrap_backend]][:ipaddress]}",
1142
+ :role => "backend",
1143
+ :bootstrap => true
1144
+
1145
+ backend_vip "#{@config['chef-server'][:bootstrap_backend]}",
1146
+ :ipaddress => "#{@server_configs[@config['chef-server'][:bootstrap_backend]][:ipaddress]}"
1147
+ )
1148
+ @config['chef-server'][:frontends].each do |frontend_name|
1149
+ chef_server_config += %Q(
1150
+ server "#{frontend_name}",
1151
+ :ipaddress => "#{@server_configs[frontend_name][:ipaddress]}",
1152
+ :role => "frontend"
1153
+ )
1154
+ end
1155
+ end
1156
+ if @config['analytics'][:fqdn]
1157
+ chef_server_config += %Q(
1158
+ oc_id['applications'] ||= {}
1159
+ oc_id['applications']['analytics'] = {
1160
+ 'redirect_uri' => 'https://#{@config['analytics'][:fqdn]}/'
1161
+ }
1162
+ rabbitmq['vip'] = '#{@config['chef-server'][:bootstrap_backend]}'
1163
+ rabbitmq['node_ip_address'] = '0.0.0.0'
1164
+ )
1165
+ end
1166
+ if @config['supermarket'][:fqdn]
1167
+ chef_server_config += %Q(
1168
+ oc_id['applications'] ||= {}
1169
+ oc_id['applications']['supermarket'] = {
1170
+ 'redirect_uri' => 'https://#{@config['supermarket'][:fqdn]}/auth/chef_oauth2/callback'
1171
+ }
1172
+ )
1173
+ end
1174
+ automate_server_name = @server_configs.select {|name, config| config[:server_type] == 'automate'}.keys.first
1175
+ if automate_server_name
1176
+ chef_server_config += %Q(
1177
+ data_collector['root_url'] = "https://#{automate_server_name}/data-collector/v0/"
1178
+ data_collector['token'] = "93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506"
1179
+ profiles['root_url'] = "https://#{automate_server_name}"
1180
+ )
1181
+ end
1182
+ return chef_server_config
1183
+ end
1184
+
1185
+ def analytics_config
1186
+ analytics_config = %Q(analytics_fqdn "#{@config['analytics'][:fqdn]}"
1187
+ topology "#{@config['analytics'][:topology]}"
1188
+ )
1189
+ if @config['analytics'][:topology] == 'tier'
1190
+ analytics_config += %Q(
1191
+ server "#{@config['analytics'][:bootstrap_backend]}",
1192
+ :ipaddress => "#{@server_configs[@config['analytics'][:bootstrap_backend]][:ipaddress]}",
1193
+ :role => "backend",
1194
+ :bootstrap => true
1195
+
1196
+ backend_vip "#{@config['analytics'][:bootstrap_backend]}",
1197
+ :ipaddress => "#{@server_configs[@config['analytics'][:bootstrap_backend]][:ipaddress]}"
1198
+ )
1199
+ @config['analytics'][:frontends].each do |frontend_name|
1200
+ analytics_config += %Q(
1201
+ server "#{frontend_name}",
1202
+ :ipaddress => "#{@server_configs[frontend_name][:ipaddress]}",
1203
+ :role => "frontend"
1204
+ )
1205
+ end
1206
+ end
1207
+ return analytics_config
1208
+ end
1209
+
1210
+ end
1211
+ end