cloud-mu 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +10 -2
  3. data/bin/mu-adopt +5 -1
  4. data/bin/mu-load-config.rb +2 -3
  5. data/bin/mu-run-tests +112 -27
  6. data/cloud-mu.gemspec +20 -20
  7. data/cookbooks/mu-tools/libraries/helper.rb +2 -1
  8. data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
  9. data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
  10. data/cookbooks/mu-tools/resources/disk.rb +1 -1
  11. data/extras/image-generators/Google/centos6.yaml +1 -0
  12. data/extras/image-generators/Google/centos7.yaml +1 -1
  13. data/modules/mommacat.ru +5 -15
  14. data/modules/mu.rb +10 -14
  15. data/modules/mu/adoption.rb +20 -14
  16. data/modules/mu/cleanup.rb +13 -9
  17. data/modules/mu/cloud.rb +26 -26
  18. data/modules/mu/clouds/aws.rb +100 -59
  19. data/modules/mu/clouds/aws/alarm.rb +4 -2
  20. data/modules/mu/clouds/aws/bucket.rb +25 -21
  21. data/modules/mu/clouds/aws/cache_cluster.rb +25 -23
  22. data/modules/mu/clouds/aws/collection.rb +21 -20
  23. data/modules/mu/clouds/aws/container_cluster.rb +47 -26
  24. data/modules/mu/clouds/aws/database.rb +57 -68
  25. data/modules/mu/clouds/aws/dnszone.rb +14 -14
  26. data/modules/mu/clouds/aws/endpoint.rb +20 -16
  27. data/modules/mu/clouds/aws/firewall_rule.rb +19 -16
  28. data/modules/mu/clouds/aws/folder.rb +7 -7
  29. data/modules/mu/clouds/aws/function.rb +15 -12
  30. data/modules/mu/clouds/aws/group.rb +14 -10
  31. data/modules/mu/clouds/aws/habitat.rb +16 -13
  32. data/modules/mu/clouds/aws/loadbalancer.rb +16 -15
  33. data/modules/mu/clouds/aws/log.rb +13 -10
  34. data/modules/mu/clouds/aws/msg_queue.rb +15 -8
  35. data/modules/mu/clouds/aws/nosqldb.rb +18 -11
  36. data/modules/mu/clouds/aws/notifier.rb +11 -6
  37. data/modules/mu/clouds/aws/role.rb +87 -70
  38. data/modules/mu/clouds/aws/search_domain.rb +30 -19
  39. data/modules/mu/clouds/aws/server.rb +102 -72
  40. data/modules/mu/clouds/aws/server_pool.rb +47 -28
  41. data/modules/mu/clouds/aws/storage_pool.rb +5 -6
  42. data/modules/mu/clouds/aws/user.rb +13 -10
  43. data/modules/mu/clouds/aws/vpc.rb +135 -121
  44. data/modules/mu/clouds/azure.rb +16 -9
  45. data/modules/mu/clouds/azure/container_cluster.rb +2 -3
  46. data/modules/mu/clouds/azure/firewall_rule.rb +10 -10
  47. data/modules/mu/clouds/azure/habitat.rb +8 -6
  48. data/modules/mu/clouds/azure/loadbalancer.rb +5 -5
  49. data/modules/mu/clouds/azure/role.rb +8 -10
  50. data/modules/mu/clouds/azure/server.rb +65 -25
  51. data/modules/mu/clouds/azure/user.rb +5 -7
  52. data/modules/mu/clouds/azure/vpc.rb +12 -15
  53. data/modules/mu/clouds/cloudformation.rb +8 -7
  54. data/modules/mu/clouds/cloudformation/vpc.rb +2 -4
  55. data/modules/mu/clouds/google.rb +39 -24
  56. data/modules/mu/clouds/google/bucket.rb +9 -11
  57. data/modules/mu/clouds/google/container_cluster.rb +27 -42
  58. data/modules/mu/clouds/google/database.rb +6 -9
  59. data/modules/mu/clouds/google/firewall_rule.rb +11 -10
  60. data/modules/mu/clouds/google/folder.rb +16 -9
  61. data/modules/mu/clouds/google/function.rb +127 -161
  62. data/modules/mu/clouds/google/group.rb +21 -18
  63. data/modules/mu/clouds/google/habitat.rb +18 -15
  64. data/modules/mu/clouds/google/loadbalancer.rb +14 -16
  65. data/modules/mu/clouds/google/role.rb +48 -31
  66. data/modules/mu/clouds/google/server.rb +105 -105
  67. data/modules/mu/clouds/google/server_pool.rb +12 -31
  68. data/modules/mu/clouds/google/user.rb +67 -13
  69. data/modules/mu/clouds/google/vpc.rb +58 -65
  70. data/modules/mu/config.rb +89 -1738
  71. data/modules/mu/config/bucket.rb +3 -3
  72. data/modules/mu/config/collection.rb +3 -3
  73. data/modules/mu/config/container_cluster.rb +2 -2
  74. data/modules/mu/config/dnszone.rb +5 -5
  75. data/modules/mu/config/doc_helpers.rb +517 -0
  76. data/modules/mu/config/endpoint.rb +3 -3
  77. data/modules/mu/config/firewall_rule.rb +118 -3
  78. data/modules/mu/config/folder.rb +3 -3
  79. data/modules/mu/config/function.rb +2 -2
  80. data/modules/mu/config/group.rb +3 -3
  81. data/modules/mu/config/habitat.rb +3 -3
  82. data/modules/mu/config/loadbalancer.rb +3 -3
  83. data/modules/mu/config/log.rb +3 -3
  84. data/modules/mu/config/msg_queue.rb +3 -3
  85. data/modules/mu/config/nosqldb.rb +3 -3
  86. data/modules/mu/config/notifier.rb +2 -2
  87. data/modules/mu/config/ref.rb +333 -0
  88. data/modules/mu/config/role.rb +3 -3
  89. data/modules/mu/config/schema_helpers.rb +508 -0
  90. data/modules/mu/config/search_domain.rb +3 -3
  91. data/modules/mu/config/server.rb +86 -58
  92. data/modules/mu/config/server_pool.rb +2 -2
  93. data/modules/mu/config/tail.rb +189 -0
  94. data/modules/mu/config/user.rb +3 -3
  95. data/modules/mu/config/vpc.rb +44 -4
  96. data/modules/mu/defaults/Google.yaml +2 -2
  97. data/modules/mu/deploy.rb +13 -10
  98. data/modules/mu/groomer.rb +1 -1
  99. data/modules/mu/groomers/ansible.rb +69 -24
  100. data/modules/mu/groomers/chef.rb +52 -44
  101. data/modules/mu/logger.rb +17 -14
  102. data/modules/mu/master.rb +317 -2
  103. data/modules/mu/master/chef.rb +3 -4
  104. data/modules/mu/master/ldap.rb +3 -3
  105. data/modules/mu/master/ssl.rb +12 -2
  106. data/modules/mu/mommacat.rb +85 -1766
  107. data/modules/mu/mommacat/daemon.rb +394 -0
  108. data/modules/mu/mommacat/naming.rb +366 -0
  109. data/modules/mu/mommacat/storage.rb +689 -0
  110. data/modules/tests/bucket.yml +4 -0
  111. data/modules/tests/{win2k12.yaml → needwork/win2k12.yaml} +0 -0
  112. data/modules/tests/regrooms/aws-iam.yaml +201 -0
  113. data/modules/tests/regrooms/bucket.yml +19 -0
  114. metadata +112 -102
@@ -66,13 +66,16 @@ module MU
66
66
  def log(msg,
67
67
  level=INFO,
68
68
  details: nil,
69
- html: @html,
70
- verbosity: @verbosity,
71
- handle: @handle,
72
- color: @color,
69
+ html: nil,
70
+ verbosity: nil,
71
+ handle: nil,
72
+ color: nil,
73
73
  deploy: MU.mommacat
74
74
  )
75
75
  verbosity ||= @verbosity
76
+ html ||= @html
77
+ handle ||= @handle
78
+ color ||= @color
76
79
  return if verbosity == MU::Logger::SILENT
77
80
  return if verbosity < MU::Logger::LOUD and level == DEBUG
78
81
  return if verbosity < MU::Logger::NORMAL and level == INFO
@@ -101,7 +104,7 @@ module MU
101
104
  end
102
105
  details = PP.pp(details, '') if !details.is_a?(String)
103
106
  end
104
- details = "<pre>"+details+"</pre>" if @html
107
+ details = "<pre>"+details+"</pre>" if html
105
108
  # We get passed literal quoted newlines sometimes, fix 'em. Get Windows'
106
109
  # ugly line feeds too.
107
110
  if !details.nil?
@@ -139,7 +142,7 @@ module MU
139
142
  @summary << msg
140
143
  when DEBUG
141
144
  if verbosity >= MU::Logger::LOUD
142
- if @html
145
+ if html
143
146
  html_out "#{time} - #{caller_name} - #{msg}", "orange"
144
147
  html_out "&nbsp;#{details}" if details
145
148
  elsif color
@@ -154,7 +157,7 @@ module MU
154
157
  end
155
158
  when INFO
156
159
  if verbosity >= MU::Logger::NORMAL
157
- if @html
160
+ if html
158
161
  html_out "#{time} - #{caller_name} - #{msg}", "green"
159
162
  elsif color
160
163
  msgs << "#{time} - #{caller_name} - #{msg}".green.on_black
@@ -162,7 +165,7 @@ module MU
162
165
  msgs << "#{time} - #{caller_name} - #{msg}"
163
166
  end
164
167
  if verbosity >= MU::Logger::LOUD
165
- if @html
168
+ if html
166
169
  html_out "&nbsp;#{details}"
167
170
  elsif color
168
171
  msgs << "#{details}".white.on_black if details
@@ -174,7 +177,7 @@ module MU
174
177
  Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details
175
178
  end
176
179
  when NOTICE
177
- if @html
180
+ if html
178
181
  html_out "#{time} - #{caller_name} - #{msg}", "yellow"
179
182
  elsif color
180
183
  msgs << "#{time} - #{caller_name} - #{msg}".yellow.on_black
@@ -182,7 +185,7 @@ module MU
182
185
  msgs << "#{time} - #{caller_name} - #{msg}"
183
186
  end
184
187
  if verbosity >= MU::Logger::QUIET
185
- if @html
188
+ if html
186
189
  html_out "#{caller_name} - #{msg}"
187
190
  elsif color
188
191
  msgs << "#{details}".white.on_black if details
@@ -193,7 +196,7 @@ module MU
193
196
  Syslog.log(Syslog::LOG_NOTICE, msg.gsub(/%/, ''))
194
197
  Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details
195
198
  when WARN
196
- if @html
199
+ if html
197
200
  html_out "#{time} - #{caller_name} - #{msg}", "orange"
198
201
  elsif color
199
202
  msgs << "#{time} - #{caller_name} - #{msg}".light_red.on_black
@@ -201,7 +204,7 @@ module MU
201
204
  msgs << "#{time} - #{caller_name} - #{msg}"
202
205
  end
203
206
  if verbosity >= MU::Logger::SILENT
204
- if @html
207
+ if html
205
208
  html_out "#{caller_name} - #{msg}"
206
209
  elsif color
207
210
  msgs << "#{details}".white.on_black if details
@@ -212,7 +215,7 @@ module MU
212
215
  Syslog.log(Syslog::LOG_WARNING, msg.gsub(/%/, ''))
213
216
  Syslog.log(Syslog::LOG_WARNING, details.gsub(/%/, '')) if details
214
217
  when ERR
215
- if @html
218
+ if html
216
219
  html_out "#{time} - #{caller_name} - #{msg}", "red"
217
220
  html_out "&nbsp;#{details}" if details
218
221
  elsif color
@@ -225,7 +228,7 @@ module MU
225
228
  Syslog.log(Syslog::LOG_ERR, msg.gsub(/%/, ''))
226
229
  Syslog.log(Syslog::LOG_ERR, details.gsub(/%/, '')) if details
227
230
  else
228
- if @html
231
+ if html
229
232
  html_out "#{time} - #{caller_name} - #{msg}"
230
233
  html_out "&nbsp;#{details}" if details
231
234
  elsif color
@@ -24,6 +24,12 @@ module MU
24
24
  autoload :LDAP, 'mu/master/ldap'
25
25
  autoload :SSL, 'mu/master/ssl'
26
26
 
27
+ # Home directory of the invoking user
28
+ MY_HOME = Etc.getpwuid(Process.uid).dir
29
+
30
+ # Home directory of the Nagios user, if we're in a non-gem context
31
+ NAGIOS_HOME = "/opt/mu/var/nagios_user_home" # XXX gross
32
+
27
33
  # @param users [Hash]: User metadata of the type returned by listUsers
28
34
  def self.printUsersToTerminal(users = MU::Master.listUsers)
29
35
  labeled = false
@@ -228,7 +234,7 @@ module MU
228
234
  begin
229
235
  resp = MU::Cloud::AWS.s3.get_object(bucket: MU.adminBucketName, key: cryptfile)
230
236
  body = resp.body
231
- rescue Exception => e
237
+ rescue StandardError => e
232
238
  MU.log "Failed to fetch #{cryptfile} from S3 bucket #{MU.adminBucketName}", MU::ERR, details: e.inspect
233
239
  %x{/bin/dd if=/dev/urandom of=#{temp_dev} bs=1M count=1 > /dev/null 2>&1}
234
240
  raise e
@@ -236,7 +242,7 @@ module MU
236
242
  elsif MU::Cloud::Google.hosted?
237
243
  begin
238
244
  body = MU::Cloud::Google.storage.get_object(MU.adminBucketName, cryptfile)
239
- rescue Exception => e
245
+ rescue StandardError => e
240
246
  MU.log "Failed to fetch #{cryptfile} from Cloud Storage bucket #{MU.adminBucketName}", MU::ERR, details: e.inspect
241
247
  %x{/bin/dd if=/dev/urandom of=#{temp_dev} bs=1M count=1 > /dev/null 2>&1}
242
248
  raise e
@@ -493,5 +499,314 @@ module MU
493
499
  end
494
500
  end
495
501
 
502
+ # Clean a node's entries out of /etc/hosts
503
+ # @param node [String]: The node's name
504
+ # @return [void]
505
+ def self.removeInstanceFromEtcHosts(node)
506
+ return if MU.mu_user != "mu"
507
+ hostsfile = "/etc/hosts"
508
+ FileUtils.copy(hostsfile, "#{hostsfile}.bak-#{MU.deploy_id}")
509
+ File.open(hostsfile, File::CREAT|File::RDWR, 0644) { |f|
510
+ f.flock(File::LOCK_EX)
511
+ newlines = Array.new
512
+ f.readlines.each { |line|
513
+ newlines << line if !line.match(/ #{node}(\s|$)/)
514
+ }
515
+ f.rewind
516
+ f.truncate(0)
517
+ f.puts(newlines)
518
+ f.flush
519
+
520
+ f.flock(File::LOCK_UN)
521
+ }
522
+ end
523
+
524
+
525
+ # Insert node names associated with a new instance into /etc/hosts so we
526
+ # can treat them as if they were real DNS entries. Especially helpful when
527
+ # Chef/Ohai mistake the proper hostname, e.g. when bootstrapping Windows.
528
+ # @param public_ip [String]: The node's IP address
529
+ # @param chef_name [String]: The node's Chef node name
530
+ # @param system_name [String]: The node's local system name
531
+ # @return [void]
532
+ def self.addInstanceToEtcHosts(public_ip, chef_name = nil, system_name = nil)
533
+
534
+ # XXX cover ipv6 case
535
+ if public_ip.nil? or !public_ip.match(/^\d+\.\d+\.\d+\.\d+$/) or (chef_name.nil? and system_name.nil?)
536
+ raise MuError, "addInstanceToEtcHosts requires public_ip and one or both of chef_name and system_name!"
537
+ end
538
+ if chef_name == "localhost" or system_name == "localhost"
539
+ raise MuError, "Can't set localhost as a name in addInstanceToEtcHosts"
540
+ end
541
+
542
+ if !["mu", "root"].include?(MU.mu_user)
543
+ response = nil
544
+ begin
545
+ response = open("https://127.0.0.1:#{MU.mommaCatPort.to_s}/rest/hosts_add/#{chef_name}/#{public_ip}").read
546
+ rescue Errno::ECONNRESET, Errno::ECONNREFUSED
547
+ end
548
+ if response != "ok"
549
+ MU.log "Error adding #{public_ip} to /etc/hosts via MommaCat request", MU::ERR
550
+ end
551
+ return
552
+ end
553
+
554
+ File.readlines("/etc/hosts").each { |line|
555
+ if line.match(/^#{public_ip} /) or (chef_name != nil and line.match(/ #{chef_name}(\s|$)/)) or (system_name != nil and line.match(/ #{system_name}(\s|$)/))
556
+ MU.log "Ignoring attempt to add duplicate /etc/hosts entry: #{public_ip} #{chef_name} #{system_name}", MU::DEBUG
557
+ return
558
+ end
559
+ }
560
+ File.open("/etc/hosts", 'a') { |etc_hosts|
561
+ etc_hosts.flock(File::LOCK_EX)
562
+ etc_hosts.puts("#{public_ip} #{chef_name} #{system_name}")
563
+ etc_hosts.flock(File::LOCK_UN)
564
+ }
565
+ MU.log("Added to /etc/hosts: #{public_ip} #{chef_name} #{system_name}")
566
+ end
567
+
568
+ @ssh_semaphore = Mutex.new
569
+ # Insert a definition for a node into our SSH config.
570
+ # @param server [MU::Cloud::Server]: The name of the node.
571
+ # @param names [Array<String>]: Other names that we'd like this host to be known by for SSH purposes
572
+ # @param ssh_dir [String]: The configuration directory of the SSH config to emit.
573
+ # @param ssh_conf [String]: A specific SSH configuration file to write entries into.
574
+ # @param ssh_owner [String]: The preferred owner of the SSH configuration files.
575
+ # @param timeout [Integer]: An alternate timeout value for connections to this server.
576
+ # @return [void]
577
+ def self.addHostToSSHConfig(server,
578
+ ssh_dir: "#{Etc.getpwuid(Process.uid).dir}/.ssh",
579
+ ssh_conf: "#{Etc.getpwuid(Process.uid).dir}/.ssh/config",
580
+ ssh_owner: Etc.getpwuid(Process.uid).name,
581
+ names: [],
582
+ timeout: 0
583
+ )
584
+ if server.nil?
585
+ MU.log "Called addHostToSSHConfig without a MU::Cloud::Server object", MU::ERR, details: caller
586
+ return nil
587
+ end
588
+
589
+ _nat_ssh_key, nat_ssh_user, nat_ssh_host, canonical_ip, ssh_user, ssh_key_name = begin
590
+ server.getSSHConfig
591
+ rescue MU::MuError
592
+ return
593
+ end
594
+
595
+ if ssh_user.nil? or ssh_user.empty?
596
+ MU.log "Failed to extract ssh_user for #{server.mu_name} addHostToSSHConfig", MU::ERR
597
+ return
598
+ end
599
+ if canonical_ip.nil? or canonical_ip.empty?
600
+ MU.log "Failed to extract canonical_ip for #{server.mu_name} addHostToSSHConfig", MU::ERR
601
+ return
602
+ end
603
+ if ssh_key_name.nil? or ssh_key_name.empty?
604
+ MU.log "Failed to extract ssh_key_name for #{ssh_key_name.mu_name} in addHostToSSHConfig", MU::ERR
605
+ return
606
+ end
607
+
608
+ @ssh_semaphore.synchronize {
609
+
610
+ if File.exist?(ssh_conf)
611
+ File.readlines(ssh_conf).each { |line|
612
+ if line.match(/^Host #{server.mu_name} /)
613
+ MU.log("Attempt to add duplicate #{ssh_conf} entry for #{server.mu_name}", MU::WARN)
614
+ return
615
+ end
616
+ }
617
+ end
618
+
619
+ File.open(ssh_conf, 'a', 0600) { |ssh_config|
620
+ ssh_config.flock(File::LOCK_EX)
621
+ host_str = "Host #{server.mu_name} #{server.canonicalIP}"
622
+ if !names.nil? and names.size > 0
623
+ host_str = host_str+" "+names.join(" ")
624
+ end
625
+ ssh_config.puts host_str
626
+ ssh_config.puts " Hostname #{server.canonicalIP}"
627
+ if !nat_ssh_host.nil? and server.canonicalIP != nat_ssh_host
628
+ ssh_config.puts " ProxyCommand ssh -W %h:%p #{nat_ssh_user}@#{nat_ssh_host}"
629
+ end
630
+ if timeout > 0
631
+ ssh_config.puts " ConnectTimeout #{timeout}"
632
+ end
633
+
634
+ ssh_config.puts " User #{ssh_user}"
635
+ # XXX I'd rather add the host key to known_hosts, but Net::SSH is a little dumb
636
+ ssh_config.puts " StrictHostKeyChecking no"
637
+ ssh_config.puts " ServerAliveInterval 60"
638
+
639
+ ssh_config.puts " IdentityFile #{ssh_dir}/#{ssh_key_name}"
640
+ if !File.exist?("#{ssh_dir}/#{ssh_key_name}")
641
+ MU.log "#{server.mu_name} - ssh private key #{ssh_dir}/#{ssh_key_name} does not exist", MU::WARN
642
+ end
643
+
644
+ ssh_config.flock(File::LOCK_UN)
645
+ ssh_config.chown(Etc.getpwnam(ssh_owner).uid, Etc.getpwnam(ssh_owner).gid)
646
+ }
647
+ MU.log "Wrote #{server.mu_name} ssh key to #{ssh_dir}/config", MU::DEBUG
648
+ return "#{ssh_dir}/#{ssh_key_name}"
649
+ }
650
+ end
651
+
652
+ # Clean an IP address out of ~/.ssh/known hosts
653
+ # @param ip [String]: The IP to remove
654
+ # @return [void]
655
+ def self.removeIPFromSSHKnownHosts(ip, noop: false)
656
+ return if ip.nil?
657
+ sshdir = "#{MY_HOME}/.ssh"
658
+ knownhosts = "#{sshdir}/known_hosts"
659
+
660
+ if File.exist?(knownhosts) and File.open(knownhosts).read.match(/^#{Regexp.quote(ip)} /)
661
+ MU.log "Expunging old #{ip} entry from #{knownhosts}", MU::NOTICE
662
+ if !noop
663
+ File.open(knownhosts, File::CREAT|File::RDWR, 0600) { |f|
664
+ f.flock(File::LOCK_EX)
665
+ newlines = Array.new
666
+ f.readlines.each { |line|
667
+ next if line.match(/^#{Regexp.quote(ip)} /)
668
+ newlines << line
669
+ }
670
+ f.rewind
671
+ f.truncate(0)
672
+ f.puts(newlines)
673
+ f.flush
674
+ f.flock(File::LOCK_UN)
675
+ }
676
+ end
677
+ end
678
+ end
679
+
680
+ # Clean a node's entries out of ~/.ssh/config
681
+ # @param nodename [String]: The node's name
682
+ # @return [void]
683
+ def self.removeHostFromSSHConfig(nodename, noop: false)
684
+ sshdir = "#{MY_HOME}/.ssh"
685
+ sshconf = "#{sshdir}/config"
686
+
687
+ if File.exist?(sshconf) and File.open(sshconf).read.match(/ #{nodename} /)
688
+ MU.log "Expunging old #{nodename} entry from #{sshconf}", MU::DEBUG
689
+ if !noop
690
+ File.open(sshconf, File::CREAT|File::RDWR, 0600) { |f|
691
+ f.flock(File::LOCK_EX)
692
+ newlines = Array.new
693
+ delete_block = false
694
+ f.readlines.each { |line|
695
+ if line.match(/^Host #{nodename}(\s|$)/)
696
+ delete_block = true
697
+ elsif line.match(/^Host /)
698
+ delete_block = false
699
+ end
700
+ newlines << line if !delete_block
701
+ }
702
+ f.rewind
703
+ f.truncate(0)
704
+ f.puts(newlines)
705
+ f.flush
706
+ f.flock(File::LOCK_UN)
707
+ }
708
+ end
709
+ end
710
+ end
711
+
712
+ # Ensure that the Nagios configuration local to the MU master has been
713
+ # updated, and make sure Nagios has all of the ssh keys it needs to tunnel
714
+ # to client nodes.
715
+ # @return [void]
716
+ def self.syncMonitoringConfig(blocking = true)
717
+ return if Etc.getpwuid(Process.uid).name != "root" or (MU.mu_user != "mu" and MU.mu_user != "root")
718
+ parent_thread_id = Thread.current.object_id
719
+ nagios_threads = []
720
+ nagios_threads << Thread.new {
721
+ MU.dupGlobals(parent_thread_id)
722
+ realhome = Etc.getpwnam("nagios").dir
723
+ [NAGIOS_HOME, "#{NAGIOS_HOME}/.ssh"].each { |dir|
724
+ Dir.mkdir(dir, 0711) if !Dir.exist?(dir)
725
+ File.chown(Etc.getpwnam("nagios").uid, Etc.getpwnam("nagios").gid, dir)
726
+ }
727
+ if realhome != NAGIOS_HOME and Dir.exist?(realhome) and !File.symlink?("#{realhome}/.ssh")
728
+ File.rename("#{realhome}/.ssh", "#{realhome}/.ssh.#{$$}") if Dir.exist?("#{realhome}/.ssh")
729
+ File.symlink("#{NAGIOS_HOME}/.ssh", Etc.getpwnam("nagios").dir+"/.ssh")
730
+ end
731
+ MU.log "Updating #{NAGIOS_HOME}/.ssh/config..."
732
+ ssh_lock = File.new("#{NAGIOS_HOME}/.ssh/config.mu.lock", File::CREAT|File::TRUNC|File::RDWR, 0600)
733
+ ssh_lock.flock(File::LOCK_EX)
734
+ ssh_conf = File.new("#{NAGIOS_HOME}/.ssh/config.tmp", File::CREAT|File::TRUNC|File::RDWR, 0600)
735
+ ssh_conf.puts "Host MU-MASTER localhost"
736
+ ssh_conf.puts " Hostname localhost"
737
+ ssh_conf.puts " User root"
738
+ ssh_conf.puts " IdentityFile #{NAGIOS_HOME}/.ssh/id_rsa"
739
+ ssh_conf.puts " StrictHostKeyChecking no"
740
+ ssh_conf.close
741
+ FileUtils.cp("#{@myhome}/.ssh/id_rsa", "#{NAGIOS_HOME}/.ssh/id_rsa")
742
+ File.chown(Etc.getpwnam("nagios").uid, Etc.getpwnam("nagios").gid, "#{NAGIOS_HOME}/.ssh/id_rsa")
743
+ threads = []
744
+
745
+ parent_thread_id = Thread.current.object_id
746
+ MU::MommaCat.listDeploys.sort.each { |deploy_id|
747
+ begin
748
+ # We don't want to use cached litter information here because this is also called by cleanTerminatedInstances.
749
+ deploy = MU::MommaCat.getLitter(deploy_id)
750
+ if deploy.ssh_key_name.nil? or deploy.ssh_key_name.empty?
751
+ MU.log "Failed to extract ssh key name from #{deploy_id} in syncMonitoringConfig", MU::ERR if deploy.kittens.has_key?("servers")
752
+ next
753
+ end
754
+ FileUtils.cp("#{@myhome}/.ssh/#{deploy.ssh_key_name}", "#{NAGIOS_HOME}/.ssh/#{deploy.ssh_key_name}")
755
+ File.chown(Etc.getpwnam("nagios").uid, Etc.getpwnam("nagios").gid, "#{NAGIOS_HOME}/.ssh/#{deploy.ssh_key_name}")
756
+ if deploy.kittens.has_key?("servers")
757
+ deploy.kittens["servers"].values.each { |nodeclasses|
758
+ nodeclasses.values.each { |nodes|
759
+ nodes.values.each { |server|
760
+ next if !server.cloud_desc
761
+ MU.dupGlobals(parent_thread_id)
762
+ threads << Thread.new {
763
+ MU::MommaCat.setThreadContext(deploy)
764
+ MU.log "Adding #{server.mu_name} to #{NAGIOS_HOME}/.ssh/config", MU::DEBUG
765
+ MU::Master.addHostToSSHConfig(
766
+ server,
767
+ ssh_dir: "#{NAGIOS_HOME}/.ssh",
768
+ ssh_conf: "#{NAGIOS_HOME}/.ssh/config.tmp",
769
+ ssh_owner: "nagios"
770
+ )
771
+ MU.purgeGlobals
772
+ }
773
+ }
774
+ }
775
+ }
776
+ end
777
+ rescue StandardError => e
778
+ MU.log "#{e.inspect} while generating Nagios SSH config in #{deploy_id}", MU::ERR, details: e.backtrace
779
+ end
780
+ }
781
+ threads.each { |t|
782
+ t.join
783
+ }
784
+ ssh_lock.flock(File::LOCK_UN)
785
+ ssh_lock.close
786
+ File.chown(Etc.getpwnam("nagios").uid, Etc.getpwnam("nagios").gid, "#{NAGIOS_HOME}/.ssh/config.tmp")
787
+ File.rename("#{NAGIOS_HOME}/.ssh/config.tmp", "#{NAGIOS_HOME}/.ssh/config")
788
+
789
+ MU.log "Updating Nagios monitoring config, this may take a while..."
790
+ output = nil
791
+ if $MU_CFG and !$MU_CFG['master_runlist_extras'].nil?
792
+ output = %x{#{MU::Groomer::Chef.chefclient} -o 'role[mu-master-nagios-only],#{$MU_CFG['master_runlist_extras'].join(",")}' 2>&1}
793
+ else
794
+ output = %x{#{MU::Groomer::Chef.chefclient} -o 'role[mu-master-nagios-only]' 2>&1}
795
+ end
796
+
797
+ if $?.exitstatus != 0
798
+ MU.log "Nagios monitoring config update returned a non-zero exit code!", MU::ERR, details: output
799
+ else
800
+ MU.log "Nagios monitoring config update complete."
801
+ end
802
+ }
803
+
804
+ if blocking
805
+ nagios_threads.each { |t|
806
+ t.join
807
+ }
808
+ end
809
+ end
810
+
496
811
  end
497
812
  end
@@ -48,7 +48,7 @@ module MU
48
48
  def self.deleteOrg(org)
49
49
  begin
50
50
  Timeout::timeout(45) {
51
- response = chefAPI.delete("organizations/#{org}")
51
+ chefAPI.delete("organizations/#{org}")
52
52
  }
53
53
  MU.log "Removed Chef organization #{org}", MU::NOTICE
54
54
  return true
@@ -82,7 +82,7 @@ module MU
82
82
 
83
83
  begin
84
84
  Timeout::timeout(45) {
85
- response = chefAPI.delete("users/#{chef_user}")
85
+ chefAPI.delete("users/#{chef_user}")
86
86
  }
87
87
  MU.log "Removed Chef user #{chef_user}", MU::NOTICE
88
88
  return true
@@ -200,7 +200,6 @@ module MU
200
200
 
201
201
  # This organization does not yet exist, create it
202
202
  if !existing_org
203
- name = org.dup if fullname.nil?
204
203
  begin
205
204
  org_data = {
206
205
  :name => org.dup,
@@ -255,7 +254,7 @@ module MU
255
254
  }
256
255
  remove_users.each { |user|
257
256
  begin
258
- response = chefAPI.delete("organizations/#{org}/users/#{user}")
257
+ chefAPI.delete("organizations/#{org}/users/#{user}")
259
258
  MU.log "Removed Chef user #{user} from organization #{org}", MU::NOTICE
260
259
  rescue Net::HTTPServerException => e
261
260
  end