cloud-mu 3.5.0 → 3.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/Berksfile +5 -2
  3. data/Berksfile.lock +135 -0
  4. data/ansible/roles/mu-base/README.md +33 -0
  5. data/ansible/roles/mu-base/defaults/main.yml +2 -0
  6. data/ansible/roles/mu-base/files/check_apm.cfg +1 -0
  7. data/ansible/roles/mu-base/files/check_apm.sh +18 -0
  8. data/ansible/roles/mu-base/files/check_disk.cfg +1 -0
  9. data/ansible/roles/mu-base/files/check_elastic_shards.cfg +1 -0
  10. data/ansible/roles/mu-base/files/check_elastic_shards.sh +12 -0
  11. data/ansible/roles/mu-base/files/check_logstash.cfg +1 -0
  12. data/ansible/roles/mu-base/files/check_logstash.sh +14 -0
  13. data/ansible/roles/mu-base/files/check_mem.cfg +1 -0
  14. data/ansible/roles/mu-base/files/check_updates.cfg +1 -0
  15. data/ansible/roles/mu-base/files/logrotate.conf +35 -0
  16. data/ansible/roles/mu-base/files/nrpe-apm-sudo +1 -0
  17. data/ansible/roles/mu-base/files/nrpe-elasticshards-sudo +2 -0
  18. data/ansible/roles/mu-base/handlers/main.yml +5 -0
  19. data/ansible/roles/mu-base/meta/main.yml +53 -0
  20. data/ansible/roles/mu-base/tasks/main.yml +113 -0
  21. data/ansible/roles/mu-base/templates/nrpe.cfg.j2 +231 -0
  22. data/ansible/roles/mu-base/tests/inventory +2 -0
  23. data/ansible/roles/mu-base/tests/test.yml +5 -0
  24. data/ansible/roles/mu-base/vars/main.yml +1 -0
  25. data/ansible/roles/mu-compliance/README.md +33 -0
  26. data/ansible/roles/mu-compliance/defaults/main.yml +2 -0
  27. data/ansible/roles/mu-compliance/files/U_MS_Windows_Server_2016_V2R1_STIG_SCAP_1-2_Benchmark.xml +15674 -0
  28. data/ansible/roles/mu-compliance/files/U_MS_Windows_Server_2019_V2R1_STIG_SCAP_1-2_Benchmark.xml +17553 -0
  29. data/ansible/roles/mu-compliance/handlers/main.yml +2 -0
  30. data/ansible/roles/mu-compliance/meta/main.yml +53 -0
  31. data/ansible/roles/mu-compliance/tasks/main.yml +45 -0
  32. data/ansible/roles/mu-compliance/tests/inventory +2 -0
  33. data/ansible/roles/mu-compliance/tests/test.yml +5 -0
  34. data/ansible/roles/mu-compliance/vars/main.yml +4 -0
  35. data/ansible/roles/mu-elastic/README.md +51 -0
  36. data/ansible/roles/mu-elastic/defaults/main.yml +2 -0
  37. data/ansible/roles/mu-elastic/files/jvm.options +93 -0
  38. data/ansible/roles/mu-elastic/handlers/main.yml +10 -0
  39. data/ansible/roles/mu-elastic/meta/main.yml +52 -0
  40. data/ansible/roles/mu-elastic/tasks/main.yml +186 -0
  41. data/ansible/roles/mu-elastic/templates/elasticsearch.yml.j2 +110 -0
  42. data/ansible/roles/mu-elastic/templates/kibana.yml.j2 +131 -0
  43. data/ansible/roles/mu-elastic/templates/password_set.expect.j2 +19 -0
  44. data/ansible/roles/mu-elastic/tests/inventory +2 -0
  45. data/ansible/roles/mu-elastic/tests/test.yml +5 -0
  46. data/ansible/roles/mu-elastic/vars/main.yml +2 -0
  47. data/ansible/roles/mu-logstash/README.md +51 -0
  48. data/ansible/roles/mu-logstash/defaults/main.yml +2 -0
  49. data/ansible/roles/mu-logstash/files/02-beats-input.conf +5 -0
  50. data/ansible/roles/mu-logstash/files/10-rails-filter.conf +16 -0
  51. data/ansible/roles/mu-logstash/files/jvm.options +84 -0
  52. data/ansible/roles/mu-logstash/files/logstash.yml +304 -0
  53. data/ansible/roles/mu-logstash/handlers/main.yml +20 -0
  54. data/ansible/roles/mu-logstash/meta/main.yml +52 -0
  55. data/ansible/roles/mu-logstash/tasks/main.yml +254 -0
  56. data/ansible/roles/mu-logstash/templates/20-cloudtrail.conf.j2 +28 -0
  57. data/ansible/roles/mu-logstash/templates/30-elasticsearch-output.conf.j2 +19 -0
  58. data/ansible/roles/mu-logstash/templates/apm-server.yml.j2 +33 -0
  59. data/ansible/roles/mu-logstash/templates/heartbeat.yml.j2 +29 -0
  60. data/ansible/roles/mu-logstash/templates/nginx/apm.conf.j2 +25 -0
  61. data/ansible/roles/mu-logstash/templates/nginx/default.conf.j2 +56 -0
  62. data/ansible/roles/mu-logstash/templates/nginx/elastic.conf.j2 +27 -0
  63. data/ansible/roles/mu-logstash/tests/inventory +2 -0
  64. data/ansible/roles/mu-logstash/tests/test.yml +5 -0
  65. data/ansible/roles/mu-logstash/vars/main.yml +2 -0
  66. data/ansible/roles/mu-rdp/README.md +33 -0
  67. data/ansible/roles/mu-rdp/meta/main.yml +53 -0
  68. data/ansible/roles/mu-rdp/tasks/main.yml +9 -0
  69. data/ansible/roles/mu-rdp/tests/inventory +2 -0
  70. data/ansible/roles/mu-rdp/tests/test.yml +5 -0
  71. data/ansible/roles/mu-windows/tasks/main.yml +3 -0
  72. data/bin/mu-ansible-secret +1 -1
  73. data/bin/mu-aws-setup +4 -3
  74. data/bin/mu-azure-setup +5 -5
  75. data/bin/mu-configure +25 -17
  76. data/bin/mu-firewall-allow-clients +1 -0
  77. data/bin/mu-gcp-setup +3 -3
  78. data/bin/mu-load-config.rb +1 -0
  79. data/bin/mu-node-manage +66 -33
  80. data/bin/mu-self-update +2 -2
  81. data/bin/mu-upload-chef-artifacts +6 -1
  82. data/bin/mu-user-manage +1 -1
  83. data/cloud-mu.gemspec +25 -23
  84. data/cookbooks/firewall/CHANGELOG.md +417 -224
  85. data/cookbooks/firewall/LICENSE +202 -0
  86. data/cookbooks/firewall/README.md +153 -126
  87. data/cookbooks/firewall/TODO.md +6 -0
  88. data/cookbooks/firewall/attributes/firewalld.rb +7 -0
  89. data/cookbooks/firewall/attributes/iptables.rb +3 -3
  90. data/cookbooks/firewall/chefignore +115 -0
  91. data/cookbooks/firewall/libraries/helpers.rb +5 -0
  92. data/cookbooks/firewall/libraries/helpers_firewalld.rb +1 -1
  93. data/cookbooks/firewall/libraries/helpers_firewalld_dbus.rb +72 -0
  94. data/cookbooks/firewall/libraries/helpers_iptables.rb +3 -3
  95. data/cookbooks/firewall/libraries/helpers_nftables.rb +170 -0
  96. data/cookbooks/firewall/libraries/helpers_ufw.rb +7 -0
  97. data/cookbooks/firewall/libraries/helpers_windows.rb +8 -9
  98. data/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +9 -9
  99. data/cookbooks/firewall/libraries/provider_firewall_iptables.rb +7 -7
  100. data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +12 -8
  101. data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +13 -9
  102. data/cookbooks/firewall/libraries/provider_firewall_rule.rb +1 -1
  103. data/cookbooks/firewall/libraries/provider_firewall_ufw.rb +5 -5
  104. data/cookbooks/firewall/libraries/provider_firewall_windows.rb +4 -4
  105. data/cookbooks/firewall/libraries/resource_firewall_rule.rb +3 -3
  106. data/cookbooks/firewall/metadata.json +40 -1
  107. data/cookbooks/firewall/metadata.rb +15 -0
  108. data/cookbooks/firewall/recipes/default.rb +7 -7
  109. data/cookbooks/firewall/recipes/disable_firewall.rb +1 -1
  110. data/cookbooks/firewall/recipes/firewalld.rb +87 -0
  111. data/cookbooks/firewall/renovate.json +18 -0
  112. data/cookbooks/firewall/resources/firewalld.rb +28 -0
  113. data/cookbooks/firewall/resources/firewalld_config.rb +39 -0
  114. data/cookbooks/firewall/resources/firewalld_helpers.rb +106 -0
  115. data/cookbooks/firewall/resources/firewalld_icmptype.rb +88 -0
  116. data/cookbooks/firewall/resources/firewalld_ipset.rb +104 -0
  117. data/cookbooks/firewall/resources/firewalld_policy.rb +115 -0
  118. data/cookbooks/firewall/resources/firewalld_service.rb +98 -0
  119. data/cookbooks/firewall/resources/firewalld_zone.rb +118 -0
  120. data/cookbooks/firewall/resources/nftables.rb +71 -0
  121. data/cookbooks/firewall/resources/nftables_rule.rb +113 -0
  122. data/cookbooks/mu-activedirectory/Berksfile +1 -1
  123. data/cookbooks/mu-activedirectory/metadata.rb +1 -1
  124. data/cookbooks/mu-firewall/metadata.rb +2 -2
  125. data/cookbooks/mu-master/Berksfile +4 -3
  126. data/cookbooks/mu-master/attributes/default.rb +5 -2
  127. data/cookbooks/mu-master/files/default/check_elastic.sh +761 -0
  128. data/cookbooks/mu-master/files/default/check_kibana.rb +45 -0
  129. data/cookbooks/mu-master/libraries/mu.rb +24 -0
  130. data/cookbooks/mu-master/metadata.rb +5 -5
  131. data/cookbooks/mu-master/recipes/default.rb +31 -20
  132. data/cookbooks/mu-master/recipes/firewall-holes.rb +5 -0
  133. data/cookbooks/mu-master/recipes/init.rb +58 -19
  134. data/cookbooks/mu-master/recipes/update_nagios_only.rb +251 -178
  135. data/cookbooks/mu-master/templates/default/nagios.conf.erb +5 -11
  136. data/cookbooks/mu-master/templates/default/web_app.conf.erb +3 -0
  137. data/cookbooks/mu-php54/Berksfile +1 -1
  138. data/cookbooks/mu-php54/metadata.rb +2 -2
  139. data/cookbooks/mu-tools/Berksfile +2 -3
  140. data/cookbooks/mu-tools/attributes/default.rb +3 -4
  141. data/cookbooks/mu-tools/files/amazon/etc/bashrc +90 -0
  142. data/cookbooks/mu-tools/files/amazon/etc/login.defs +292 -0
  143. data/cookbooks/mu-tools/files/amazon/etc/profile +77 -0
  144. data/cookbooks/mu-tools/files/amazon/etc/security/limits.conf +63 -0
  145. data/cookbooks/mu-tools/files/amazon/etc/sysconfig/init +19 -0
  146. data/cookbooks/mu-tools/files/amazon/etc/sysctl.conf +82 -0
  147. data/cookbooks/mu-tools/files/amazon-2023/etc/login.defs +294 -0
  148. data/cookbooks/mu-tools/files/default/logrotate.conf +35 -0
  149. data/cookbooks/mu-tools/files/default/nrpe_conf_d.pp +0 -0
  150. data/cookbooks/mu-tools/libraries/helper.rb +21 -9
  151. data/cookbooks/mu-tools/metadata.rb +4 -4
  152. data/cookbooks/mu-tools/recipes/apply_security.rb +3 -2
  153. data/cookbooks/mu-tools/recipes/aws_api.rb +23 -5
  154. data/cookbooks/mu-tools/recipes/base_repositories.rb +4 -1
  155. data/cookbooks/mu-tools/recipes/gcloud.rb +56 -56
  156. data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
  157. data/cookbooks/mu-tools/recipes/nrpe.rb +20 -2
  158. data/cookbooks/mu-tools/recipes/rsyslog.rb +12 -1
  159. data/cookbooks/mu-tools/recipes/set_local_fw.rb +1 -1
  160. data/data_bags/nagios_services/apm_backend_connect.json +5 -0
  161. data/data_bags/nagios_services/apm_listen.json +5 -0
  162. data/data_bags/nagios_services/elastic_shards.json +5 -0
  163. data/data_bags/nagios_services/logstash.json +5 -0
  164. data/data_bags/nagios_services/rhel7_updates.json +8 -0
  165. data/extras/image-generators/AWS/centos7.yaml +1 -0
  166. data/extras/image-generators/AWS/rhel7.yaml +21 -0
  167. data/extras/image-generators/AWS/win2k12r2.yaml +1 -0
  168. data/extras/image-generators/AWS/win2k16.yaml +1 -0
  169. data/extras/image-generators/AWS/win2k19.yaml +1 -0
  170. data/extras/list-stock-amis +0 -0
  171. data/extras/ruby_rpm/muby.spec +8 -5
  172. data/extras/vault_tools/export_vaults.sh +1 -1
  173. data/extras/vault_tools/recreate_vaults.sh +0 -0
  174. data/extras/vault_tools/test_vaults.sh +0 -0
  175. data/install/deprecated-bash-library.sh +1 -1
  176. data/install/installer +4 -2
  177. data/modules/mommacat.ru +3 -1
  178. data/modules/mu/adoption.rb +1 -1
  179. data/modules/mu/cloud/dnszone.rb +2 -2
  180. data/modules/mu/cloud/machine_images.rb +26 -25
  181. data/modules/mu/cloud/resource_base.rb +213 -182
  182. data/modules/mu/cloud/server_pool.rb +1 -1
  183. data/modules/mu/cloud/ssh_sessions.rb +7 -5
  184. data/modules/mu/cloud/wrappers.rb +2 -2
  185. data/modules/mu/cloud.rb +1 -1
  186. data/modules/mu/config/bucket.rb +1 -1
  187. data/modules/mu/config/function.rb +6 -1
  188. data/modules/mu/config/loadbalancer.rb +24 -2
  189. data/modules/mu/config/ref.rb +12 -0
  190. data/modules/mu/config/role.rb +1 -1
  191. data/modules/mu/config/schema_helpers.rb +42 -9
  192. data/modules/mu/config/server.rb +43 -27
  193. data/modules/mu/config/tail.rb +19 -10
  194. data/modules/mu/config.rb +6 -5
  195. data/modules/mu/defaults/AWS.yaml +78 -114
  196. data/modules/mu/deploy.rb +9 -2
  197. data/modules/mu/groomer.rb +12 -4
  198. data/modules/mu/groomers/ansible.rb +104 -20
  199. data/modules/mu/groomers/chef.rb +15 -6
  200. data/modules/mu/master.rb +9 -4
  201. data/modules/mu/mommacat/daemon.rb +4 -2
  202. data/modules/mu/mommacat/naming.rb +1 -2
  203. data/modules/mu/mommacat/storage.rb +7 -2
  204. data/modules/mu/mommacat.rb +33 -6
  205. data/modules/mu/providers/aws/database.rb +161 -8
  206. data/modules/mu/providers/aws/dnszone.rb +11 -6
  207. data/modules/mu/providers/aws/endpoint.rb +81 -6
  208. data/modules/mu/providers/aws/firewall_rule.rb +254 -172
  209. data/modules/mu/providers/aws/function.rb +65 -3
  210. data/modules/mu/providers/aws/loadbalancer.rb +39 -28
  211. data/modules/mu/providers/aws/log.rb +2 -1
  212. data/modules/mu/providers/aws/role.rb +25 -7
  213. data/modules/mu/providers/aws/server.rb +36 -12
  214. data/modules/mu/providers/aws/server_pool.rb +237 -127
  215. data/modules/mu/providers/aws/storage_pool.rb +7 -1
  216. data/modules/mu/providers/aws/user.rb +1 -1
  217. data/modules/mu/providers/aws/userdata/linux.erb +6 -2
  218. data/modules/mu/providers/aws/userdata/windows.erb +7 -5
  219. data/modules/mu/providers/aws/vpc.rb +49 -25
  220. data/modules/mu/providers/aws.rb +13 -8
  221. data/modules/mu/providers/azure/container_cluster.rb +1 -1
  222. data/modules/mu/providers/azure/loadbalancer.rb +2 -2
  223. data/modules/mu/providers/azure/server.rb +5 -2
  224. data/modules/mu/providers/azure/userdata/linux.erb +1 -1
  225. data/modules/mu/providers/azure.rb +11 -8
  226. data/modules/mu/providers/cloudformation/dnszone.rb +1 -1
  227. data/modules/mu/providers/google/container_cluster.rb +15 -2
  228. data/modules/mu/providers/google/folder.rb +2 -1
  229. data/modules/mu/providers/google/function.rb +130 -4
  230. data/modules/mu/providers/google/habitat.rb +2 -1
  231. data/modules/mu/providers/google/loadbalancer.rb +407 -160
  232. data/modules/mu/providers/google/role.rb +16 -3
  233. data/modules/mu/providers/google/server.rb +5 -1
  234. data/modules/mu/providers/google/user.rb +25 -18
  235. data/modules/mu/providers/google/userdata/linux.erb +1 -1
  236. data/modules/mu/providers/google/vpc.rb +53 -7
  237. data/modules/mu/providers/google.rb +39 -39
  238. data/modules/mu.rb +8 -8
  239. data/modules/tests/elk.yaml +46 -0
  240. data/test/mu-master-test/controls/all_in_one.rb +1 -1
  241. metadata +207 -112
  242. data/cookbooks/firewall/CONTRIBUTING.md +0 -2
  243. data/cookbooks/firewall/MAINTAINERS.md +0 -19
  244. data/cookbooks/firewall/libraries/matchers.rb +0 -30
  245. data/extras/image-generators/AWS/rhel71.yaml +0 -17
@@ -250,6 +250,7 @@ module MU
250
250
  @groomclass = MU::Groomer.loadGroomer(@config["groomer"])
251
251
 
252
252
  if windows? or @config['active_directory'] and !@mu_windows_name
253
+ describe # make sure @deploydata is populated
253
254
  if !@deploydata.nil? and !@deploydata['mu_windows_name'].nil?
254
255
  @mu_windows_name = @deploydata['mu_windows_name']
255
256
  else
@@ -267,6 +268,11 @@ module MU
267
268
  attr_reader :groomer
268
269
  attr_reader :groomerclass
269
270
  attr_accessor :mu_windows_name # XXX might be ok as reader now
271
+ if @cloudparentclass.respond_to?(:customAttrReaders)
272
+ @cloudparentclass.customAttrReaders.each { |a|
273
+ attr_reader a
274
+ }
275
+ end
270
276
  end
271
277
  end
272
278
  @tags["Name"] ||= @mu_name if @mu_name
@@ -411,7 +417,7 @@ module MU
411
417
  # end
412
418
  }
413
419
 
414
- matches = self.class.find(args)
420
+ matches = self.class.find(**args)
415
421
  if !matches.nil? and matches.is_a?(Hash)
416
422
  # XXX or if the hash is keyed with an ::Id element, oh boy
417
423
  # puts matches[@cloud_id][:self_link]
@@ -529,170 +535,11 @@ module MU
529
535
 
530
536
  # Special dependencies: my containing VPC
531
537
  if self.class.can_live_in_vpc and !@config['vpc'].nil?
532
- @config['vpc']["id"] ||= @config['vpc']["vpc_id"] # old deploys
533
- @config['vpc']["name"] ||= @config['vpc']["vpc_name"] # old deploys
534
- # If something hash-ified a MU::Config::Ref here, fix it
535
- if !@config['vpc']["id"].nil? and @config['vpc']["id"].is_a?(Hash)
536
- @config['vpc']["id"] = MU::Config::Ref.new(@config['vpc']["id"])
537
- end
538
- if !@config['vpc']["id"].nil?
539
- if @config['vpc']["id"].is_a?(MU::Config::Ref) and !@config['vpc']["id"].kitten.nil?
540
- @vpc = @config['vpc']["id"].kitten(@deploy)
541
- else
542
- if @config['vpc']['habitat']
543
- @config['vpc']['habitat'] = MU::Config::Ref.get(@config['vpc']['habitat'])
544
- end
545
- vpc_ref = MU::Config::Ref.get(@config['vpc'])
546
- @vpc = vpc_ref.kitten(@deploy)
547
- end
548
- elsif !@config['vpc']["name"].nil? and @deploy
549
- MU.log "Attempting findLitterMate on VPC for #{self}", loglevel, details: @config['vpc']
550
-
551
- sib_by_name = @deploy.findLitterMate(name: @config['vpc']['name'], type: "vpcs", return_all: true, habitat: @config['vpc']['project'], debug: debug)
552
- if sib_by_name.is_a?(Hash)
553
- if sib_by_name.size == 1
554
- @vpc = sib_by_name.values.first
555
- MU.log "Single VPC match for #{self}", loglevel, details: @vpc.to_s
556
- else
557
- # XXX ok but this is the wrong place for this really the config parser needs to sort this out somehow
558
- # we got multiple matches, try to pick one by preferred subnet
559
- # behavior
560
- MU.log "Sorting a bunch of VPC matches for #{self}", loglevel, details: sib_by_name.map { |s| s.to_s }.join(", ")
561
- sib_by_name.values.each { |sibling|
562
- all_private = sibling.subnets.map { |s| s.private? }.all?(true)
563
- all_public = sibling.subnets.map { |s| s.private? }.all?(false)
564
- names = sibling.subnets.map { |s| s.name }
565
- ids = sibling.subnets.map { |s| s.cloud_id }
566
- if all_private and ["private", "all_private"].include?(@config['vpc']['subnet_pref'])
567
- @vpc = sibling
568
- break
569
- elsif all_public and ["public", "all_public"].include?(@config['vpc']['subnet_pref'])
570
- @vpc = sibling
571
- break
572
- elsif @config['vpc']['subnet_name'] and
573
- names.include?(@config['vpc']['subnet_name'])
574
- #puts "CHOOSING #{@vpc.to_s} 'cause it has #{@config['vpc']['subnet_name']}"
575
- @vpc = sibling
576
- break
577
- elsif @config['vpc']['subnet_id'] and
578
- ids.include?(@config['vpc']['subnet_id'])
579
- @vpc = sibling
580
- break
581
- end
582
- }
583
- if !@vpc
584
- sibling = sib_by_name.values.sample
585
- MU.log "Got multiple matching VPCs for #{self.class.cfg_name} #{@mu_name}, so I'm arbitrarily choosing #{sibling.mu_name}", MU::WARN, details: @config['vpc']
586
- @vpc = sibling
587
- end
588
- end
589
- else
590
- @vpc = sib_by_name
591
- MU.log "Found exact VPC match for #{self}", loglevel, details: sib_by_name.to_s
592
- end
593
- else
594
- MU.log "No shortcuts available to fetch VPC for #{self}", loglevel, details: @config['vpc']
595
- end
596
-
597
- if !@vpc and !@config['vpc']["name"].nil? and
598
- @dependencies.has_key?("vpc") and
599
- @dependencies["vpc"].has_key?(@config['vpc']["name"])
600
- MU.log "Grabbing VPC I see in @dependencies['vpc']['#{@config['vpc']["name"]}'] for #{self}", loglevel, details: @config['vpc']
601
- @vpc = @dependencies["vpc"][@config['vpc']["name"]]
602
- elsif !@vpc
603
- tag_key, tag_value = @config['vpc']['tag'].split(/=/, 2) if !@config['vpc']['tag'].nil?
604
- if !@config['vpc'].has_key?("id") and
605
- !@config['vpc'].has_key?("deploy_id") and !@deploy.nil?
606
- @config['vpc']["deploy_id"] = @deploy.deploy_id
607
- end
608
- MU.log "Doing findStray for VPC for #{self}", loglevel, details: @config['vpc']
609
- vpcs = MU::MommaCat.findStray(
610
- @config['cloud'],
611
- "vpc",
612
- deploy_id: @config['vpc']["deploy_id"],
613
- cloud_id: @config['vpc']["id"],
614
- name: @config['vpc']["name"],
615
- tag_key: tag_key,
616
- tag_value: tag_value,
617
- habitats: [@project_id],
618
- region: @config['vpc']["region"],
619
- calling_deploy: @deploy,
620
- credentials: @credentials,
621
- dummy_ok: true,
622
- debug: debug
623
- )
624
- @vpc = vpcs.first if !vpcs.nil? and vpcs.size > 0
625
- end
626
- if @vpc and @vpc.config and @vpc.config['bastion'] and
627
- @vpc.config['bastion'].to_h['name'] != @config['name']
628
- refhash = @vpc.config['bastion'].to_h
629
- refhash['deploy_id'] ||= @vpc.deploy.deploy_id
630
- natref = MU::Config::Ref.get(refhash)
631
- if natref and natref.kitten(@vpc.deploy)
632
- @nat = natref.kitten(@vpc.deploy)
633
- end
634
- end
635
- if @nat.nil? and !@vpc.nil? and (
636
- @config['vpc'].has_key?("nat_host_id") or
637
- @config['vpc'].has_key?("nat_host_tag") or
638
- @config['vpc'].has_key?("nat_host_ip") or
639
- @config['vpc'].has_key?("nat_host_name")
640
- )
641
-
642
- nat_tag_key, nat_tag_value = @config['vpc']['nat_host_tag'].split(/=/, 2) if !@config['vpc']['nat_host_tag'].nil?
643
-
644
- @nat = @vpc.findBastion(
645
- nat_name: @config['vpc']['nat_host_name'],
646
- nat_cloud_id: @config['vpc']['nat_host_id'],
647
- nat_tag_key: nat_tag_key,
648
- nat_tag_value: nat_tag_value,
649
- nat_ip: @config['vpc']['nat_host_ip']
650
- )
651
-
652
- if @nat.nil?
653
- if !@vpc.cloud_desc.nil?
654
- @nat = @vpc.findNat(
655
- nat_cloud_id: @config['vpc']['nat_host_id'],
656
- nat_filter_key: "vpc-id",
657
- region: @config['vpc']["region"],
658
- nat_filter_value: @vpc.cloud_id,
659
- credentials: @config['credentials']
660
- )
661
- else
662
- @nat = @vpc.findNat(
663
- nat_cloud_id: @config['vpc']['nat_host_id'],
664
- region: @config['vpc']["region"],
665
- credentials: @config['credentials']
666
- )
667
- end
668
- end
669
- end
670
- if @vpc.nil? and @config['vpc']
671
- feck = MU::Config::Ref.get(@config['vpc'])
672
- feck.kitten(@deploy, debug: true)
673
- pp feck
674
- raise MuError.new "#{self.class.cfg_name} #{@config['name']} failed to locate its VPC", details: @config['vpc']
675
- end
538
+ @vpc, @nat = myVpc(@config['vpc'], loglevel: loglevel, debug: debug)
676
539
  elsif self.class.cfg_name == "vpc"
677
540
  @vpc = self
678
541
  end
679
542
 
680
- # Google accounts usually have a useful default VPC we can use
681
- if @vpc.nil? and @project_id and @cloud == "Google" and
682
- self.class.can_live_in_vpc
683
- MU.log "Seeing about default VPC for #{self}", MU::NOTICE
684
- vpcs = MU::MommaCat.findStray(
685
- "Google",
686
- "vpc",
687
- cloud_id: "default",
688
- habitats: [@project_id],
689
- credentials: @credentials,
690
- dummy_ok: true,
691
- debug: debug
692
- )
693
- @vpc = vpcs.first if !vpcs.nil? and vpcs.size > 0
694
- end
695
-
696
543
  # Special dependencies: LoadBalancers I've asked to attach to an
697
544
  # instance.
698
545
  if @config.has_key?("loadbalancers")
@@ -738,7 +585,7 @@ module MU
738
585
  MU.log "Couldn't find existing resource #{ext_deploy["cloud_id"]}, #{ext_deploy["cloud_type"]}", MU::ERR if found.nil?
739
586
  @deploy.notify(ext_deploy["cloud_type"], found.config["name"], found.deploydata, mu_name: found.mu_name, triggering_node: @mu_name)
740
587
  elsif ext_deploy["mu_name"] && ext_deploy["deploy_id"]
741
- MU.log "#{self}: Importing metadata for #{ext_deploy["cloud_type"]} #{ext_deploy["mu_name"]} from #{ext_deploy["deploy_id"]}"
588
+ MU.log "#{self}: Importing metadata for #{ext_deploy["cloud_type"]} #{ext_deploy["mu_name"]} from #{ext_deploy["deploy_id"]}", MU::DEBUG
742
589
  found = MU::MommaCat.findStray(
743
590
  @config['cloud'],
744
591
  ext_deploy["cloud_type"],
@@ -751,7 +598,7 @@ module MU
751
598
  if found.nil?
752
599
  MU.log "Couldn't find existing resource #{ext_deploy["mu_name"]}/#{ext_deploy["deploy_id"]}, #{ext_deploy["cloud_type"]}", MU::ERR
753
600
  else
754
- @deploy.notify(ext_deploy["cloud_type"], found.config["name"], found.deploydata, mu_name: ext_deploy["mu_name"], triggering_node: @mu_name)
601
+ @deploy.notify(ext_deploy["cloud_type"], found.config["name"], found.deploydata, mu_name: ext_deploy["mu_name"], triggering_node: @mu_name, no_write: true)
755
602
  end
756
603
  else
757
604
  MU.log "Trying to find existing deploy, but either the cloud_id is not valid or no mu_name and deploy_id where provided", MU::ERR
@@ -774,33 +621,209 @@ module MU
774
621
  return [@dependencies, @vpc, @loadbalancers]
775
622
  end
776
623
 
624
+ # Resolve a VPC block to an actual resource
625
+ def myVpc(vpc_block = @config['vpc'], loglevel: MU::DEBUG, debug: false)
626
+ vpc_obj = nat_obj = nil
627
+
628
+ vpc_block['credentials'] ||= @credentials
629
+ vpc_block["id"] ||= vpc_block["vpc_id"] # old deploys
630
+ vpc_block["name"] ||= vpc_block["vpc_name"] # old deploys
631
+ if vpc_block['habitat']
632
+ vpc_block['habitat'] = MU::Config::Ref.get(vpc_block['habitat'])
633
+ end
634
+ habitats_arg = if vpc_block['habitat']
635
+ [vpc_block['habitat'].id]
636
+ else
637
+ [@project_id]
638
+ end
639
+
640
+ # If something hash-ified a MU::Config::Ref here, fix it
641
+ if !vpc_block["id"].nil? and vpc_block["id"].is_a?(Hash)
642
+ vpc_block["id"] = MU::Config::Ref.new(vpc_block["id"])
643
+ end
644
+ if !vpc_block["id"].nil?
645
+ if vpc_block["id"].is_a?(MU::Config::Ref) and !vpc_block["id"].kitten.nil?
646
+ vpc_obj = vpc_block["id"].kitten(@deploy)
647
+ else
648
+ vpc_ref = MU::Config::Ref.get(vpc_block)
649
+ vpc_obj = vpc_ref.kitten(@deploy)
650
+ end
651
+ elsif !vpc_block["name"].nil? and @deploy
652
+ MU.log "Attempting findLitterMate on VPC for #{self}", loglevel, details: vpc_block
653
+
654
+ sib_by_name = @deploy.findLitterMate(name: vpc_block['name'], type: "vpcs", return_all: true, habitat: vpc_block['project'], debug: debug)
655
+ if sib_by_name.is_a?(Hash)
656
+ if sib_by_name.size == 1
657
+ vpc_obj = sib_by_name.values.first
658
+ MU.log "Single VPC match for #{self}", loglevel, details: vpc_obj.to_s
659
+ else
660
+ # XXX ok but this is the wrong place for this really the config parser needs to sort this out somehow
661
+ # we got multiple matches, try to pick one by preferred subnet
662
+ # behavior
663
+ MU.log "Sorting a bunch of VPC matches for #{self}", loglevel, details: sib_by_name.map { |s| s.to_s }.join(", ")
664
+ sib_by_name.values.each { |sibling|
665
+ all_private = sibling.subnets.map { |s| s.private? }.all?(true)
666
+ all_public = sibling.subnets.map { |s| s.private? }.all?(false)
667
+ names = sibling.subnets.map { |s| s.name }
668
+ ids = sibling.subnets.map { |s| s.cloud_id }
669
+ if all_private and ["private", "all_private"].include?(vpc_block['subnet_pref'])
670
+ vpc_obj = sibling
671
+ break
672
+ elsif all_public and ["public", "all_public"].include?(vpc_block['subnet_pref'])
673
+ vpc_obj = sibling
674
+ break
675
+ elsif vpc_block['subnet_name'] and
676
+ names.include?(vpc_block['subnet_name'])
677
+ #puts "CHOOSING #{vpc_obj.to_s} 'cause it has #{vpc_block['subnet_name']}"
678
+ vpc_obj = sibling
679
+ break
680
+ elsif vpc_block['subnet_id'] and
681
+ ids.include?(vpc_block['subnet_id'])
682
+ vpc_obj = sibling
683
+ break
684
+ end
685
+ }
686
+ if !vpc_obj
687
+ sibling = sib_by_name.values.sample
688
+ MU.log "Got multiple matching VPCs for #{self.class.cfg_name} #{@mu_name}, so I'm arbitrarily choosing #{sibling.mu_name}", MU::WARN, details: vpc_block
689
+ vpc_obj = sibling
690
+ end
691
+ end
692
+ else
693
+ vpc_obj = sib_by_name
694
+ MU.log "Found exact VPC match for #{self}", loglevel, details: sib_by_name.to_s
695
+ end
696
+ else
697
+ MU.log "No shortcuts available to fetch VPC for #{self}", loglevel, details: vpc_block
698
+ end
699
+
700
+ if !vpc_obj and !vpc_block["name"].nil? and
701
+ @dependencies.has_key?("vpc") and
702
+ @dependencies["vpc"].has_key?(vpc_block["name"])
703
+ MU.log "Grabbing VPC I see in @dependencies['vpc']['#{vpc_block["name"]}'] for #{self}", loglevel, details: vpc_block
704
+ vpc_obj = @dependencies["vpc"][vpc_block["name"]]
705
+ elsif !vpc_obj
706
+ tag_key, tag_value = vpc_block['tag'].split(/=/, 2) if !vpc_block['tag'].nil?
707
+ if !vpc_block.has_key?("id") and
708
+ !vpc_block.has_key?("deploy_id") and !@deploy.nil?
709
+ vpc_block["deploy_id"] = @deploy.deploy_id
710
+ end
711
+ MU.log "Doing findStray for VPC for #{self}", loglevel, details: vpc_block
712
+ vpcs = MU::MommaCat.findStray(
713
+ @config['cloud'],
714
+ "vpc",
715
+ deploy_id: vpc_block["deploy_id"],
716
+ cloud_id: vpc_block["id"],
717
+ name: vpc_block["name"],
718
+ tag_key: tag_key,
719
+ tag_value: tag_value,
720
+ habitats: habitats_arg,
721
+ region: vpc_block["region"],
722
+ calling_deploy: @deploy,
723
+ credentials: vpc_block["credentials"],
724
+ dummy_ok: true,
725
+ debug: debug
726
+ )
727
+ vpc_obj = vpcs.first if !vpcs.nil? and vpcs.size > 0
728
+ end
729
+ if vpc_obj and vpc_obj.config and vpc_obj.config['bastion'] and
730
+ vpc_obj.config['bastion'].to_h['name'] != @config['name']
731
+ refhash = vpc_obj.config['bastion'].to_h
732
+ refhash['deploy_id'] ||= vpc_obj.deploy.deploy_id
733
+ natref = MU::Config::Ref.get(refhash)
734
+ if natref and natref.kitten(vpc_obj.deploy)
735
+ nat_obj = natref.kitten(vpc_obj.deploy)
736
+ end
737
+ end
738
+ if nat_obj.nil? and !vpc_obj.nil? and (
739
+ vpc_block.has_key?("nat_host_id") or
740
+ vpc_block.has_key?("nat_host_tag") or
741
+ vpc_block.has_key?("nat_host_ip") or
742
+ vpc_block.has_key?("nat_host_name")
743
+ )
744
+
745
+ nat_tag_key, nat_tag_value = vpc_block['nat_host_tag'].split(/=/, 2) if !vpc_block['nat_host_tag'].nil?
746
+
747
+ nat_obj = vpc_obj.findBastion(
748
+ nat_name: vpc_block['nat_host_name'],
749
+ nat_cloud_id: vpc_block['nat_host_id'],
750
+ nat_tag_key: nat_tag_key,
751
+ nat_tag_value: nat_tag_value,
752
+ nat_ip: vpc_block['nat_host_ip']
753
+ )
754
+
755
+ if naa_obj.nil?
756
+ if !vpc_obj.cloud_desc.nil?
757
+ nat_obj = vpc_obj.findNat(
758
+ nat_cloud_id: vpc_block['nat_host_id'],
759
+ nat_filter_key: "vpc-id",
760
+ region: vpc_block["region"],
761
+ nat_filter_value: vpc_obj.cloud_id,
762
+ credentials: vpc_block['credentials']
763
+ )
764
+ else
765
+ nat_obj = vpc_obj.findNat(
766
+ nat_cloud_id: vpc_block['nat_host_id'],
767
+ region: vpc_block["region"],
768
+ credentials: vpc_block['credentials']
769
+ )
770
+ end
771
+ end
772
+ end
773
+ if vpc_obj.nil? and vpc_block
774
+ feck = MU::Config::Ref.get(vpc_block)
775
+ feck.kitten(@deploy, debug: true)
776
+ pp feck
777
+ raise MuError.new "#{self.class.cfg_name} #{@config['name']} failed to locate its VPC", details: vpc_block
778
+ end
779
+
780
+ # Google accounts usually have a useful default VPC we can use
781
+ if vpc_obj.nil? and @project_id and @cloud == "Google" and
782
+ self.class.can_live_in_vpc
783
+ MU.log "Seeing about default VPC for #{self}", MU::NOTICE
784
+ vpcs = MU::MommaCat.findStray(
785
+ "Google",
786
+ "vpc",
787
+ cloud_id: "default",
788
+ habitats: [@project_id],
789
+ credentials: vpc_block['credentials'],
790
+ dummy_ok: true,
791
+ debug: debug
792
+ )
793
+ vpc_obj = vpcs.first if !vpcs.nil? and vpcs.size > 0
794
+ end
795
+
796
+ [vpc_obj, nat_obj]
797
+ end
798
+
777
799
  # Using the automatically-defined +@vpc+ from {dependencies} in
778
800
  # conjunction with our config, return our configured subnets.
779
801
  # @return [Array<MU::Cloud::VPC::Subnet>]
780
- def mySubnets
802
+ def mySubnets(vpc = @vpc, vpc_block = @config["vpc"])
781
803
  dependencies
782
- if !@vpc or !@config["vpc"]
804
+ vpc ||= @vpc # in case dependencies worked it out for us
805
+ if !vpc or !vpc_block
783
806
  return nil
784
807
  end
785
808
 
786
- if @config["vpc"]["subnet_id"] or @config["vpc"]["subnet_name"]
787
- @config["vpc"]["subnets"] ||= []
809
+ if vpc_block["subnet_id"] or vpc_block["subnet_name"]
810
+ vpc_block["subnets"] ||= []
788
811
  subnet_block = {}
789
- subnet_block["subnet_id"] = @config["vpc"]["subnet_id"] if @config["vpc"]["subnet_id"]
790
- subnet_block["subnet_name"] = @config["vpc"]["subnet_name"] if @config["vpc"]["subnet_name"]
791
- @config["vpc"]["subnets"] << subnet_block
792
- @config["vpc"]["subnets"].uniq!
812
+ subnet_block["subnet_id"] = vpc_block["subnet_id"] if vpc_block["subnet_id"]
813
+ subnet_block["subnet_name"] = vpc_block["subnet_name"] if vpc_block["subnet_name"]
814
+ vpc_block["subnets"] << subnet_block
815
+ vpc_block["subnets"].uniq!
793
816
  end
794
817
 
795
- if (!@config["vpc"]["subnets"] or @config["vpc"]["subnets"].empty?) and
796
- !@config["vpc"]["subnet_id"]
797
- return @vpc.subnets
818
+ if (!vpc_block["subnets"] or vpc_block["subnets"].empty?) and
819
+ !vpc_block["subnet_id"]
820
+ return vpc.subnets
798
821
  end
799
822
 
800
823
  subnets = []
801
- @config["vpc"]["subnets"].each { |subnet|
802
- subnet_obj = @vpc.getSubnet(cloud_id: subnet["subnet_id"].to_s, name: subnet["subnet_name"].to_s)
803
- raise MuError.new "Couldn't find a live subnet for #{self} matching #{subnet} in #{@vpc}", details: @vpc.subnets.map { |s| s.name }.join(",") if subnet_obj.nil?
824
+ vpc_block["subnets"].each { |subnet|
825
+ subnet_obj = vpc.getSubnet(cloud_id: subnet["subnet_id"].to_s, name: subnet["subnet_name"].to_s)
826
+ raise MuError.new "Couldn't find a live subnet for #{self} matching #{subnet} in #{vpc}", details: vpc.subnets.map { |s| s.name }.join(",") if subnet_obj.nil?
804
827
  subnets << subnet_obj
805
828
  }
806
829
 
@@ -872,15 +895,23 @@ module MU
872
895
  @cloudobj.describe if method != :describe
873
896
 
874
897
  # Don't run through dependencies on simple attr_reader lookups
875
- if ![:dependencies, :cloud_id, :config, :mu_name].include?(method)
898
+ if ![:dependencies, :cloud_id, :config, :mu_name, :active?].include?(method)
876
899
  @cloudobj.dependencies
877
900
  end
878
901
 
879
902
  retval = nil
880
- if !args.nil? and args.size == 1
881
- retval = @cloudobj.method(method).call(args.first)
882
- elsif !args.nil? and args.size > 0
883
- retval = @cloudobj.method(method).call(*args)
903
+ if !args.nil?
904
+ if args.is_a?(Hash)
905
+ retval = @cloudobj.method(method).call(**args)
906
+ elsif args.is_a?(Array)
907
+ if args.size == 1 and args.first.is_a?(Hash)
908
+ retval = @cloudobj.method(method).call(**args.first)
909
+ else
910
+ retval = @cloudobj.method(method).call(*args)
911
+ end
912
+ else
913
+ retval = @cloudobj.method(method).call(args)
914
+ end
884
915
  else
885
916
  retval = @cloudobj.method(method).call
886
917
  end
@@ -1 +1 @@
1
- modules/mu/cloud/server.rb
1
+ server.rb
@@ -51,7 +51,7 @@ module MU
51
51
  win_set_pw = nil
52
52
 
53
53
  if windows? and !@config['use_cloud_provider_windows_password']
54
- # This covers both the case where we have a windows password passed from a vault and where we need to use a a random Windows Admin password generated by MU::Cloud::Server.generateWindowsPassword
54
+ # This covers both the case where we have a windows password passed from a vault and where we need to use a a random Windows Admin password generated by MU::Cloud::Server.generatePassword
55
55
  pw = @groomer.getSecret(
56
56
  vault: @config['mu_name'],
57
57
  item: "windows_credentials",
@@ -156,9 +156,10 @@ module MU
156
156
  :config => false,
157
157
  :keys_only => true,
158
158
  :keys => [ssh_keydir+"/"+nat_ssh_key, ssh_keydir+"/"+@deploy.ssh_key_name],
159
- :verify_host_key => false,
159
+ :verify_host_key => :never, # grr
160
160
  # :verbose => :info,
161
- :host_key => "ssh-rsa",
161
+ # :host_key => "ssh-rsa",
162
+ :host_key => "ecdsa-sha2-nistp256",
162
163
  :port => 22,
163
164
  :auth_methods => ['publickey'],
164
165
  :proxy => proxy
@@ -172,9 +173,10 @@ module MU
172
173
  :config => false,
173
174
  :keys_only => true,
174
175
  :keys => [ssh_keydir+"/"+@deploy.ssh_key_name],
175
- :verify_host_key => false,
176
+ :verify_host_key => :never, # grr
176
177
  # :verbose => :info,
177
- :host_key => "ssh-rsa",
178
+ # :host_key => "ssh-rsa",
179
+ :host_key => "ecdsa-sha2-nistp256",
178
180
  :port => 22,
179
181
  :auth_methods => ['publickey']
180
182
  )
@@ -111,7 +111,7 @@ module MU
111
111
 
112
112
  credsets.each { |creds|
113
113
  args[:credentials] = creds
114
- found = cloudclass.find(args)
114
+ found = cloudclass.find(**args)
115
115
  if !found.nil?
116
116
  if found.is_a?(Hash)
117
117
  allfound.merge!(found)
@@ -150,7 +150,7 @@ module MU
150
150
 
151
151
  raise MuCloudResourceNotImplemented if !cloudclass.respond_to?(:cleanup) or cloudclass.method(:cleanup).owner.to_s != "#<Class:#{cloudclass}>"
152
152
  MU.log "Invoking #{cloudclass}.cleanup from #{shortname}", MU::DEBUG, details: flags
153
- cloudclass.cleanup(params)
153
+ cloudclass.cleanup(**params)
154
154
  rescue MuCloudResourceNotImplemented
155
155
  MU.log "No #{cloud} implementation of #{shortname}.cleanup, skipping", MU::DEBUG, details: flags
156
156
  rescue StandardError => e
data/modules/mu/cloud.rb CHANGED
@@ -246,7 +246,7 @@ module MU
246
246
  :deps_wait_on_my_creation => true,
247
247
  :waits_on_parent_completion => false,
248
248
  :class => @@generic_class_methods,
249
- :instance => @@generic_instance_methods + [:groom, :registerNode]
249
+ :instance => @@generic_instance_methods + [:groom, :registerTarget]
250
250
  },
251
251
  :Server => {
252
252
  :has_multiples => true,
@@ -85,7 +85,7 @@ module MU
85
85
 
86
86
  if bucket['upload']
87
87
  bucket['upload'].each { |batch|
88
- if !File.exists?(batch['source'])
88
+ if !File.exist?(batch['source'])
89
89
  MU.log "Bucket '#{bucket['name']}' specifies upload for file/directory that does not exist", MU::ERR, details: batch
90
90
  ok = false
91
91
  next
@@ -38,6 +38,11 @@ module MU
38
38
  "description" => "Triggers which will cause this function to be invoked."
39
39
  }
40
40
  },
41
+ "loadbalancers" => {
42
+ "type" => "array",
43
+ "minItems" => 1,
44
+ "items" => MU::Config::LoadBalancer.reference
45
+ },
41
46
  "handler" => {
42
47
  "type" => "string",
43
48
  "description" => "The function within your code that is should be called to begin execution. For Node.js, it is the module-name.export value in your function. For Java, it can be package.class-name::handler or package.class-name. For more information, see https://docs.aws.amazon.com/lambda/latest/dg/java-programming-model-handler-types.html"
@@ -114,7 +119,7 @@ module MU
114
119
  if function['code']
115
120
  ['zip_file', 'path'].each { |src|
116
121
  if function['code'][src]
117
- if !File.readable?(function['code'][src]) and !Dir.exists?(function['code'][src])
122
+ if !File.readable?(function['code'][src]) and !Dir.exist?(function['code'][src])
118
123
  MU.log "Function '#{function['name']}' specifies a deployment package that I can't read at #{function['code'][src]}", MU::ERR
119
124
  ok = false
120
125
  else
@@ -443,13 +443,14 @@ module MU
443
443
  l["targetgroup"] = tgname
444
444
  tg = {
445
445
  "name" => tgname,
446
- "proto" => l["instance_protocol"],
447
- "port" => l["instance_port"]
446
+ "proto" => l["instance_protocol"] || l["lb_protocol"],
447
+ "port" => l["instance_port"] || l["lb_port"]
448
448
  }
449
449
  if l["redirect"]
450
450
  tg["proto"] ||= l["redirect"]["protocol"]
451
451
  tg["port"] ||= l["redirect"]["port"]
452
452
  end
453
+ tg["vpc"] = l["vpc"] if l["vpc"]
453
454
  l['healthcheck'] ||= lb['healthcheck'] if lb['healthcheck']
454
455
  if l["healthcheck"]
455
456
  hc_target = l['healthcheck']['target'].match(/^([^:]+):(\d+)(.*)/)
@@ -461,6 +462,18 @@ module MU
461
462
  end
462
463
  lb["targetgroups"] << tg
463
464
  }
465
+ elsif lb['listeners'].nil?
466
+ # well ok, manufacture listeners out of targetgroups then?
467
+ lb['listeners'] ||= []
468
+ lb["targetgroups"].each { |tg|
469
+ listener = {
470
+ "targetgroup" => tg['name'],
471
+ "lb_protocol" => tg["proto"],
472
+ "lb_port" => tg["port"]
473
+ }
474
+ listener["vpc"] = tg["vpc"] if tg["vpc"]
475
+ lb['listeners'] << listener
476
+ }
464
477
  else
465
478
  lb['listeners'].each { |l|
466
479
  found = false
@@ -477,6 +490,15 @@ module MU
477
490
  }
478
491
  end
479
492
 
493
+ lb['targetgroups'].each { |tg|
494
+ if tg['target']
495
+ tg['target']['cloud'] ||= lb['cloud']
496
+ if tg['target']['name']
497
+ MU::Config.addDependency(lb, tg['target']['name'], tg['target']['type'], their_phase: "create", my_phase: "groom")
498
+ end
499
+ end
500
+ }
501
+
480
502
  lb['listeners'].each { |l|
481
503
  if !l['rules'].nil? and l['rules'].size > 0
482
504
  l['rules'].each { |r|
@@ -80,6 +80,11 @@ module MU
80
80
  end
81
81
  }
82
82
 
83
+ if MU.mommacat
84
+ @mommacat ||= MU.mommacat
85
+ @deploy_id ||= MU.mommacat.deploy_id
86
+ end
87
+
83
88
  }
84
89
 
85
90
  # if we get here, there was no match
@@ -291,6 +296,7 @@ module MU
291
296
  return nil if !cloud or !@type
292
297
 
293
298
  _shortclass, _cfg_name, cfg_plural, _classname, _attrs = MU::Cloud.getResourceNames(@type, false)
299
+
294
300
  if cfg_plural
295
301
  @type = cfg_plural # make sure this is the thing we expect
296
302
  else
@@ -299,6 +305,12 @@ module MU
299
305
 
300
306
  loglevel = debug ? MU::NOTICE : MU::DEBUG
301
307
 
308
+ if @name and !@id and !mommacat and !@deploy_id and MU.mommacat
309
+ MU.log "Checking active deploy for #{@type} #{@name} first", loglevel
310
+ resp = kitten(MU.mommacat, shallow: shallow, debug: debug, cloud: cloud)
311
+ return resp if resp
312
+ end
313
+
302
314
  if debug
303
315
  MU.log "this mf kitten", MU::WARN, details: caller
304
316
  end
@@ -28,7 +28,7 @@ module MU
28
28
  "name" => {
29
29
  "type" => "string",
30
30
  "description" => "The name of a cloud provider role to create",
31
- "pattern" => '^[a-zA-Z0-9_\-]+$'
31
+ "pattern" => '^[a-zA-Z0-9_\-\.]+$'
32
32
  },
33
33
  "import" => {
34
34
  "type" => "array",