cloud-mu 3.1.2 → 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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +15 -3
  3. data/ansible/roles/mu-windows/README.md +33 -0
  4. data/ansible/roles/mu-windows/defaults/main.yml +2 -0
  5. data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
  6. data/ansible/roles/mu-windows/files/config.xml +76 -0
  7. data/ansible/roles/mu-windows/handlers/main.yml +2 -0
  8. data/ansible/roles/mu-windows/meta/main.yml +53 -0
  9. data/ansible/roles/mu-windows/tasks/main.yml +36 -0
  10. data/ansible/roles/mu-windows/tests/inventory +2 -0
  11. data/ansible/roles/mu-windows/tests/test.yml +5 -0
  12. data/ansible/roles/mu-windows/vars/main.yml +2 -0
  13. data/bin/mu-adopt +10 -13
  14. data/bin/mu-azure-tests +57 -0
  15. data/bin/mu-cleanup +2 -4
  16. data/bin/mu-configure +52 -0
  17. data/bin/mu-deploy +3 -3
  18. data/bin/mu-findstray-tests +25 -0
  19. data/bin/mu-gen-docs +2 -4
  20. data/bin/mu-load-config.rb +2 -3
  21. data/bin/mu-node-manage +15 -16
  22. data/bin/mu-run-tests +135 -37
  23. data/cloud-mu.gemspec +22 -20
  24. data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
  25. data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
  26. data/cookbooks/mu-tools/libraries/helper.rb +3 -2
  27. data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
  28. data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
  29. data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
  30. data/cookbooks/mu-tools/recipes/eks.rb +2 -2
  31. data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
  32. data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
  33. data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
  34. data/cookbooks/mu-tools/resources/disk.rb +1 -1
  35. data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
  36. data/extras/clean-stock-amis +25 -19
  37. data/extras/generate-stock-images +1 -0
  38. data/extras/image-generators/AWS/win2k12.yaml +18 -13
  39. data/extras/image-generators/AWS/win2k16.yaml +18 -13
  40. data/extras/image-generators/AWS/win2k19.yaml +21 -0
  41. data/extras/image-generators/Google/centos6.yaml +1 -0
  42. data/extras/image-generators/Google/centos7.yaml +1 -1
  43. data/modules/mommacat.ru +6 -16
  44. data/modules/mu.rb +165 -111
  45. data/modules/mu/adoption.rb +401 -68
  46. data/modules/mu/cleanup.rb +199 -306
  47. data/modules/mu/cloud.rb +100 -1632
  48. data/modules/mu/cloud/database.rb +49 -0
  49. data/modules/mu/cloud/dnszone.rb +46 -0
  50. data/modules/mu/cloud/machine_images.rb +212 -0
  51. data/modules/mu/cloud/providers.rb +81 -0
  52. data/modules/mu/cloud/resource_base.rb +920 -0
  53. data/modules/mu/cloud/server.rb +40 -0
  54. data/modules/mu/cloud/server_pool.rb +1 -0
  55. data/modules/mu/cloud/ssh_sessions.rb +228 -0
  56. data/modules/mu/cloud/winrm_sessions.rb +237 -0
  57. data/modules/mu/cloud/wrappers.rb +165 -0
  58. data/modules/mu/config.rb +171 -1767
  59. data/modules/mu/config/alarm.rb +2 -6
  60. data/modules/mu/config/bucket.rb +4 -4
  61. data/modules/mu/config/cache_cluster.rb +1 -1
  62. data/modules/mu/config/collection.rb +4 -4
  63. data/modules/mu/config/container_cluster.rb +9 -4
  64. data/modules/mu/config/database.rb +83 -104
  65. data/modules/mu/config/database.yml +1 -2
  66. data/modules/mu/config/dnszone.rb +6 -6
  67. data/modules/mu/config/doc_helpers.rb +516 -0
  68. data/modules/mu/config/endpoint.rb +4 -4
  69. data/modules/mu/config/firewall_rule.rb +103 -4
  70. data/modules/mu/config/folder.rb +4 -4
  71. data/modules/mu/config/function.rb +3 -3
  72. data/modules/mu/config/group.rb +4 -4
  73. data/modules/mu/config/habitat.rb +4 -4
  74. data/modules/mu/config/loadbalancer.rb +60 -14
  75. data/modules/mu/config/log.rb +4 -4
  76. data/modules/mu/config/msg_queue.rb +4 -4
  77. data/modules/mu/config/nosqldb.rb +4 -4
  78. data/modules/mu/config/notifier.rb +3 -3
  79. data/modules/mu/config/ref.rb +365 -0
  80. data/modules/mu/config/role.rb +4 -4
  81. data/modules/mu/config/schema_helpers.rb +509 -0
  82. data/modules/mu/config/search_domain.rb +4 -4
  83. data/modules/mu/config/server.rb +97 -70
  84. data/modules/mu/config/server.yml +1 -0
  85. data/modules/mu/config/server_pool.rb +5 -9
  86. data/modules/mu/config/storage_pool.rb +1 -1
  87. data/modules/mu/config/tail.rb +200 -0
  88. data/modules/mu/config/user.rb +4 -4
  89. data/modules/mu/config/vpc.rb +70 -27
  90. data/modules/mu/config/vpc.yml +0 -1
  91. data/modules/mu/defaults/AWS.yaml +83 -60
  92. data/modules/mu/defaults/Azure.yaml +1 -0
  93. data/modules/mu/defaults/Google.yaml +3 -2
  94. data/modules/mu/deploy.rb +30 -26
  95. data/modules/mu/groomer.rb +17 -2
  96. data/modules/mu/groomers/ansible.rb +188 -41
  97. data/modules/mu/groomers/chef.rb +116 -55
  98. data/modules/mu/logger.rb +127 -148
  99. data/modules/mu/master.rb +389 -2
  100. data/modules/mu/master/chef.rb +3 -4
  101. data/modules/mu/master/ldap.rb +3 -3
  102. data/modules/mu/master/ssl.rb +12 -3
  103. data/modules/mu/mommacat.rb +217 -2612
  104. data/modules/mu/mommacat/daemon.rb +397 -0
  105. data/modules/mu/mommacat/naming.rb +473 -0
  106. data/modules/mu/mommacat/search.rb +495 -0
  107. data/modules/mu/mommacat/storage.rb +722 -0
  108. data/modules/mu/{clouds → providers}/README.md +1 -1
  109. data/modules/mu/{clouds → providers}/aws.rb +271 -112
  110. data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
  111. data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
  112. data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
  113. data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
  114. data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
  115. data/modules/mu/providers/aws/database.rb +1744 -0
  116. data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
  117. data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
  118. data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
  119. data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
  120. data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
  121. data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
  122. data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
  123. data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
  124. data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
  125. data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
  126. data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
  127. data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
  128. data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
  129. data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
  130. data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
  131. data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
  132. data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
  133. data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
  134. data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
  135. data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
  136. data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
  137. data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
  138. data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
  139. data/modules/mu/{clouds → providers}/azure.rb +29 -9
  140. data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
  141. data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
  142. data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
  143. data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
  144. data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
  145. data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
  146. data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
  147. data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
  148. data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
  149. data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
  150. data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
  151. data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
  152. data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
  153. data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
  154. data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
  155. data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
  156. data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
  157. data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
  158. data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
  159. data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
  160. data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
  161. data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
  162. data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
  163. data/modules/mu/{clouds → providers}/docker.rb +0 -0
  164. data/modules/mu/{clouds → providers}/google.rb +67 -30
  165. data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
  166. data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
  167. data/modules/mu/{clouds → providers}/google/database.rb +10 -20
  168. data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
  169. data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
  170. data/modules/mu/{clouds → providers}/google/function.rb +139 -167
  171. data/modules/mu/{clouds → providers}/google/group.rb +29 -34
  172. data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
  173. data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
  174. data/modules/mu/{clouds → providers}/google/role.rb +92 -58
  175. data/modules/mu/{clouds → providers}/google/server.rb +242 -155
  176. data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
  177. data/modules/mu/{clouds → providers}/google/user.rb +95 -31
  178. data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
  179. data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
  180. data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
  181. data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
  182. data/modules/tests/bucket.yml +4 -0
  183. data/modules/tests/centos6.yaml +11 -0
  184. data/modules/tests/centos7.yaml +11 -0
  185. data/modules/tests/centos8.yaml +12 -0
  186. data/modules/tests/ecs.yaml +23 -0
  187. data/modules/tests/includes-and-params.yaml +2 -1
  188. data/modules/tests/rds.yaml +108 -0
  189. data/modules/tests/regrooms/aws-iam.yaml +201 -0
  190. data/modules/tests/regrooms/bucket.yml +19 -0
  191. data/modules/tests/regrooms/rds.yaml +123 -0
  192. data/modules/tests/server-with-scrub-muisms.yaml +1 -0
  193. data/modules/tests/super_simple_bok.yml +1 -3
  194. data/modules/tests/win2k12.yaml +17 -5
  195. data/modules/tests/win2k16.yaml +25 -0
  196. data/modules/tests/win2k19.yaml +25 -0
  197. data/requirements.txt +1 -0
  198. data/spec/mu/clouds/azure_spec.rb +2 -2
  199. metadata +232 -154
  200. data/extras/image-generators/AWS/windows.yaml +0 -18
  201. data/modules/mu/clouds/aws/database.rb +0 -1985
@@ -36,12 +36,10 @@ module MU
36
36
 
37
37
  # Called automatically by {MU::Deploy#createResources}
38
38
  def create
39
-
40
39
  networkobj = MU::Cloud::Google.compute(:Network).new(
41
40
  name: MU::Cloud::Google.nameStr(@mu_name),
42
41
  description: @deploy.deploy_id,
43
42
  auto_create_subnetworks: false
44
- # i_pv4_range: @config['ip_block']
45
43
  )
46
44
  MU.log "Creating network #{@mu_name} (#{@config['ip_block']}) in project #{@project_id}", details: networkobj
47
45
 
@@ -58,7 +56,7 @@ module MU
58
56
  subnet_name = @config['name']+subnet['name']
59
57
 
60
58
  subnet_mu_name = @config['scrub_mu_isms'] ? @cloud_id+subnet_name.downcase : MU::Cloud::Google.nameStr(@deploy.getResourceName(subnet_name, max_length: 61))
61
- MU.log "Creating subnetwork #{subnet_mu_name} (#{subnet['ip_block']}) in project #{@project_id}", details: subnet
59
+ MU.log "Creating subnetwork #{subnet_mu_name} (#{subnet['ip_block']}) in project #{@project_id} region #{subnet['availability_zone']}", details: subnet
62
60
  subnetobj = MU::Cloud::Google.compute(:Subnetwork).new(
63
61
  name: subnet_mu_name,
64
62
  description: @deploy.deploy_id,
@@ -72,9 +70,17 @@ module MU
72
70
  subnetdesc = nil
73
71
  begin
74
72
  subnetdesc = MU::Cloud::Google.compute(credentials: @config['credentials']).get_subnetwork(@project_id, subnet['availability_zone'], subnet_mu_name)
73
+ if !subnetdesc.nil?
74
+ subnet_cfg = {}
75
+ subnet_cfg["ip_block"] = subnet['ip_block']
76
+ subnet_cfg["name"] = subnet_name
77
+ subnet_cfg['mu_name'] = subnet_mu_name
78
+ subnet_cfg["cloud_id"] = subnetdesc.self_link.gsub(/.*?\/([^\/]+)$/, '\1')
79
+ subnet_cfg['az'] = subnet['availability_zone']
80
+ @subnets << MU::Cloud::Google::VPC::Subnet.new(self, subnet_cfg, precache_description: false)
81
+ end
75
82
  sleep 1
76
83
  end while subnetdesc.nil?
77
-
78
84
  }
79
85
  }
80
86
  subnetthreads.each do |t|
@@ -82,7 +88,6 @@ module MU
82
88
  end
83
89
  end
84
90
 
85
- route_table_ids = []
86
91
  if !@config['route_tables'].nil?
87
92
  @config['route_tables'].each { |rtb|
88
93
  rtb['routes'].each { |route|
@@ -108,7 +113,7 @@ module MU
108
113
  # Describe this VPC
109
114
  # @return [Hash]
110
115
  def notify
111
- base = MU.structToHash(cloud_desc)
116
+ base = MU.structToHash(cloud_desc, stringify_keys: true)
112
117
  base["cloud_id"] = @cloud_id
113
118
  base["project_id"] = habitat_id
114
119
  base.merge!(@config.to_h)
@@ -120,8 +125,8 @@ module MU
120
125
 
121
126
  # Describe this VPC from the cloud platform's perspective
122
127
  # @return [Google::Apis::Core::Hashable]
123
- def cloud_desc
124
- if @cloud_desc_cache
128
+ def cloud_desc(use_cache: true)
129
+ if @cloud_desc_cache and use_cache
125
130
  return @cloud_desc_cache
126
131
  end
127
132
 
@@ -230,8 +235,8 @@ end
230
235
  # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
231
236
  # @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
232
237
  def self.find(**args)
233
- args[:project] ||= args[:habitat]
234
- args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
238
+ args = MU::Cloud::Google.findLocationArgs(args)
239
+
235
240
  resp = {}
236
241
  if args[:cloud_id] and args[:project]
237
242
  begin
@@ -240,7 +245,7 @@ end
240
245
  args[:cloud_id].to_s.sub(/^.*?\/([^\/]+)$/, '\1')
241
246
  )
242
247
  resp[args[:cloud_id]] = vpc if !vpc.nil?
243
- rescue ::Google::Apis::ClientError => e
248
+ rescue ::Google::Apis::ClientError
244
249
  MU.log "VPC #{args[:cloud_id]} in project #{args[:project]} does not exist, or I do not have permission to view it", MU::WARN
245
250
  end
246
251
  else # XXX other criteria
@@ -296,14 +301,10 @@ end
296
301
  @deploy.deployment["vpcs"][@config['name']]["subnets"] and
297
302
  @deploy.deployment["vpcs"][@config['name']]["subnets"].size > 0
298
303
  @deploy.deployment["vpcs"][@config['name']]["subnets"].each { |desc|
299
- subnet = {}
300
- subnet["ip_block"] = desc['ip_block']
301
- subnet["name"] = desc["name"]
304
+ subnet = desc.clone
302
305
  subnet['mu_name'] = @config['scrub_mu_isms'] ? @cloud_id+subnet['name'].downcase : MU::Cloud::Google.nameStr(@deploy.getResourceName(subnet['name'], max_length: 61))
303
- subnet["cloud_id"] = desc['cloud_id']
304
306
  subnet["cloud_id"] ||= desc['self_link'].gsub(/.*?\/([^\/]+)$/, '\1')
305
307
  subnet["cloud_id"] ||= subnet['mu_name']
306
- subnet['az'] = desc["az"]
307
308
  subnet['az'] ||= desc["region"].gsub(/.*?\/([^\/]+)$/, '\1')
308
309
  @subnets << MU::Cloud::Google::VPC::Subnet.new(self, subnet, precache_description: false)
309
310
  }
@@ -477,9 +478,8 @@ end
477
478
  # directly at child nodes in peered VPCs, the public internet, and the
478
479
  # like.
479
480
  # @param target_instance [OpenStruct]: The cloud descriptor of the instance to check.
480
- # @param region [String]: The cloud provider region of the target subnet.
481
481
  # @return [Boolean]
482
- def self.haveRouteToInstance?(target_instance, region: MU.curRegion, credentials: nil)
482
+ def self.haveRouteToInstance?(target_instance, credentials: nil)
483
483
  project ||= MU::Cloud::Google.defaultProject(credentials)
484
484
  return false if MU.myCloud != "Google"
485
485
  # XXX see if we reside in the same Network and overlap subnets
@@ -509,7 +509,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
509
509
  # @param target_subnets_key [String]: The subnet/subnets on the other side of the peered VPC.
510
510
  # @param instance_id [String]: The instance ID in the target subnet/subnets.
511
511
  # @return [Boolean]
512
- def self.have_route_peered_vpc?(source_subnets_key, target_subnets_key, instance_id)
512
+ def self.can_route_to_master_peer?(source_subnets_key, target_subnets_key, instance_id)
513
513
  end
514
514
 
515
515
  # Retrieves the route tables of used by subnets
@@ -536,13 +536,17 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
536
536
  # Remove all VPC resources associated with the currently loaded deployment.
537
537
  # @param noop [Boolean]: If true, will only print what would be done
538
538
  # @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
539
- # @param region [String]: The cloud provider region
540
539
  # @return [void]
541
- def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
542
- flags["project"] ||= MU::Cloud::Google.defaultProject(credentials)
543
- return if !MU::Cloud::Google::Habitat.isLive?(flags["project"], credentials)
540
+ def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
541
+ flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
542
+ return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
543
+ filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
544
+ if !ignoremaster and MU.mu_public_ip
545
+ filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
546
+ end
547
+ MU.log "Placeholder: Google VPC artifacts do not support labels, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: filter
544
548
 
545
- purge_subnets(noop, project: flags['project'], credentials: credentials)
549
+ purge_subnets(noop, project: flags['habitat'], credentials: credentials)
546
550
  ["route", "network"].each { |type|
547
551
  # XXX tagged routes aren't showing up in list, and the networks that own them
548
552
  # fail to delete silently
@@ -551,7 +555,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
551
555
  begin
552
556
  MU::Cloud::Google.compute(credentials: credentials).delete(
553
557
  type,
554
- flags["project"],
558
+ flags["habitat"],
555
559
  nil,
556
560
  noop
557
561
  )
@@ -561,13 +565,13 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
561
565
  MU.log e.message, MU::WARN
562
566
  if e.message.match(/Failed to delete network (.+)/)
563
567
  network_name = Regexp.last_match[1]
564
- fwrules = MU::Cloud::Google::FirewallRule.find(project: flags['project'], credentials: credentials)
565
- fwrules.reject! { |name, desc|
568
+ fwrules = MU::Cloud.resourceClass("Google", "FirewallRule").find(project: flags['habitat'], credentials: credentials)
569
+ fwrules.reject! { |_name, desc|
566
570
  !desc.network.match(/.*?\/#{Regexp.quote(network_name)}$/)
567
571
  }
568
572
  fwrules.keys.each { |name|
569
573
  MU.log "Attempting to delete firewall rule #{name} so that VPC #{network_name} can be removed", MU::NOTICE
570
- MU::Cloud::Google.compute(credentials: credentials).delete_firewall(flags['project'], name)
574
+ MU::Cloud::Google.compute(credentials: credentials).delete_firewall(flags['habitat'], name)
571
575
  }
572
576
  end
573
577
  end
@@ -586,7 +590,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
586
590
  # We assume that any values we have in +@config+ are placeholders, and
587
591
  # calculate our own accordingly based on what's live in the cloud.
588
592
  # XXX add flag to return the diff between @config and live cloud
589
- def toKitten(rootparent: nil, billing: nil, habitats: nil)
593
+ def toKitten(**_args)
590
594
  return nil if cloud_desc.name == "default" # parent project builds these
591
595
  bok = {
592
596
  "cloud" => "Google",
@@ -595,8 +599,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
595
599
  }
596
600
  MU::Cloud::Google.listRegions.size
597
601
 
598
- diff = {}
599
- schema, valid = MU::Config.loadResourceSchema("VPC", cloud: "Google")
602
+ _schema, valid = MU::Config.loadResourceSchema("VPC", cloud: "Google")
600
603
  return [nil, nil] if !valid
601
604
  # pp schema
602
605
  # MU.log "++++++++++++++++++++++++++++++++"
@@ -609,6 +612,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
609
612
  bok['subnets'] = []
610
613
  regions_seen = []
611
614
  names_seen = []
615
+ @subnets.reject! { |x| x.cloud_desc.nil? }
612
616
  @subnets.map { |x| x.cloud_desc }.each { |s|
613
617
  subnet_name = s.name.dup
614
618
  names_seen << s.name.dup
@@ -630,7 +634,6 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
630
634
  end
631
635
  end
632
636
 
633
- peer_names = []
634
637
  if cloud_desc.peerings and cloud_desc.peerings.size > 0
635
638
  bok['peers'] = []
636
639
  cloud_desc.peerings.each { |peer|
@@ -688,9 +691,9 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
688
691
  end
689
692
 
690
693
  # Cloud-specific configuration properties.
691
- # @param config [MU::Config]: The calling MU::Config object
694
+ # @param _config [MU::Config]: The calling MU::Config object
692
695
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
693
- def self.schema(config = nil)
696
+ def self.schema(_config = nil)
694
697
  toplevel_required = []
695
698
  schema = {
696
699
  "regions" => {
@@ -736,7 +739,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
736
739
 
737
740
  # see if one of this thing's siblings declared a subnet_pref we can
738
741
  # use to guess which one we should marry ourselves to
739
- configurator.kittens.each_pair { |type, siblings|
742
+ configurator.kittens.values.each { |siblings|
740
743
  siblings.each { |sibling|
741
744
  next if !sibling['dependencies']
742
745
  sibling['dependencies'].each { |dep|
@@ -900,7 +903,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
900
903
  "destination_network"=>"0.0.0.0/0"
901
904
  }
902
905
  end
903
- nat_count = 0
906
+
904
907
  # You know what, let's just guarantee that we'll have a route from
905
908
  # this master, always
906
909
  # XXX this confuses machines that don't have public IPs
@@ -943,9 +946,44 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
943
946
  createRoute(route, network: @url, tags: [MU::Cloud::Google.nameStr(server.mu_name)])
944
947
  end
945
948
 
949
+ # Looks at existing subnets, and attempts to find the next available
950
+ # IP block that's roughly similar to the ones we already have. This
951
+ # checks against secondary IP ranges, as well as each subnet's primary
952
+ # CIDR block.
953
+ # @param exclude [Array<String>]: One or more CIDRs to treat as unavailable, in addition to those allocated to existing subnets
954
+ # @return [String]
955
+ def getUnusedAddressBlock(exclude: [], max_bits: 28)
956
+ used_ranges = exclude.map { |cidr| NetAddr::IPv4Net.parse(cidr) }
957
+ subnets.each { |s|
958
+ used_ranges << NetAddr::IPv4Net.parse(s.cloud_desc.ip_cidr_range)
959
+ if s.cloud_desc.secondary_ip_ranges
960
+ used_ranges.concat(s.cloud_desc.secondary_ip_ranges.map { |r| NetAddr::IPv4Net.parse(r.ip_cidr_range) })
961
+ end
962
+ }
963
+ # XXX sort used_ranges
964
+ candidate = used_ranges.first.next_sib
965
+
966
+ begin
967
+ if candidate.netmask.prefix_len > max_bits
968
+ candidate = candidate.resize(max_bits)
969
+ end
970
+ try_again = false
971
+ used_ranges.each { |cidr|
972
+ if !cidr.rel(candidate).nil?
973
+ candidate = candidate.next_sib
974
+ try_again = true
975
+ break
976
+ end
977
+ }
978
+ try_again = false if candidate.nil?
979
+ end while try_again
980
+
981
+ candidate.to_s
982
+ end
983
+
946
984
  private
947
985
 
948
- def self.genStandardSubnetACLs(vpc_cidr, vpc_name, configurator, project, publicroute = true, credentials: nil)
986
+ def self.genStandardSubnetACLs(vpc_cidr, vpc_name, configurator, project, _publicroute = true, credentials: nil)
949
987
  private_acl = {
950
988
  "name" => vpc_name+"-rt",
951
989
  "cloud" => "Google",
@@ -973,6 +1011,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
973
1011
  # end
974
1012
  configurator.insertKitten(private_acl, "firewall_rules", true)
975
1013
  end
1014
+ private_class_method :genStandardSubnetACLs
976
1015
 
977
1016
  # Helper method for manufacturing routes. Expect to be called from
978
1017
  # {MU::Cloud::Google::VPC#create} or {MU::Cloud::Google::VPC#groom}.
@@ -1039,7 +1078,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
1039
1078
  rescue ::Google::Apis::ClientError, MU::MuError => e
1040
1079
  if e.message.match(/notFound/)
1041
1080
  MU.log "Creating route #{routename} in project #{@project_id}", details: routeobj
1042
- resp = MU::Cloud::Google.compute(credentials: @config['credentials']).insert_route(@project_id, routeobj)
1081
+ MU::Cloud::Google.compute(credentials: @config['credentials']).insert_route(@project_id, routeobj)
1043
1082
  else
1044
1083
  # TODO can't update GCP routes, would have to delete and re-create
1045
1084
  end
@@ -1047,44 +1086,12 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
1047
1086
  end
1048
1087
  end
1049
1088
 
1050
-
1051
- # Remove all network gateways associated with the currently loaded deployment.
1052
- # @param noop [Boolean]: If true, will only print what would be done
1053
- # @param region [String]: The cloud provider region
1054
- # @return [void]
1055
- def self.purge_gateways(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
1056
- end
1057
-
1058
- # Remove all NAT gateways associated with the VPC of the currently loaded deployment.
1059
- # @param noop [Boolean]: If true, will only print what would be done
1060
- # @param vpc_id [String]: The cloud provider's unique VPC identifier
1061
- # @param region [String]: The cloud provider region
1062
- # @return [void]
1063
- def self.purge_nat_gateways(noop = false, vpc_id: nil, region: MU.curRegion)
1064
- end
1065
-
1066
- # Remove all VPC endpoints associated with the VPC of the currently loaded deployment.
1067
- # @param noop [Boolean]: If true, will only print what would be done
1068
- # @param vpc_id [String]: The cloud provider's unique VPC identifier
1069
- # @param region [String]: The cloud provider region
1070
- # @return [void]
1071
- def self.purge_endpoints(noop = false, vpc_id: nil, region: MU.curRegion)
1072
- end
1073
-
1074
- # Remove all network interfaces associated with the currently loaded deployment.
1075
- # @param noop [Boolean]: If true, will only print what would be done
1076
- # @param tagfilters [Array<Hash>]: Labels to filter against when search for resources to purge
1077
- # @param region [String]: The cloud provider region
1078
- # @return [void]
1079
- def self.purge_interfaces(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion)
1080
- end
1081
-
1082
1089
  # Remove all subnets associated with the currently loaded deployment.
1083
1090
  # @param noop [Boolean]: If true, will only print what would be done
1084
- # @param tagfilters [Array<Hash>]: Labels to filter against when search for resources to purge
1091
+ # @param _tagfilters [Array<Hash>]: Labels to filter against when search for resources to purge
1085
1092
  # @param regions [Array<String>]: The cloud provider regions to check
1086
1093
  # @return [void]
1087
- def self.purge_subnets(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], regions: MU::Cloud::Google.listRegions, project: nil, credentials: nil)
1094
+ def self.purge_subnets(noop = false, _tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], regions: MU::Cloud::Google.listRegions, project: nil, credentials: nil)
1088
1095
  project ||= MU::Cloud::Google.defaultProject(credentials)
1089
1096
  parent_thread_id = Thread.current.object_id
1090
1097
  regionthreads = []
@@ -1098,7 +1105,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
1098
1105
  r,
1099
1106
  noop
1100
1107
  )
1101
- rescue MU::Cloud::MuDefunctHabitat => e
1108
+ rescue MU::Cloud::MuDefunctHabitat
1102
1109
  Thread.exit
1103
1110
  end
1104
1111
  }
@@ -1107,8 +1114,7 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
1107
1114
  t.join
1108
1115
  end
1109
1116
  end
1110
-
1111
- protected
1117
+ private_class_method :purge_subnets
1112
1118
 
1113
1119
  # Subnets are almost a first-class resource. So let's kinda sorta treat
1114
1120
  # them like one. This should only be invoked on objects that already
@@ -1116,7 +1122,6 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
1116
1122
  class Subnet < MU::Cloud::Google::VPC
1117
1123
 
1118
1124
  attr_reader :cloud_id
1119
- attr_reader :url
1120
1125
  attr_reader :ip_block
1121
1126
  attr_reader :mu_name
1122
1127
  attr_reader :name
@@ -1146,13 +1151,32 @@ MU.log "ROUTES TO #{target_instance.name}", MU::WARN, details: resp
1146
1151
  # Describe this VPC Subnet
1147
1152
  # @return [Hash]
1148
1153
  def notify
1149
- MU.structToHash(cloud_desc)
1154
+ MU.structToHash(cloud_desc, stringify_keys: true)
1155
+ end
1156
+
1157
+ # Return the +self_link+ to this subnet
1158
+ def url
1159
+ cloud_desc if !@url
1160
+ @url
1150
1161
  end
1151
1162
 
1163
+ @cloud_desc_cache = nil
1152
1164
  # Describe this VPC Subnet from the cloud platform's perspective
1153
1165
  # @return [Google::Apis::Core::Hashable]
1154
- def cloud_desc
1155
- @cloud_desc_cache ||= MU::Cloud::Google.compute(credentials: @parent.config['credentials']).get_subnetwork(@parent.habitat_id, @config['az'], @config['cloud_id'])
1166
+ def cloud_desc(use_cache: true)
1167
+ return @cloud_desc_cache if @cloud_desc_cache and use_cache
1168
+
1169
+ begin
1170
+ @cloud_desc_cache = MU::Cloud::Google.compute(credentials: @parent.config['credentials']).get_subnetwork(@parent.habitat_id, @az, @cloud_id)
1171
+ rescue ::Google::Apis::ClientError => e
1172
+ if e.message.match(/notFound: /)
1173
+ MU.log "Failed to fetch cloud description for Google subnet #{@cloud_id}", MU::WARN, details: { "project" => @parent.habitat_id, "region" => @az, "name" => @cloud_id }
1174
+ return nil
1175
+ else
1176
+ raise e
1177
+ end
1178
+ end
1179
+ @url ||= @cloud_desc_cache.self_link
1156
1180
  @cloud_desc_cache
1157
1181
  end
1158
1182
 
@@ -6,7 +6,11 @@ buckets:
6
6
  policies:
7
7
  - name: testpermissions
8
8
  grant_to:
9
+ <% if cloud == "Google" %>
9
10
  - identifier: egt.gcp.sandbox@gmail.com
11
+ <% elsif cloud == "AWS" %>
12
+ - identifier: "arn:aws:iam::<%= MU::Cloud::AWS.account_number %>:root"
13
+ <% end %>
10
14
  targets: # XXX this is redundant except for path:
11
15
  - type: bucket
12
16
  identifier: bucket
@@ -0,0 +1,11 @@
1
+ # groomers: Chef
2
+ ---
3
+ appname: smoketest
4
+ servers:
5
+ - name: centos6
6
+ platform: centos6
7
+ size: m3.medium
8
+ run_list:
9
+ - recipe[mu-tools::apply_security]
10
+ - recipe[mu-tools::updates]
11
+ - recipe[mu-tools::split_var_partitions]
@@ -0,0 +1,11 @@
1
+ # groomers: Chef
2
+ ---
3
+ appname: smoketest
4
+ servers:
5
+ - name: centos7
6
+ platform: centos7
7
+ size: m3.medium
8
+ run_list:
9
+ - recipe[mu-tools::apply_security]
10
+ - recipe[mu-tools::updates]
11
+ - recipe[mu-tools::split_var_partitions]
@@ -0,0 +1,12 @@
1
+ # groomers: Chef
2
+ # clouds: Azure, Google
3
+ ---
4
+ appname: smoketest
5
+ servers:
6
+ - name: centos8
7
+ platform: centos8
8
+ size: m3.medium
9
+ run_list:
10
+ - recipe[mu-tools::apply_security]
11
+ - recipe[mu-tools::updates]
12
+ - recipe[mu-tools::split_var_partitions]