cloud-mu 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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]