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
@@ -129,13 +129,13 @@ module MU
129
129
 
130
130
  if launch_desc["storage"]
131
131
  launch_desc["storage"].each { |vol|
132
- mapping, cfm_mapping = MU::Cloud::AWS::Server.convertBlockDeviceMapping(vol)
132
+ mapping, cfm_mapping = MU::Cloud.resourceClass("AWS", "Server").convertBlockDeviceMapping(vol)
133
133
  if cfm_mapping.size > 0
134
134
  MU::Cloud::CloudFormation.setCloudFormationProp(@cfm_template[@cfm_launch_name], "BlockDeviceMappings", cfm_mapping)
135
135
  end
136
136
  }
137
137
  end
138
- MU::Cloud::AWS::Server.ephemeral_mappings.each { |mapping|
138
+ MU::Cloud.resourceClass("AWS", "Server.ephemeral_mappings").each { |mapping|
139
139
  MU::Cloud::CloudFormation.setCloudFormationProp(@cfm_template[@cfm_launch_name], "BlockDeviceMappings", { "DeviceName" => mapping[:device_name], "VirtualName" => mapping[:virtual_name] })
140
140
  }
141
141
 
@@ -263,7 +263,7 @@ module MU
263
263
  # @param config [MU::Config]: The calling MU::Config object
264
264
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
265
265
  def self.schema(config)
266
- MU::Cloud::AWS::ServerPool.schema(config)
266
+ MU::Cloud.resourceClass("AWS", "ServerPool").schema(config)
267
267
  end
268
268
 
269
269
  # Cloud-specific pre-processing of {MU::Config::BasketofKittens::servers}, bare and unvalidated.
@@ -271,14 +271,14 @@ module MU
271
271
  # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
272
272
  # @return [Boolean]: True if validation succeeded, False otherwise
273
273
  def self.validateConfig(server, configurator)
274
- MU::Cloud::AWS::ServerPool.validateConfig(server, configurator)
274
+ MU::Cloud.resourceClass("AWS", "ServerPool").validateConfig(server, configurator)
275
275
  end
276
276
 
277
277
  # Does this resource type exist as a global (cloud-wide) artifact, or
278
278
  # is it localized to a region/zone?
279
279
  # @return [Boolean]
280
280
  def self.isGlobal?
281
- MU::Cloud::AWS::ServerPool.isGlobal?
281
+ MU::Cloud.resourceClass("AWS", "ServerPool").isGlobal?
282
282
  end
283
283
 
284
284
  end
@@ -301,7 +301,7 @@ module MU
301
301
  # @param config [MU::Config]: The calling MU::Config object
302
302
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
303
303
  def self.schema(config)
304
- MU::Cloud::AWS::VPC.schema(config)
304
+ MU::Cloud.resourceClass("AWS", "VPC").schema(config)
305
305
  end
306
306
 
307
307
  # Cloud-specific pre-processing of {MU::Config::BasketofKittens::servers}, bare and unvalidated.
@@ -309,14 +309,14 @@ module MU
309
309
  # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
310
310
  # @return [Boolean]: True if validation succeeded, False otherwise
311
311
  def self.validateConfig(server, configurator)
312
- MU::Cloud::AWS::VPC.validateConfig(server, configurator)
312
+ MU::Cloud.resourceClass("AWS", "VPC").validateConfig(server, configurator)
313
313
  end
314
314
 
315
315
  # Does this resource type exist as a global (cloud-wide) artifact, or
316
316
  # is it localized to a region/zone?
317
317
  # @return [Boolean]
318
318
  def self.isGlobal?
319
- MU::Cloud::AWS::VPC.isGlobal?
319
+ MU::Cloud.resourceClass("AWS", "VPC").isGlobal?
320
320
  end
321
321
 
322
322
  end #class
@@ -236,7 +236,7 @@ module MU
236
236
  # @param sibling_only [Boolean]
237
237
  # @return [MU::Config::Habitat,nil]
238
238
  def self.projectLookup(name, deploy = MU.mommacat, raise_on_fail: true, sibling_only: false)
239
- project_obj = deploy.findLitterMate(type: "habitats", name: name) if deploy
239
+ project_obj = deploy.findLitterMate(type: "habitats", name: name) if deploy if !caller.grep(/`findLitterMate'/) # XXX the dumbest
240
240
 
241
241
  if !project_obj and !sibling_only
242
242
  resp = MU::MommaCat.findStray(
@@ -706,21 +706,26 @@ MU.log e.message, MU::WARN, details: e.inspect
706
706
  nil
707
707
  end
708
708
 
709
+ @allprojects = []
710
+
709
711
  # List all Google Cloud Platform projects available to our credentials
710
- def self.listHabitats(credentials = nil)
712
+ def self.listHabitats(credentials = nil, use_cache: true)
711
713
  cfg = credConfig(credentials)
712
714
  return [] if !cfg
713
715
  if cfg['restrict_to_habitats'] and cfg['restrict_to_habitats'].is_a?(Array)
714
716
  cfg['restrict_to_habitats'] << cfg['project'] if cfg['project']
715
717
  return cfg['restrict_to_habitats'].uniq
716
718
  end
719
+ if @allprojects and !@allprojects.empty? and use_cache
720
+ return @allprojects
721
+ end
717
722
  result = MU::Cloud::Google.resource_manager(credentials: credentials).list_projects
718
723
  result.projects.reject! { |p| p.lifecycle_state == "DELETE_REQUESTED" }
719
- allprojects = result.projects.map { |p| p.project_id }
724
+ @allprojects = result.projects.map { |p| p.project_id }
720
725
  if cfg['ignore_habitats'] and cfg['ignore_habitats'].is_a?(Array)
721
- allprojects.reject! { |p| cfg['ignore_habitats'].include?(p) }
726
+ @allprojects.reject! { |p| cfg['ignore_habitats'].include?(p) }
722
727
  end
723
- allprojects
728
+ @allprojects
724
729
  end
725
730
 
726
731
  @@regions = {}
@@ -1025,8 +1030,10 @@ MU.log e.message, MU::WARN, details: e.inspect
1025
1030
  "default"
1026
1031
  end
1027
1032
 
1033
+ with_id ||= creds['org'] if creds['org']
1028
1034
  return @@orgmap[credname] if @@orgmap.has_key?(credname)
1029
1035
  resp = MU::Cloud::Google.resource_manager(credentials: credname).search_organizations
1036
+
1030
1037
  if resp and resp.organizations
1031
1038
  # XXX no idea if it's possible to be a member of multiple orgs
1032
1039
  if !with_id
@@ -1034,7 +1041,8 @@ MU.log e.message, MU::WARN, details: e.inspect
1034
1041
  return resp.organizations.first
1035
1042
  else
1036
1043
  resp.organizations.each { |org|
1037
- if org.name == with_id
1044
+ if org.name == with_id or org.display_name == with_id or
1045
+ org.name == "organizations/#{with_id}"
1038
1046
  @@orgmap[credname] = org
1039
1047
  return org
1040
1048
  end
@@ -243,7 +243,7 @@ module MU
243
243
  grantees[binding.role] << { "id" => grantee }
244
244
  elsif grantee.match(/^serviceAccount:(.*)/)
245
245
  sa_name = Regexp.last_match[1]
246
- if MU::Cloud::Google::User.cannedServiceAcctName?(sa_name)
246
+ if MU::Cloud.resourceClass("Google", "User").cannedServiceAcctName?(sa_name)
247
247
  grantees[binding.role] << { "id" => grantee }
248
248
  else
249
249
  grantees[binding.role] << MU::Config::Ref.get(
@@ -657,7 +657,7 @@ module MU
657
657
  end
658
658
 
659
659
  if bok['service_account']
660
- found = MU::Cloud::Google::User.find(
660
+ found = MU::Cloud.resourceClass("Google", "User").find(
661
661
  credentials: bok['credentials'],
662
662
  project: bok['project'],
663
663
  cloud_id: bok['service_account']
@@ -747,7 +747,7 @@ module MU
747
747
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
748
748
 
749
749
  flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
750
- return if !MU::Cloud::Google::Habitat.isLive?(flags["habitat"], credentials)
750
+ return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
751
751
  clusters = []
752
752
 
753
753
  # Make sure we catch regional *and* zone clusters
@@ -817,10 +817,10 @@ module MU
817
817
  "type" => "integer",
818
818
  "description" => "The number of local SSD disks to be attached to workers. See https://cloud.google.com/compute/docs/disks/local-ssd#local_ssd_limits"
819
819
  },
820
- "ssh_user" => MU::Cloud::Google::Server.schema(config)[1]["ssh_user"],
821
- "metadata" => MU::Cloud::Google::Server.schema(config)[1]["metadata"],
822
- "service_account" => MU::Cloud::Google::Server.schema(config)[1]["service_account"],
823
- "scopes" => MU::Cloud::Google::Server.schema(config)[1]["scopes"],
820
+ "ssh_user" => MU::Cloud.resourceClass("Google", "Server").schema(config)[1]["ssh_user"],
821
+ "metadata" => MU::Cloud.resourceClass("Google", "Server").schema(config)[1]["metadata"],
822
+ "service_account" => MU::Cloud.resourceClass("Google", "Server").schema(config)[1]["service_account"],
823
+ "scopes" => MU::Cloud.resourceClass("Google", "Server").schema(config)[1]["scopes"],
824
824
  "private_cluster" => {
825
825
  "description" => "Set a GKE cluster to be private, that is segregated into its own hidden VPC.",
826
826
  "type" => "object",
@@ -1021,6 +1021,25 @@ module MU
1021
1021
  cluster['ip_aliases'] = true
1022
1022
  end
1023
1023
 
1024
+ # try to stake out some nice /21s for our networking config
1025
+ if cluster['ip_aliases'] and cluster["vpc"] and cluster["vpc"]["id"]
1026
+ habarg = if cluster["vpc"]["habitat"] and cluster["vpc"]["habitat"]["id"]
1027
+ cluster["vpc"]["habitat"]["id"]
1028
+ else
1029
+ cluster["project"]
1030
+ end
1031
+ found = MU::MommaCat.findStray("Google", "vpcs", cloud_id: cluster["vpc"]["id"], credentials: cluster["credentials"], habitats: [habarg], dummy_ok: true)
1032
+ if found and found.size == 1
1033
+ myvpc = found.first
1034
+ # XXX this might not make sense with custom_subnet
1035
+ cluster['pod_ip_block'] ||= myvpc.getUnusedAddressBlock(max_bits: 21)
1036
+ cluster['services_ip_block'] ||= myvpc.getUnusedAddressBlock(exclude: [cluster['pod_ip_block']], max_bits: 21)
1037
+ if cluster['tpu']
1038
+ cluster['tpu_ip_block'] ||= myvpc.getUnusedAddressBlock(exclude: [cluster['pod_ip_block'], cluster['services_ip_block']], max_bits: 21)
1039
+ end
1040
+ end
1041
+ end
1042
+
1024
1043
  if cluster['service_account']
1025
1044
  cluster['service_account']['cloud'] = "Google"
1026
1045
  cluster['service_account']['habitat'] ||= MU::Config::Ref.get(
@@ -1032,11 +1051,7 @@ module MU
1032
1051
  if cluster['service_account']['name'] and
1033
1052
  !cluster['service_account']['id'] and
1034
1053
  !cluster['service_account']['deploy_id']
1035
- cluster['dependencies'] ||= []
1036
- cluster['dependencies'] << {
1037
- "type" => "user",
1038
- "name" => cluster['service_account']['name']
1039
- }
1054
+ MU::Config.addDependency(cluster, cluster['service_account']['name'], "user")
1040
1055
  end
1041
1056
  found = MU::Config::Ref.get(cluster['service_account'])
1042
1057
  # XXX verify that found.kitten fails when it's supposed to
@@ -1045,7 +1060,7 @@ module MU
1045
1060
  ok = false
1046
1061
  end
1047
1062
  else
1048
- cluster = MU::Cloud::Google::User.genericServiceAccount(cluster, configurator)
1063
+ cluster = MU::Cloud.resourceClass("Google", "User").genericServiceAccount(cluster, configurator)
1049
1064
  end
1050
1065
 
1051
1066
  if cluster['dependencies']
@@ -1141,7 +1156,7 @@ module MU
1141
1156
  end
1142
1157
  end
1143
1158
 
1144
- cluster['instance_type'] = MU::Cloud::Google::Server.validateInstanceType(cluster["instance_type"], cluster["region"], project: cluster['project'], credentials: cluster['credentials'])
1159
+ cluster['instance_type'] = MU::Cloud.resourceClass("Google", "Server").validateInstanceType(cluster["instance_type"], cluster["region"], project: cluster['project'], credentials: cluster['credentials'])
1145
1160
  ok = false if cluster['instance_type'].nil?
1146
1161
 
1147
1162
  if !MU::Master.kubectl
@@ -25,14 +25,7 @@ module MU
25
25
  @config["groomer"] = MU::Config.defaultGroomer unless @config["groomer"]
26
26
  @groomclass = MU::Groomer.loadGroomer(@config["groomer"])
27
27
 
28
- @mu_name ||=
29
- if @config and @config['engine'] and @config["engine"].match(/^sqlserver/)
30
- @deploy.getResourceName(@config["name"], max_length: 15)
31
- else
32
- @deploy.getResourceName(@config["name"], max_length: 63)
33
- end
34
-
35
- @mu_name.gsub(/(--|-$)/i, "").gsub(/(_)/, "-").gsub!(/^[^a-z]/i, "")
28
+ @mu_name ||= @deploy.getResourceName(@config["name"], max_length: 63)
36
29
  end
37
30
 
38
31
  # Called automatically by {MU::Deploy#createResources}
@@ -209,7 +209,7 @@ end
209
209
  # @return [void]
210
210
  def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
211
211
  flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
212
- return if !MU::Cloud::Google::Habitat.isLive?(flags["habitat"], credentials)
212
+ return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
213
213
  filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
214
214
  if !ignoremaster and MU.mu_public_ip
215
215
  filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
@@ -440,7 +440,7 @@ end
440
440
  elsif acl['vpc']['habitat'] and acl['vpc']['habitat']['name']
441
441
  acl['vpc']['project'] = acl['vpc']['habitat']['name']
442
442
  end
443
- correct_vpc = MU::Cloud::Google::VPC.pickVPC(
443
+ correct_vpc = MU::Cloud.resourceClass("Google", "VPC").pickVPC(
444
444
  acl['vpc'],
445
445
  acl,
446
446
  "firewall_rule",
@@ -138,7 +138,7 @@ module MU
138
138
  # Return the metadata for this folders's configuration
139
139
  # @return [Hash]
140
140
  def notify
141
- desc = MU.structToHash(MU::Cloud::Google.folder(credentials: @config['credentials']).get_folder("folders/"+@cloud_id))
141
+ desc = MU.structToHash(cloud_desc)
142
142
  desc["mu_name"] = @mu_name
143
143
  desc["parent"] = @parent
144
144
  desc["cloud_id"] = @cloud_id
@@ -236,10 +236,10 @@ module MU
236
236
  # @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
237
237
  def self.find(**args)
238
238
  found = {}
239
-
240
239
  # Recursively search a GCP folder hierarchy for a folder matching our
241
240
  # supplied name or identifier.
242
241
  def self.find_matching_folder(parent, name: nil, id: nil, credentials: nil)
242
+
243
243
  resp = MU::Cloud::Google.folder(credentials: credentials).list_folders(parent: parent)
244
244
  if resp and resp.folders
245
245
  resp.folders.each { |f|
@@ -278,6 +278,7 @@ module MU
278
278
  end
279
279
  else
280
280
  resp = MU::Cloud::Google.folder(credentials: args[:credentials]).list_folders(parent: parent)
281
+
281
282
  if resp and resp.folders
282
283
  resp.folders.each { |folder|
283
284
  next if folder.lifecycle_state == "DELETE_REQUESTED"
@@ -310,7 +311,6 @@ module MU
310
311
  bok['cloud_id'] = cloud_desc.name
311
312
  bok['name'] = cloud_desc.display_name#+bok['cloud_id'] # only way to guarantee uniqueness
312
313
  if cloud_desc.parent.match(/^folders\/(.*)/)
313
- MU.log bok['display_name']+" generating reference", MU::NOTICE, details: cloud_desc.parent
314
314
  bok['parent'] = MU::Config::Ref.get(
315
315
  id: cloud_desc.parent,
316
316
  cloud: "Google",
@@ -355,11 +355,7 @@ MU.log bok['display_name']+" generating reference", MU::NOTICE, details: cloud_d
355
355
  end
356
356
 
357
357
  if folder['parent'] and folder['parent']['name'] and !folder['parent']['deploy_id'] and configurator.haveLitterMate?(folder['parent']['name'], "folders")
358
- folder["dependencies"] ||= []
359
- folder["dependencies"] << {
360
- "type" => "folder",
361
- "name" => folder['parent']['name']
362
- }
358
+ MU::Config.addDependency(folder, folder['parent']['name'], "folder")
363
359
  end
364
360
 
365
361
  ok
@@ -235,7 +235,7 @@ module example.com/cloudfunction
235
235
  # @return [void]
236
236
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
237
237
  flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
238
- return if !MU::Cloud::Google::Habitat.isLive?(flags["habitat"], credentials)
238
+ return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
239
239
  # Make sure we catch regional *and* zone functions
240
240
  found = MU::Cloud::Google::Function.find(credentials: credentials, region: region, project: flags["habitat"])
241
241
  found.each_pair { |cloud_id, desc|
@@ -373,7 +373,7 @@ module example.com/cloudfunction
373
373
  }
374
374
  }
375
375
  },
376
- "service_account" => MU::Cloud::Google::Server.schema(config)[1]["service_account"],
376
+ "service_account" => MU::Cloud.resourceClass("Google", "Server").schema(config)[1]["service_account"],
377
377
  "runtime" => {
378
378
  "type" => "string",
379
379
  "enum" => %w{nodejs go python nodejs8 nodejs10 python37 go111 go113},
@@ -524,7 +524,7 @@ module example.com/cloudfunction
524
524
  ok = false
525
525
  end
526
526
  else
527
- function = MU::Cloud::Google::User.genericServiceAccount(function, configurator)
527
+ function = MU::Cloud.resourceClass("Google", "User").genericServiceAccount(function, configurator)
528
528
  end
529
529
 
530
530
  # siblings = configurator.haveLitterMate?(nil, "vpcs", has_multiple: true)
@@ -44,7 +44,7 @@ module MU
44
44
  resp = MU::Cloud::Google.admin_directory(credentials: @credentials).insert_group(group_obj)
45
45
  @cloud_id = resp.email
46
46
 
47
- MU::Cloud::Google::Role.bindFromConfig("group", @cloud_id, @config['roles'], credentials: @config['credentials'])
47
+ MU::Cloud.resourceClass("Google", "Role").bindFromConfig("group", @cloud_id, @config['roles'], credentials: @config['credentials'])
48
48
  else
49
49
  @cloud_id = @config['name'].sub(/@.*/, "")+"@"+@config['domain']
50
50
  end
@@ -52,7 +52,7 @@ module MU
52
52
 
53
53
  # Called automatically by {MU::Deploy#createResources}
54
54
  def groom
55
- MU::Cloud::Google::Role.bindFromConfig("group", @cloud_id, @config['roles'], credentials: @config['credentials'], debug: true)
55
+ MU::Cloud.resourceClass("Google", "Role").bindFromConfig("group", @cloud_id, @config['roles'], credentials: @config['credentials'], debug: true)
56
56
 
57
57
  if @config['members']
58
58
  resolved_desired = []
@@ -166,7 +166,7 @@ module MU
166
166
 
167
167
  if flags['known']
168
168
  flags['known'].each { |group|
169
- MU::Cloud::Google::Role.removeBindings("group", group, credentials: credentials, noop: noop)
169
+ MU::Cloud.resourceClass("Google", "Role").removeBindings("group", group, credentials: credentials, noop: noop)
170
170
  }
171
171
  end
172
172
  end
@@ -222,10 +222,10 @@ module MU
222
222
  # type: "users"
223
223
  # )
224
224
  # }
225
- group_roles = MU::Cloud::Google::Role.getAllBindings(@config['credentials'])["by_entity"]
225
+ group_roles = MU::Cloud.resourceClass("Google", "Role").getAllBindings(@config['credentials'])["by_entity"]
226
226
  if group_roles["group"] and group_roles["group"][bok['cloud_id']] and
227
227
  group_roles["group"][bok['cloud_id']].size > 0
228
- bok['roles'] = MU::Cloud::Google::Role.entityBindingsToSchema(group_roles["group"][bok['cloud_id']], credentials: @config['credentials'])
228
+ bok['roles'] = MU::Cloud.resourceClass("Google", "Role").entityBindingsToSchema(group_roles["group"][bok['cloud_id']], credentials: @config['credentials'])
229
229
  end
230
230
 
231
231
  bok
@@ -264,7 +264,7 @@ If we are binding (rather than creating) a group and no roles are specified, we
264
264
 
265
265
  "roles" => {
266
266
  "type" => "array",
267
- "items" => MU::Cloud::Google::Role.ref_schema
267
+ "items" => MU::Cloud.resourceClass("Google", "Role").ref_schema
268
268
  }
269
269
  }
270
270
  [toplevel_required, schema]
@@ -340,11 +340,7 @@ If we are binding (rather than creating) a group and no roles are specified, we
340
340
  if group['members']
341
341
  group['members'].each { |m|
342
342
  if configurator.haveLitterMate?(m, "users")
343
- group['dependencies'] ||= []
344
- group['dependencies'] << {
345
- "name" => m,
346
- "type" => "user"
347
- }
343
+ MU::Config.addDependency(group, m, "user")
348
344
  end
349
345
  }
350
346
  end
@@ -353,11 +349,7 @@ If we are binding (rather than creating) a group and no roles are specified, we
353
349
  group['roles'].each { |r|
354
350
  if r['role'] and r['role']['name'] and
355
351
  (!r['role']['deploy_id'] and !r['role']['id'])
356
- group['dependencies'] ||= []
357
- group['dependencies'] << {
358
- "type" => "role",
359
- "name" => r['role']['name']
360
- }
352
+ MU::Config.addDependency(group, r['role']['name'], "role")
361
353
  end
362
354
  }
363
355
  end
@@ -61,7 +61,7 @@ module MU
61
61
  if @config['parent']['name'] and !@config['parent']['id']
62
62
  @config['parent']['deploy_id'] = @deploy.deploy_id
63
63
  end
64
- parent = MU::Cloud::Google::Folder.resolveParent(@config['parent'], credentials: @config['credentials'])
64
+ parent = MU::Cloud.resourceClass("Google", "Folder").resolveParent(@config['parent'], credentials: @config['credentials'])
65
65
  if !parent
66
66
  MU.log "Unable to resolve parent resource of Google Project #{@config['name']}", MU::ERR, details: @config['parent']
67
67
  raise "Unable to resolve parent resource of Google Project #{@config['name']}"
@@ -285,7 +285,7 @@ module MU
285
285
  next if p.lifecycle_state == "DELETE_REQUESTED"
286
286
  found[p.project_id] = p
287
287
  }
288
- @@list_projects_cache = found
288
+ @@list_projects_cache = found.clone
289
289
  end
290
290
 
291
291
  found
@@ -376,11 +376,7 @@ module MU
376
376
  end
377
377
 
378
378
  if habitat['parent'] and habitat['parent']['name'] and !habitat['parent']['deploy_id'] and configurator.haveLitterMate?(habitat['parent']['name'], "folders")
379
- habitat["dependencies"] ||= []
380
- habitat["dependencies"] << {
381
- "type" => "folder",
382
- "name" => habitat['parent']['name']
383
- }
379
+ MU::Config.addDependency(habitat, habitat['parent']['name'], "folder")
384
380
  end
385
381
 
386
382
  ok
@@ -148,7 +148,7 @@ module MU
148
148
  # @return [void]
149
149
  def self.cleanup(noop: false, ignoremaster: false, region: nil, credentials: nil, flags: {})
150
150
  flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
151
- return if !MU::Cloud::Google::Habitat.isLive?(flags["habitat"], credentials)
151
+ return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
152
152
  filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
153
153
  if !ignoremaster and MU.mu_public_ip
154
154
  filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}