cloud-mu 3.1.6 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mu-adopt +4 -12
  3. data/bin/mu-azure-tests +57 -0
  4. data/bin/mu-cleanup +2 -4
  5. data/bin/mu-configure +37 -1
  6. data/bin/mu-deploy +3 -3
  7. data/bin/mu-findstray-tests +25 -0
  8. data/bin/mu-gen-docs +2 -4
  9. data/bin/mu-run-tests +23 -10
  10. data/cloud-mu.gemspec +2 -2
  11. data/cookbooks/mu-tools/libraries/helper.rb +1 -1
  12. data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
  13. data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
  14. data/extras/generate-stock-images +1 -0
  15. data/modules/mu.rb +82 -95
  16. data/modules/mu/adoption.rb +356 -56
  17. data/modules/mu/cleanup.rb +21 -20
  18. data/modules/mu/cloud.rb +79 -1753
  19. data/modules/mu/cloud/database.rb +49 -0
  20. data/modules/mu/cloud/dnszone.rb +46 -0
  21. data/modules/mu/cloud/machine_images.rb +212 -0
  22. data/modules/mu/cloud/providers.rb +81 -0
  23. data/modules/mu/cloud/resource_base.rb +920 -0
  24. data/modules/mu/cloud/server.rb +40 -0
  25. data/modules/mu/cloud/server_pool.rb +1 -0
  26. data/modules/mu/cloud/ssh_sessions.rb +228 -0
  27. data/modules/mu/cloud/winrm_sessions.rb +237 -0
  28. data/modules/mu/cloud/wrappers.rb +165 -0
  29. data/modules/mu/config.rb +122 -80
  30. data/modules/mu/config/alarm.rb +2 -6
  31. data/modules/mu/config/bucket.rb +1 -1
  32. data/modules/mu/config/cache_cluster.rb +1 -1
  33. data/modules/mu/config/collection.rb +1 -1
  34. data/modules/mu/config/container_cluster.rb +2 -2
  35. data/modules/mu/config/database.rb +83 -104
  36. data/modules/mu/config/database.yml +1 -2
  37. data/modules/mu/config/dnszone.rb +1 -1
  38. data/modules/mu/config/doc_helpers.rb +4 -5
  39. data/modules/mu/config/endpoint.rb +1 -1
  40. data/modules/mu/config/firewall_rule.rb +3 -19
  41. data/modules/mu/config/folder.rb +1 -1
  42. data/modules/mu/config/function.rb +1 -1
  43. data/modules/mu/config/group.rb +1 -1
  44. data/modules/mu/config/habitat.rb +1 -1
  45. data/modules/mu/config/loadbalancer.rb +57 -11
  46. data/modules/mu/config/log.rb +1 -1
  47. data/modules/mu/config/msg_queue.rb +1 -1
  48. data/modules/mu/config/nosqldb.rb +1 -1
  49. data/modules/mu/config/notifier.rb +1 -1
  50. data/modules/mu/config/ref.rb +30 -4
  51. data/modules/mu/config/role.rb +1 -1
  52. data/modules/mu/config/schema_helpers.rb +30 -34
  53. data/modules/mu/config/search_domain.rb +1 -1
  54. data/modules/mu/config/server.rb +4 -12
  55. data/modules/mu/config/server_pool.rb +3 -7
  56. data/modules/mu/config/storage_pool.rb +1 -1
  57. data/modules/mu/config/tail.rb +10 -0
  58. data/modules/mu/config/user.rb +1 -1
  59. data/modules/mu/config/vpc.rb +12 -17
  60. data/modules/mu/defaults/AWS.yaml +32 -32
  61. data/modules/mu/defaults/Azure.yaml +1 -0
  62. data/modules/mu/defaults/Google.yaml +1 -0
  63. data/modules/mu/deploy.rb +16 -15
  64. data/modules/mu/groomer.rb +15 -0
  65. data/modules/mu/groomers/chef.rb +3 -0
  66. data/modules/mu/logger.rb +120 -144
  67. data/modules/mu/master.rb +1 -1
  68. data/modules/mu/mommacat.rb +54 -25
  69. data/modules/mu/mommacat/daemon.rb +10 -7
  70. data/modules/mu/mommacat/naming.rb +82 -3
  71. data/modules/mu/mommacat/search.rb +47 -15
  72. data/modules/mu/mommacat/storage.rb +72 -41
  73. data/modules/mu/{clouds → providers}/README.md +1 -1
  74. data/modules/mu/{clouds → providers}/aws.rb +114 -47
  75. data/modules/mu/{clouds → providers}/aws/alarm.rb +1 -1
  76. data/modules/mu/{clouds → providers}/aws/bucket.rb +2 -2
  77. data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +10 -46
  78. data/modules/mu/{clouds → providers}/aws/collection.rb +3 -3
  79. data/modules/mu/{clouds → providers}/aws/container_cluster.rb +15 -33
  80. data/modules/mu/providers/aws/database.rb +1744 -0
  81. data/modules/mu/{clouds → providers}/aws/dnszone.rb +2 -5
  82. data/modules/mu/{clouds → providers}/aws/endpoint.rb +2 -11
  83. data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +33 -29
  84. data/modules/mu/{clouds → providers}/aws/folder.rb +0 -0
  85. data/modules/mu/{clouds → providers}/aws/function.rb +2 -10
  86. data/modules/mu/{clouds → providers}/aws/group.rb +9 -13
  87. data/modules/mu/{clouds → providers}/aws/habitat.rb +1 -1
  88. data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +41 -33
  89. data/modules/mu/{clouds → providers}/aws/log.rb +2 -2
  90. data/modules/mu/{clouds → providers}/aws/msg_queue.rb +2 -8
  91. data/modules/mu/{clouds → providers}/aws/nosqldb.rb +0 -0
  92. data/modules/mu/{clouds → providers}/aws/notifier.rb +0 -0
  93. data/modules/mu/{clouds → providers}/aws/role.rb +7 -7
  94. data/modules/mu/{clouds → providers}/aws/search_domain.rb +8 -13
  95. data/modules/mu/{clouds → providers}/aws/server.rb +55 -90
  96. data/modules/mu/{clouds → providers}/aws/server_pool.rb +10 -33
  97. data/modules/mu/{clouds → providers}/aws/storage_pool.rb +19 -36
  98. data/modules/mu/{clouds → providers}/aws/user.rb +8 -12
  99. data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
  100. data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
  101. data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +0 -0
  102. data/modules/mu/{clouds → providers}/aws/vpc.rb +135 -70
  103. data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
  104. data/modules/mu/{clouds → providers}/azure.rb +4 -1
  105. data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
  106. data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
  107. data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
  108. data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
  109. data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
  110. data/modules/mu/{clouds → providers}/azure/server.rb +30 -23
  111. data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
  112. data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
  113. data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
  114. data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
  115. data/modules/mu/{clouds → providers}/azure/vpc.rb +4 -6
  116. data/modules/mu/{clouds → providers}/cloudformation.rb +1 -1
  117. data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
  118. data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
  119. data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
  120. data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
  121. data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
  122. data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
  123. data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
  124. data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
  125. data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
  126. data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
  127. data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +3 -3
  128. data/modules/mu/{clouds → providers}/docker.rb +0 -0
  129. data/modules/mu/{clouds → providers}/google.rb +14 -6
  130. data/modules/mu/{clouds → providers}/google/bucket.rb +1 -1
  131. data/modules/mu/{clouds → providers}/google/container_cluster.rb +28 -13
  132. data/modules/mu/{clouds → providers}/google/database.rb +1 -8
  133. data/modules/mu/{clouds → providers}/google/firewall_rule.rb +2 -2
  134. data/modules/mu/{clouds → providers}/google/folder.rb +4 -8
  135. data/modules/mu/{clouds → providers}/google/function.rb +3 -3
  136. data/modules/mu/{clouds → providers}/google/group.rb +8 -16
  137. data/modules/mu/{clouds → providers}/google/habitat.rb +3 -7
  138. data/modules/mu/{clouds → providers}/google/loadbalancer.rb +1 -1
  139. data/modules/mu/{clouds → providers}/google/role.rb +42 -34
  140. data/modules/mu/{clouds → providers}/google/server.rb +25 -10
  141. data/modules/mu/{clouds → providers}/google/server_pool.rb +10 -10
  142. data/modules/mu/{clouds → providers}/google/user.rb +31 -21
  143. data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
  144. data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
  145. data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
  146. data/modules/mu/{clouds → providers}/google/vpc.rb +37 -2
  147. data/modules/tests/centos6.yaml +11 -0
  148. data/modules/tests/centos7.yaml +11 -0
  149. data/modules/tests/centos8.yaml +12 -0
  150. data/modules/tests/rds.yaml +108 -0
  151. data/modules/tests/regrooms/rds.yaml +123 -0
  152. data/spec/mu/clouds/azure_spec.rb +2 -2
  153. metadata +108 -89
  154. data/modules/mu/clouds/aws/database.rb +0 -1974
@@ -156,8 +156,8 @@ module MU
156
156
  begin
157
157
  resp = MU::Cloud::AWS.iam(credentials: credentials).list_roles(marker: marker)
158
158
  resp.roles.each{ |role|
159
- # XXX Maybe we should have a more generic way to delete IAM profiles and policies. The call itself should be moved from MU::Cloud::AWS::Server.
160
- # MU::Cloud::AWS::Server.removeIAMProfile(role.role_name) if role.role_name.match(/^#{Regexp.quote(MU.deploy_id)}/)
159
+ # XXX Maybe we should have a more generic way to delete IAM profiles and policies. The call itself should be moved from MU::Cloud.resourceClass("AWS", "Server").
160
+ # MU::Cloud.resourceClass("AWS", "Server").removeIAMProfile(role.role_name) if role.role_name.match(/^#{Regexp.quote(MU.deploy_id)}/)
161
161
  }
162
162
  marker = resp.marker
163
163
  end while resp.is_truncated
@@ -378,9 +378,9 @@ module MU
378
378
 
379
379
  if dom['slow_logs']
380
380
  if configurator.haveLitterMate?(dom['slow_logs'], "log")
381
- dom['dependencies'] << { "name" => dom['slow_logs'], "type" => "log" }
381
+ MU::Config.addDependency(dom, dom['slow_logs'], "log")
382
382
  else
383
- log_group = MU::Cloud::AWS::Log.find(cloud_id: dom['slow_logs'], region: dom['region']).values.first
383
+ log_group = MU::Cloud.resourceClass("AWS", "Log").find(cloud_id: dom['slow_logs'], region: dom['region']).values.first
384
384
  if !log_group
385
385
  MU.log "Specified slow_logs CloudWatch log group '#{dom['slow_logs']}' in SearchDomain '#{dom['name']}' doesn't appear to exist", MU::ERR
386
386
  ok = false
@@ -395,7 +395,7 @@ module MU
395
395
  "credentials" => dom['credentials']
396
396
  }
397
397
  ok = false if !configurator.insertKitten(log_group, "logs")
398
- dom['dependencies'] << { "name" => dom['slow_logs'], "type" => "log" }
398
+ MU::Config.addDependency(dom, dom['slow_logs'], "log")
399
399
  end
400
400
 
401
401
  if dom['advanced_options']
@@ -456,12 +456,7 @@ module MU
456
456
  ]
457
457
  }
458
458
  configurator.insertKitten(roledesc, "roles")
459
-
460
- dom['dependencies'] ||= []
461
- dom['dependencies'] << {
462
- "type" => "role",
463
- "name" => dom['name']+"cognitorole"
464
- }
459
+ MU::Config.addDependency(dom, dom['name']+"cognitorole", "role")
465
460
  end
466
461
 
467
462
  end
@@ -525,7 +520,7 @@ module MU
525
520
  arn = @config['slow_logs']
526
521
  else
527
522
  log_group = @deploy.findLitterMate(type: "log", name: @config['slow_logs'])
528
- log_group = MU::Cloud::AWS::Log.find(cloud_id: log_group.mu_name, region: log_group.cloudobj.config['region']).values.first
523
+ log_group = MU::Cloud.resourceClass("AWS", "Log").find(cloud_id: log_group.mu_name, region: log_group.cloudobj.config['region']).values.first
529
524
  if log_group.nil? or log_group.arn.nil?
530
525
  raise MuError, "Failed to retrieve ARN of sibling LogGroup '#{@config['slow_logs']}'"
531
526
  end
@@ -552,7 +547,7 @@ module MU
552
547
  params[:log_publishing_options]["SEARCH_SLOW_LOGS"] = {}
553
548
  params[:log_publishing_options]["SEARCH_SLOW_LOGS"][:enabled] = true
554
549
  params[:log_publishing_options]["SEARCH_SLOW_LOGS"][:cloud_watch_logs_log_group_arn] = arn
555
- MU::Cloud::AWS::Log.allowService("es.amazonaws.com", arn, @config['region'])
550
+ MU::Cloud.resourceClass("AWS", "Log").allowService("es.amazonaws.com", arn, @config['region'])
556
551
  end
557
552
  end
558
553
 
@@ -145,7 +145,7 @@ module MU
145
145
  raise MuError, "My second argument should be a hash of variables to pass into ERB templates"
146
146
  end
147
147
  $mu = OpenStruct.new(template_variables)
148
- userdata_dir = File.expand_path(MU.myRoot+"/modules/mu/clouds/aws/userdata")
148
+ userdata_dir = File.expand_path(MU.myRoot+"/modules/mu/providers/aws/userdata")
149
149
  platform = "linux" if %w{centos centos6 centos7 ubuntu ubuntu14 rhel rhel7 rhel71 amazon}.include? platform
150
150
  platform = "windows" if %w{win2k12r2 win2k12 win2k8 win2k8r2 win2k16}.include? platform
151
151
  erbfile = "#{userdata_dir}/#{platform}.erb"
@@ -299,7 +299,7 @@ module MU
299
299
  raise MuError, "Got null subnet id out of #{@config['vpc']}"
300
300
  end
301
301
  MU.log "Deploying #{@mu_name} into VPC #{@vpc.cloud_id} Subnet #{subnet.cloud_id}"
302
- punchAdminNAT
302
+ allowBastionAccess
303
303
  instance_descriptor[:subnet_id] = subnet.cloud_id
304
304
  end
305
305
 
@@ -399,13 +399,13 @@ module MU
399
399
  # Figure out what's needed to SSH into this server.
400
400
  # @return [Array<String>]: nat_ssh_key, nat_ssh_user, nat_ssh_host, canonical_ip, ssh_user, ssh_key_name, alternate_names
401
401
  def getSSHConfig
402
- describe(cloud_id: @cloud_id)
402
+ cloud_desc(use_cache: false) # make sure we're current
403
403
  # XXX add some awesome alternate names from metadata and make sure they end
404
404
  # up in MU::MommaCat's ssh config wangling
405
405
  return nil if @config.nil? or @deploy.nil?
406
406
 
407
407
  nat_ssh_key = nat_ssh_user = nat_ssh_host = nil
408
- if !@config["vpc"].nil? and !MU::Cloud::AWS::VPC.haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
408
+ if !@config["vpc"].nil? and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
409
409
  if !@nat.nil?
410
410
  if @nat.is_a?(Struct) && @nat.nat_gateway_id && @nat.nat_gateway_id.start_with?("nat-")
411
411
  raise MuError, "Configured to use NAT Gateway, but I have no route to instance. Either use Bastion, or configure VPC peering"
@@ -444,8 +444,7 @@ module MU
444
444
  # administravia for a new instance.
445
445
  def postBoot(instance_id = nil)
446
446
  @cloud_id ||= instance_id
447
- node, _config, deploydata = describe(cloud_id: @cloud_id)
448
- @mu_name ||= node
447
+ _node, _config, deploydata = describe(cloud_id: @cloud_id)
449
448
 
450
449
  raise MuError, "Couldn't find instance #{@mu_name} (#{@cloud_id})" if !cloud_desc
451
450
  return false if !MU::MommaCat.lock(@cloud_id+"-orchestrate", true)
@@ -482,7 +481,7 @@ module MU
482
481
  end
483
482
  }
484
483
 
485
- punchAdminNAT
484
+ allowBastionAccess
486
485
 
487
486
  setAlarms
488
487
 
@@ -615,7 +614,7 @@ module MU
615
614
  return nil
616
615
  end
617
616
 
618
- asgs = MU::Cloud::AWS::ServerPool.find(
617
+ asgs = MU::Cloud.resourceClass("AWS", "ServerPool").find(
619
618
  instance_id: @cloud_id,
620
619
  region: @config['region'],
621
620
  credentials: @credentials
@@ -725,15 +724,15 @@ module MU
725
724
 
726
725
  if int.groups.size > 0
727
726
 
728
- require 'mu/clouds/aws/firewall_rule'
729
- ifaces = MU::Cloud::AWS::FirewallRule.getAssociatedInterfaces(int.groups.map { |sg| sg.group_id }, credentials: @credentials, region: @config['region'])
727
+ require 'mu/providers/aws/firewall_rule'
728
+ ifaces = MU::Cloud.resourceClass("AWS", "FirewallRule").getAssociatedInterfaces(int.groups.map { |sg| sg.group_id }, credentials: @credentials, region: @config['region'])
730
729
  done_local_rules = false
731
730
  int.groups.each { |sg|
732
731
  if !done_local_rules and ifaces[sg.group_id].size == 1
733
- sg_desc = MU::Cloud::AWS::FirewallRule.find(cloud_id: sg.group_id, credentials: @credentials, region: @config['region']).values.first
732
+ sg_desc = MU::Cloud.resourceClass("AWS", "FirewallRule").find(cloud_id: sg.group_id, credentials: @credentials, region: @config['region']).values.first
734
733
  if sg_desc
735
- bok["ingress_rules"] = MU::Cloud::AWS::FirewallRule.rulesToBoK(sg_desc.ip_permissions)
736
- bok["ingress_rules"].concat(MU::Cloud::AWS::FirewallRule.rulesToBoK(sg_desc.ip_permissions_egress, egress: true))
734
+ bok["ingress_rules"] = MU::Cloud.resourceClass("AWS", "FirewallRule").rulesToBoK(sg_desc.ip_permissions)
735
+ bok["ingress_rules"].concat(MU::Cloud.resourceClass("AWS", "FirewallRule").rulesToBoK(sg_desc.ip_permissions_egress, egress: true))
737
736
  done_local_rules = true
738
737
  next
739
738
  end
@@ -802,44 +801,13 @@ module MU
802
801
  end
803
802
  deploydata["region"] = @config['region'] if !@config['region'].nil?
804
803
  if !@named
805
- MU::MommaCat.nameKitten(self)
804
+ MU::MommaCat.nameKitten(self, no_dns: true)
806
805
  @named = true
807
806
  end
808
807
 
809
808
  return deploydata
810
809
  end
811
810
 
812
- # If the specified server is in a VPC, and has a NAT, make sure we'll
813
- # be letting ssh traffic in from said NAT.
814
- def punchAdminNAT
815
- if @config['vpc'].nil? or
816
- (
817
- !@config['vpc'].has_key?("nat_host_id") and
818
- !@config['vpc'].has_key?("nat_host_tag") and
819
- !@config['vpc'].has_key?("nat_host_ip") and
820
- !@config['vpc'].has_key?("nat_host_name")
821
- )
822
- return nil
823
- end
824
-
825
- return nil if @nat.is_a?(Struct) && @nat.nat_gateway_id && @nat.nat_gateway_id.start_with?("nat-")
826
-
827
- dependencies if @nat.nil?
828
- if @nat.nil? or @nat.cloud_desc.nil?
829
- raise MuError, "#{@mu_name} (#{MU.deploy_id}) is configured to use #{@config['vpc']} but I can't find the cloud descriptor for a matching NAT instance"
830
- end
831
- MU.log "Adding administrative holes for NAT host #{@nat.cloud_desc.private_ip_address} to #{@mu_name}"
832
- if !@deploy.kittens['firewall_rules'].nil?
833
- @deploy.kittens['firewall_rules'].values.each { |acl|
834
- if acl.config["admin"]
835
- acl.addRule([@nat.cloud_desc.private_ip_address], proto: "tcp")
836
- acl.addRule([@nat.cloud_desc.private_ip_address], proto: "udp")
837
- acl.addRule([@nat.cloud_desc.private_ip_address], proto: "icmp")
838
- end
839
- }
840
- end
841
- end
842
-
843
811
  # Called automatically by {MU::Deploy#createResources}
844
812
  def groom
845
813
  MU::MommaCat.lock(@cloud_id+"-groom")
@@ -851,7 +819,7 @@ module MU
851
819
  end
852
820
  end
853
821
 
854
- punchAdminNAT
822
+ allowBastionAccess
855
823
 
856
824
  tagVolumes
857
825
 
@@ -883,12 +851,25 @@ module MU
883
851
 
884
852
  begin
885
853
  getIAMProfile
854
+
855
+ dbs = @deploy.findLitterMate(type: "database", return_all: true)
856
+ if dbs
857
+ dbs.each_pair { |sib_name, sib|
858
+ @groomer.groomer_class.grantSecretAccess(@mu_name, sib_name, "database_credentials")
859
+ if sib.config and sib.config['auth_vault']
860
+ @groomer.groomer_class.grantSecretAccess(@mu_name, sib.config['auth_vault']['vault'], sib.config['auth_vault']['item'])
861
+ end
862
+ }
863
+ end
864
+
886
865
  if @config['groom'].nil? or @config['groom']
887
866
  @groomer.run(purpose: "Full Initial Run", max_retries: 15, reboot_first_fail: (windows? and @config['groomer'] != "Ansible"), timeout: @config['groomer_timeout'])
888
867
  end
889
868
  rescue MU::Groomer::RunError => e
869
+ raise e if !@config['create_image'].nil? and !@config['image_created']
890
870
  MU.log "Proceeding after failed initial Groomer run, but #{@mu_name} may not behave as expected!", MU::WARN, details: e.message
891
871
  rescue StandardError => e
872
+ raise e if !@config['create_image'].nil? and !@config['image_created']
892
873
  MU.log "Caught #{e.inspect} on #{@mu_name} in an unexpected place (after @groomer.run on Full Initial Run)", MU::ERR
893
874
  end
894
875
 
@@ -961,7 +942,7 @@ module MU
961
942
  # Our deploydata gets corrupted often with server pools, this will cause us to use the wrong IP to identify a node
962
943
  # which will cause us to create certificates, DNS records and other artifacts with incorrect information which will cause our deploy to fail.
963
944
  # The cloud_id is always correct so lets use 'cloud_desc' to get the correct IPs
964
- if MU::Cloud::AWS::VPC.haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials']) or @deploydata["public_ip_address"].nil?
945
+ if MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials']) or @deploydata["public_ip_address"].nil?
965
946
  @config['canonical_ip'] = cloud_desc.private_ip_address
966
947
  @deploydata["private_ip_address"] = cloud_desc.private_ip_address
967
948
  return cloud_desc.private_ip_address
@@ -1181,10 +1162,7 @@ module MU
1181
1162
  end
1182
1163
  end
1183
1164
 
1184
- if @cloud_id.nil?
1185
- describe
1186
- @cloud_id = cloud_desc.instance_id
1187
- end
1165
+ @cloud_id ||= cloud_desc(use_cache: false).instance_id
1188
1166
  ssh_keydir = "#{Etc.getpwuid(Process.uid).dir}/.ssh"
1189
1167
  ssh_key_name = @deploy.ssh_key_name
1190
1168
 
@@ -1318,7 +1296,7 @@ module MU
1318
1296
 
1319
1297
  if @deploy
1320
1298
  MU::Cloud::AWS.createStandardTags(
1321
- resource_id,
1299
+ creation.volume_id,
1322
1300
  region: @config['region'],
1323
1301
  credentials: @config['credentials'],
1324
1302
  optional: @config['optional_tags'],
@@ -1577,7 +1555,11 @@ module MU
1577
1555
  return if !instance
1578
1556
 
1579
1557
  id ||= instance.instance_id
1580
- MU::MommaCat.lock(".cleanup-"+id)
1558
+ begin
1559
+ MU::MommaCat.lock(".cleanup-"+id)
1560
+ rescue Errno::ENOENT => e
1561
+ MU.log "No lock for terminating instance #{id} due to missing metadata", MU::DEBUG
1562
+ end
1581
1563
 
1582
1564
  ips, names = getAddresses(instance, region: region, credentials: credentials)
1583
1565
  targets = ips +names
@@ -1632,7 +1614,11 @@ module MU
1632
1614
  end
1633
1615
 
1634
1616
  MU.log "#{instance.instance_id}#{server_obj ? " ("+server_obj.mu_name+")" : ""} terminated" if !noop
1635
- MU::MommaCat.unlock(".cleanup-"+id)
1617
+ begin
1618
+ MU::MommaCat.unlock(".cleanup-"+id)
1619
+ rescue Errno::ENOENT => e
1620
+ MU.log "No lock for terminating instance #{id} due to missing metadata", MU::DEBUG
1621
+ end
1636
1622
 
1637
1623
  end
1638
1624
 
@@ -1690,26 +1676,7 @@ module MU
1690
1676
  "type" => "object"
1691
1677
  }
1692
1678
  },
1693
- "ingress_rules" => {
1694
- "items" => {
1695
- "properties" => {
1696
- "sgs" => {
1697
- "type" => "array",
1698
- "items" => {
1699
- "description" => "Other AWS Security Groups; resources that are associated with this group will have this rule applied to their traffic",
1700
- "type" => "string"
1701
- }
1702
- },
1703
- "lbs" => {
1704
- "type" => "array",
1705
- "items" => {
1706
- "description" => "AWS Load Balancers which will have this rule applied to their traffic",
1707
- "type" => "string"
1708
- }
1709
- }
1710
- }
1711
- }
1712
- },
1679
+ "ingress_rules" => MU::Cloud.resourceClass("AWS", "FirewallRule").ingressRuleAddtlSchema,
1713
1680
  "ssh_user" => {
1714
1681
  "type" => "string",
1715
1682
  "default" => "root",
@@ -1777,8 +1744,7 @@ module MU
1777
1744
 
1778
1745
  MU::Cloud.availableClouds.each { |cloud|
1779
1746
  next if cloud == "AWS"
1780
- cloudbase = Object.const_get("MU").const_get("Cloud").const_get(cloud)
1781
- foreign_types = (cloudbase.listInstanceTypes).values.first
1747
+ foreign_types = (MU::Cloud.cloudClass(cloud).listInstanceTypes).values.first
1782
1748
  if foreign_types.size == 1
1783
1749
  foreign_types = foreign_types.values.first
1784
1750
  end
@@ -1845,12 +1811,7 @@ module MU
1845
1811
  end
1846
1812
 
1847
1813
  configurator.insertKitten(role, "roles")
1848
-
1849
- server["dependencies"] ||= []
1850
- server["dependencies"] << {
1851
- "type" => "role",
1852
- "name" => server["name"]
1853
- }
1814
+ MU::Config.addDependency(server, server["name"], "role")
1854
1815
  end
1855
1816
 
1856
1817
  # Cloud-specific pre-processing of {MU::Config::BasketofKittens::servers}, bare and unvalidated.
@@ -1901,10 +1862,7 @@ module MU
1901
1862
  server["loadbalancers"].each { |lb|
1902
1863
  lb["name"] ||= lb["concurrent_load_balancer"]
1903
1864
  if lb["name"]
1904
- server["dependencies"] << {
1905
- "type" => "loadbalancer",
1906
- "name" => lb["name"]
1907
- }
1865
+ MU::Config.addDependency(server, lb["name"], "loadbalancer")
1908
1866
  end
1909
1867
  }
1910
1868
  end
@@ -2019,6 +1977,13 @@ module MU
2019
1977
  configured_storage
2020
1978
  end
2021
1979
 
1980
+ # Return all of the IP addresses, public and private, from all of our
1981
+ # network interfaces.
1982
+ # @return [Array<String>]
1983
+ def listIPs
1984
+ MU::Cloud::AWS::Server.getAddresses(cloud_desc).first
1985
+ end
1986
+
2022
1987
  private
2023
1988
 
2024
1989
  def bootstrapGroomer
@@ -2144,7 +2109,7 @@ module MU
2144
2109
  subnet = @vpc.getSubnet(cloud_id: cloud_desc.subnet_id)
2145
2110
 
2146
2111
  _nat_ssh_key, _nat_ssh_user, nat_ssh_host, _canonical_ip, _ssh_user, _ssh_key_name = getSSHConfig
2147
- if subnet.private? and !nat_ssh_host and !MU::Cloud::AWS::VPC.haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
2112
+ if subnet.private? and !nat_ssh_host and !MU::Cloud.resourceClass("AWS", "VPC").haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
2148
2113
  raise MuError, "#{@mu_name} is in a private subnet (#{subnet}), but has no bastion host configured, and I have no other route to it"
2149
2114
  end
2150
2115
 
@@ -2236,15 +2201,15 @@ module MU
2236
2201
  alarm["dimensions"] = [{:name => "InstanceId", :value => @cloud_id}]
2237
2202
 
2238
2203
  if alarm["enable_notifications"]
2239
- topic_arn = MU::Cloud::AWS::Notification.createTopic(alarm["notification_group"], region: @config["region"], credentials: @config['credentials'])
2240
- MU::Cloud::AWS::Notification.subscribe(arn: topic_arn, protocol: alarm["notification_type"], endpoint: alarm["notification_endpoint"], region: @config["region"], credentials: @config["credentials"])
2204
+ topic_arn = MU::Cloud.resourceClass("AWS", "Notification").createTopic(alarm["notification_group"], region: @config["region"], credentials: @config['credentials'])
2205
+ MU::Cloud.resourceClass("AWS", "Notification").subscribe(arn: topic_arn, protocol: alarm["notification_type"], endpoint: alarm["notification_endpoint"], region: @config["region"], credentials: @config["credentials"])
2241
2206
  alarm["alarm_actions"] = [topic_arn]
2242
2207
  alarm["ok_actions"] = [topic_arn]
2243
2208
  end
2244
2209
 
2245
2210
  alarm_name = alarm_obj ? alarm_obj.cloud_id : "#{@mu_name}-#{alarm['name']}".upcase
2246
2211
 
2247
- MU::Cloud::AWS::Alarm.setAlarm(
2212
+ MU::Cloud.resourceClass("AWS", "Alarm").setAlarm(
2248
2213
  name: alarm_name,
2249
2214
  ok_actions: alarm["ok_actions"],
2250
2215
  alarm_actions: alarm["alarm_actions"],
@@ -120,7 +120,7 @@ module MU
120
120
  if !@deploy.nocleanup
121
121
  Thread.new {
122
122
  MU.dupGlobals(parent_thread_id)
123
- MU::Cloud::AWS::Server.terminateInstance(id: member.instance_id)
123
+ MU::Cloud.resourceClass("AWS", "Server").terminateInstance(id: member.instance_id)
124
124
  }
125
125
  end
126
126
  end
@@ -813,26 +813,7 @@ module MU
813
813
  }
814
814
  }
815
815
  },
816
- "ingress_rules" => {
817
- "items" => {
818
- "properties" => {
819
- "sgs" => {
820
- "type" => "array",
821
- "items" => {
822
- "description" => "Other AWS Security Groups; resources that are associated with this group will have this rule applied to their traffic",
823
- "type" => "string"
824
- }
825
- },
826
- "lbs" => {
827
- "type" => "array",
828
- "items" => {
829
- "description" => "AWS Load Balancers which will have this rule applied to their traffic",
830
- "type" => "string"
831
- }
832
- }
833
- }
834
- }
835
- }
816
+ "ingress_rules" => MU::Cloud.resourceClass("AWS", "FirewallRule").ingressRuleAddtlSchema
836
817
  }
837
818
  [toplevel_required, schema]
838
819
  end
@@ -905,7 +886,7 @@ module MU
905
886
  launch = pool["basis"]["launch_config"]
906
887
  launch['iam_policies'] ||= pool['iam_policies']
907
888
 
908
- launch['size'] = MU::Cloud::AWS::Server.validateInstanceType(launch["size"], pool["region"])
889
+ launch['size'] = MU::Cloud.resourceClass("AWS", "Server").validateInstanceType(launch["size"], pool["region"])
909
890
  ok = false if launch['size'].nil?
910
891
  if !launch['generate_iam_role']
911
892
  if !launch['iam_role'] and pool['cloud'] != "CloudFormation"
@@ -949,11 +930,7 @@ module MU
949
930
 
950
931
  role['credentials'] = pool['credentials'] if pool['credentials']
951
932
  configurator.insertKitten(role, "roles")
952
- pool["dependencies"] ||= []
953
- pool["dependencies"] << {
954
- "type" => "role",
955
- "name" => pool["name"]
956
- }
933
+ MU::Config.addDependency(pool, pool['name'], "role")
957
934
  end
958
935
  launch["ami_id"] ||= launch["image_id"]
959
936
  if launch["server"].nil? and launch["instance_id"].nil? and launch["ami_id"].nil?
@@ -967,7 +944,7 @@ module MU
967
944
  end
968
945
  end
969
946
  if launch["server"] != nil
970
- pool["dependencies"] << {"type" => "server", "name" => launch["server"]}
947
+ MU::Config.addDependency(pool, launch["server"], "server", phase: "groom")
971
948
  # XXX I dunno, maybe toss an error if this isn't done already
972
949
  # servers.each { |server|
973
950
  # if server["name"] == launch["server"]
@@ -1123,7 +1100,7 @@ module MU
1123
1100
  end
1124
1101
  end
1125
1102
 
1126
- # MU::Cloud::AWS::Server.removeIAMProfile(resource_id)
1103
+ # MU::Cloud.resourceClass("AWS", "Server").removeIAMProfile(resource_id)
1127
1104
 
1128
1105
  # Generally there should be a launch_configuration of the same name
1129
1106
  # XXX search for these independently, too?
@@ -1164,14 +1141,14 @@ module MU
1164
1141
  @config['basis']['launch_config']["ami_id"] = @deploy.deployment["images"][@config['basis']['launch_config']["server"]]["image_id"]
1165
1142
  MU.log "Using AMI '#{@config['basis']['launch_config']["ami_id"]}' from sibling server #{@config['basis']['launch_config']["server"]} in ServerPool #{@mu_name}"
1166
1143
  elsif !@config['basis']['launch_config']["instance_id"].nil?
1167
- @config['basis']['launch_config']["ami_id"] = MU::Cloud::AWS::Server.createImage(
1144
+ @config['basis']['launch_config']["ami_id"] = MU::Cloud.resourceClass("AWS", "Server").createImage(
1168
1145
  name: @mu_name,
1169
1146
  instance_id: @config['basis']['launch_config']["instance_id"],
1170
1147
  credentials: @config['credentials'],
1171
1148
  region: @config['region']
1172
1149
  )[@config['region']]
1173
1150
  end
1174
- MU::Cloud::AWS::Server.waitForAMI(@config['basis']['launch_config']["ami_id"], credentials: @config['credentials'])
1151
+ MU::Cloud.resourceClass("AWS", "Server").waitForAMI(@config['basis']['launch_config']["ami_id"], credentials: @config['credentials'])
1175
1152
 
1176
1153
  oldlaunch = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_launch_configurations(
1177
1154
  launch_configuration_names: [@mu_name]
@@ -1226,12 +1203,12 @@ module MU
1226
1203
  vol.delete("encrypted")
1227
1204
  end
1228
1205
  end
1229
- mapping, _cfm_mapping = MU::Cloud::AWS::Server.convertBlockDeviceMapping(vol)
1206
+ mapping, _cfm_mapping = MU::Cloud.resourceClass("AWS", "Server").convertBlockDeviceMapping(vol)
1230
1207
  storage << mapping
1231
1208
  }
1232
1209
  end
1233
1210
 
1234
- storage.concat(MU::Cloud::AWS::Server.ephemeral_mappings)
1211
+ storage.concat(MU::Cloud.resourceClass("AWS", "Server").ephemeral_mappings)
1235
1212
 
1236
1213
  if @config['basis']['launch_config']['generate_iam_role']
1237
1214
  role = @deploy.findLitterMate(name: @config['name'], type: "roles")