cloud-mu 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +10 -2
  3. data/bin/mu-adopt +5 -1
  4. data/bin/mu-load-config.rb +2 -3
  5. data/bin/mu-run-tests +112 -27
  6. data/cloud-mu.gemspec +20 -20
  7. data/cookbooks/mu-tools/libraries/helper.rb +2 -1
  8. data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
  9. data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
  10. data/cookbooks/mu-tools/resources/disk.rb +1 -1
  11. data/extras/image-generators/Google/centos6.yaml +1 -0
  12. data/extras/image-generators/Google/centos7.yaml +1 -1
  13. data/modules/mommacat.ru +5 -15
  14. data/modules/mu.rb +10 -14
  15. data/modules/mu/adoption.rb +20 -14
  16. data/modules/mu/cleanup.rb +13 -9
  17. data/modules/mu/cloud.rb +26 -26
  18. data/modules/mu/clouds/aws.rb +100 -59
  19. data/modules/mu/clouds/aws/alarm.rb +4 -2
  20. data/modules/mu/clouds/aws/bucket.rb +25 -21
  21. data/modules/mu/clouds/aws/cache_cluster.rb +25 -23
  22. data/modules/mu/clouds/aws/collection.rb +21 -20
  23. data/modules/mu/clouds/aws/container_cluster.rb +47 -26
  24. data/modules/mu/clouds/aws/database.rb +57 -68
  25. data/modules/mu/clouds/aws/dnszone.rb +14 -14
  26. data/modules/mu/clouds/aws/endpoint.rb +20 -16
  27. data/modules/mu/clouds/aws/firewall_rule.rb +19 -16
  28. data/modules/mu/clouds/aws/folder.rb +7 -7
  29. data/modules/mu/clouds/aws/function.rb +15 -12
  30. data/modules/mu/clouds/aws/group.rb +14 -10
  31. data/modules/mu/clouds/aws/habitat.rb +16 -13
  32. data/modules/mu/clouds/aws/loadbalancer.rb +16 -15
  33. data/modules/mu/clouds/aws/log.rb +13 -10
  34. data/modules/mu/clouds/aws/msg_queue.rb +15 -8
  35. data/modules/mu/clouds/aws/nosqldb.rb +18 -11
  36. data/modules/mu/clouds/aws/notifier.rb +11 -6
  37. data/modules/mu/clouds/aws/role.rb +87 -70
  38. data/modules/mu/clouds/aws/search_domain.rb +30 -19
  39. data/modules/mu/clouds/aws/server.rb +102 -72
  40. data/modules/mu/clouds/aws/server_pool.rb +47 -28
  41. data/modules/mu/clouds/aws/storage_pool.rb +5 -6
  42. data/modules/mu/clouds/aws/user.rb +13 -10
  43. data/modules/mu/clouds/aws/vpc.rb +135 -121
  44. data/modules/mu/clouds/azure.rb +16 -9
  45. data/modules/mu/clouds/azure/container_cluster.rb +2 -3
  46. data/modules/mu/clouds/azure/firewall_rule.rb +10 -10
  47. data/modules/mu/clouds/azure/habitat.rb +8 -6
  48. data/modules/mu/clouds/azure/loadbalancer.rb +5 -5
  49. data/modules/mu/clouds/azure/role.rb +8 -10
  50. data/modules/mu/clouds/azure/server.rb +65 -25
  51. data/modules/mu/clouds/azure/user.rb +5 -7
  52. data/modules/mu/clouds/azure/vpc.rb +12 -15
  53. data/modules/mu/clouds/cloudformation.rb +8 -7
  54. data/modules/mu/clouds/cloudformation/vpc.rb +2 -4
  55. data/modules/mu/clouds/google.rb +39 -24
  56. data/modules/mu/clouds/google/bucket.rb +9 -11
  57. data/modules/mu/clouds/google/container_cluster.rb +27 -42
  58. data/modules/mu/clouds/google/database.rb +6 -9
  59. data/modules/mu/clouds/google/firewall_rule.rb +11 -10
  60. data/modules/mu/clouds/google/folder.rb +16 -9
  61. data/modules/mu/clouds/google/function.rb +127 -161
  62. data/modules/mu/clouds/google/group.rb +21 -18
  63. data/modules/mu/clouds/google/habitat.rb +18 -15
  64. data/modules/mu/clouds/google/loadbalancer.rb +14 -16
  65. data/modules/mu/clouds/google/role.rb +48 -31
  66. data/modules/mu/clouds/google/server.rb +105 -105
  67. data/modules/mu/clouds/google/server_pool.rb +12 -31
  68. data/modules/mu/clouds/google/user.rb +67 -13
  69. data/modules/mu/clouds/google/vpc.rb +58 -65
  70. data/modules/mu/config.rb +89 -1738
  71. data/modules/mu/config/bucket.rb +3 -3
  72. data/modules/mu/config/collection.rb +3 -3
  73. data/modules/mu/config/container_cluster.rb +2 -2
  74. data/modules/mu/config/dnszone.rb +5 -5
  75. data/modules/mu/config/doc_helpers.rb +517 -0
  76. data/modules/mu/config/endpoint.rb +3 -3
  77. data/modules/mu/config/firewall_rule.rb +118 -3
  78. data/modules/mu/config/folder.rb +3 -3
  79. data/modules/mu/config/function.rb +2 -2
  80. data/modules/mu/config/group.rb +3 -3
  81. data/modules/mu/config/habitat.rb +3 -3
  82. data/modules/mu/config/loadbalancer.rb +3 -3
  83. data/modules/mu/config/log.rb +3 -3
  84. data/modules/mu/config/msg_queue.rb +3 -3
  85. data/modules/mu/config/nosqldb.rb +3 -3
  86. data/modules/mu/config/notifier.rb +2 -2
  87. data/modules/mu/config/ref.rb +333 -0
  88. data/modules/mu/config/role.rb +3 -3
  89. data/modules/mu/config/schema_helpers.rb +508 -0
  90. data/modules/mu/config/search_domain.rb +3 -3
  91. data/modules/mu/config/server.rb +86 -58
  92. data/modules/mu/config/server_pool.rb +2 -2
  93. data/modules/mu/config/tail.rb +189 -0
  94. data/modules/mu/config/user.rb +3 -3
  95. data/modules/mu/config/vpc.rb +44 -4
  96. data/modules/mu/defaults/Google.yaml +2 -2
  97. data/modules/mu/deploy.rb +13 -10
  98. data/modules/mu/groomer.rb +1 -1
  99. data/modules/mu/groomers/ansible.rb +69 -24
  100. data/modules/mu/groomers/chef.rb +52 -44
  101. data/modules/mu/logger.rb +17 -14
  102. data/modules/mu/master.rb +317 -2
  103. data/modules/mu/master/chef.rb +3 -4
  104. data/modules/mu/master/ldap.rb +3 -3
  105. data/modules/mu/master/ssl.rb +12 -2
  106. data/modules/mu/mommacat.rb +85 -1766
  107. data/modules/mu/mommacat/daemon.rb +394 -0
  108. data/modules/mu/mommacat/naming.rb +366 -0
  109. data/modules/mu/mommacat/storage.rb +689 -0
  110. data/modules/tests/bucket.yml +4 -0
  111. data/modules/tests/{win2k12.yaml → needwork/win2k12.yaml} +0 -0
  112. data/modules/tests/regrooms/aws-iam.yaml +201 -0
  113. data/modules/tests/regrooms/bucket.yml +19 -0
  114. metadata +112 -102
@@ -87,7 +87,7 @@ module MU
87
87
  img = fetchImage(image_id, credentials: credentials)
88
88
  return DateTime.new if img.nil?
89
89
  return DateTime.parse(img.creation_timestamp)
90
- rescue ::Google::Apis::ClientError => e
90
+ rescue ::Google::Apis::ClientError
91
91
  end
92
92
 
93
93
  return DateTime.new
@@ -247,15 +247,22 @@ next if !create
247
247
  subnet_cfg = config['vpc']['subnets'].sample
248
248
 
249
249
  end
250
+
250
251
  subnet = vpc.getSubnet(name: subnet_cfg['subnet_name'], cloud_id: subnet_cfg['subnet_id'])
251
252
  if subnet.nil?
252
- raise MuError, "Couldn't find subnet details for #{subnet_cfg['subnet_name'] || subnet_cfg['subnet_id']} while configuring Server #{config['name']} (VPC: #{vpc.mu_name})"
253
+ if config['vpc']['name']
254
+ subnet = vpc.getSubnet(name: config['vpc']['name']+subnet_cfg['subnet_name'], cloud_id: subnet_cfg['subnet_id'])
255
+ end
256
+ if subnet.nil?
257
+ raise MuError, "Couldn't find subnet details for #{subnet_cfg['subnet_name'] || subnet_cfg['subnet_id']} while configuring Server #{config['name']} (VPC: #{vpc.mu_name})"
258
+ end
253
259
  end
254
260
 
255
261
  base_iface_obj = {
256
262
  :network => vpc.url,
257
263
  :subnetwork => subnet.url
258
264
  }
265
+
259
266
  if config['associate_public_ip']
260
267
  base_iface_obj[:access_configs] = [
261
268
  MU::Cloud::Google.compute(:AccessConfig).new
@@ -348,7 +355,7 @@ next if !create
348
355
  desc[:labels]["name"] = @mu_name.downcase
349
356
 
350
357
  if @config['network_tags'] and @config['network_tags'].size > 0
351
- desc[:tags] = U::Cloud::Google.compute(:Tags).new(
358
+ desc[:tags] = MU::Cloud::Google.compute(:Tags).new(
352
359
  items: @config['network_tags']
353
360
  )
354
361
  end
@@ -369,7 +376,7 @@ next if !create
369
376
  sleep 10
370
377
  end
371
378
  rescue ::Google::Apis::ClientError => e
372
- MU.log e.message, MU::ERR
379
+ MU.log e.message+" inserting instance into #{@project_id}/#{@config['availability_zone']}", MU::ERR, details: instanceobj
373
380
  raise e
374
381
  end while @cloud_id.nil?
375
382
 
@@ -394,7 +401,7 @@ next if !create
394
401
 
395
402
  notify
396
403
 
397
- rescue Exception => e
404
+ rescue StandardError => e
398
405
  if !cloud_desc.nil? and !done
399
406
  MU.log "Aborted before I could finish setting up #{@config['name']}, cleaning it up. Stack trace will print once cleanup is complete.", MU::WARN if !@deploy.nocleanup
400
407
  MU::MommaCat.unlockAll
@@ -445,7 +452,7 @@ next if !create
445
452
  )
446
453
  begin
447
454
  sleep 5
448
- end while cloud_desc.status != "TERMINATED" # means STOPPED
455
+ end while cloud_desc(use_cache: false).status != "TERMINATED" # means STOPPED
449
456
  end
450
457
 
451
458
  # Ask the Google API to start this node
@@ -462,30 +469,30 @@ next if !create
462
469
  end
463
470
 
464
471
  # Ask the Google API to restart this node
465
- # XXX unimplemented
466
- def reboot(hard = false)
472
+ # @param _hard [Boolean]: [IGNORED] Force a stop/start. This is the only available way to restart an instance in Google, so this flag is ignored.
473
+ def reboot(_hard = false)
467
474
  return if @cloud_id.nil?
468
-
475
+ stop
476
+ start
469
477
  end
470
478
 
471
479
  # Figure out what's needed to SSH into this server.
472
480
  # @return [Array<String>]: nat_ssh_key, nat_ssh_user, nat_ssh_host, canonical_ip, ssh_user, ssh_key_name, alternate_names
473
481
  def getSSHConfig
474
- node, config, deploydata = describe(cloud_id: @cloud_id)
482
+ describe(cloud_id: @cloud_id)
475
483
  # XXX add some awesome alternate names from metadata and make sure they end
476
484
  # up in MU::MommaCat's ssh config wangling
477
- ssh_keydir = Etc.getpwuid(Process.uid).dir+"/.ssh"
478
485
  return nil if @config.nil? or @deploy.nil?
479
486
 
480
487
  nat_ssh_key = nat_ssh_user = nat_ssh_host = nil
481
- if !@config["vpc"].nil? and !MU::Cloud::Google::VPC.haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
488
+ if !@config["vpc"].nil? and !MU::Cloud::Google::VPC.haveRouteToInstance?(cloud_desc, credentials: @config['credentials'])
482
489
 
483
490
  if !@nat.nil?
484
491
  if @nat.cloud_desc.nil?
485
492
  MU.log "NAT was missing cloud descriptor when called in #{@mu_name}'s getSSHConfig", MU::ERR
486
493
  return nil
487
494
  end
488
- foo, bar, baz, nat_ssh_host, nat_ssh_user, nat_ssh_key = @nat.getSSHConfig
495
+ _foo, _bar, _baz, nat_ssh_host, nat_ssh_user, nat_ssh_key = @nat.getSSHConfig
489
496
  if nat_ssh_user.nil? and !nat_ssh_host.nil?
490
497
  MU.log "#{@config["name"]} (#{MU.deploy_id}) is configured to use #{@config['vpc']} NAT #{nat_ssh_host}, but username isn't specified. Guessing root.", MU::ERR, details: caller
491
498
  nat_ssh_user = "root"
@@ -512,26 +519,24 @@ next if !create
512
519
  @cloud_id = instance_id
513
520
  end
514
521
 
515
- instance = cloud_desc
516
-
517
- node, config, deploydata = describe(cloud_id: @cloud_id)
522
+ node, _config, deploydata = describe(cloud_id: @cloud_id)
518
523
  instance = cloud_desc
519
524
  raise MuError, "Couldn't find instance of #{@mu_name} (#{@cloud_id})" if !instance
520
525
  return false if !MU::MommaCat.lock(@cloud_id+"-orchestrate", true)
521
526
  return false if !MU::MommaCat.lock(@cloud_id+"-groom", true)
522
527
 
523
528
  # MU::Cloud::AWS.createStandardTags(@cloud_id, region: @config['region'])
524
- # MU::MommaCat.createTag(@cloud_id, "Name", node, region: @config['region'])
529
+ # MU::Cloud::AWS.createTag(@cloud_id, "Name", node, region: @config['region'])
525
530
  #
526
531
  # if @config['optional_tags']
527
532
  # MU::MommaCat.listOptionalTags.each { |key, value|
528
- # MU::MommaCat.createTag(@cloud_id, key, value, region: @config['region'])
533
+ # MU::Cloud::AWS.createTag(@cloud_id, key, value, region: @config['region'])
529
534
  # }
530
535
  # end
531
536
  #
532
537
  # if !@config['tags'].nil?
533
538
  # @config['tags'].each { |tag|
534
- # MU::MommaCat.createTag(@cloud_id, tag['key'], tag['value'], region: @config['region'])
539
+ # MU::Cloud::AWS.createTag(@cloud_id, tag['key'], tag['value'], region: @config['region'])
535
540
  # }
536
541
  # end
537
542
  # MU.log "Tagged #{node} (#{@cloud_id}) with MU-ID=#{MU.deploy_id}", MU::DEBUG
@@ -609,8 +614,8 @@ next if !create
609
614
  @named = true
610
615
  end
611
616
 
612
- nat_ssh_key, nat_ssh_user, nat_ssh_host, canonical_ip, ssh_user, ssh_key_name = getSSHConfig
613
- if !nat_ssh_host and !MU::Cloud::Google::VPC.haveRouteToInstance?(cloud_desc, region: @config['region'], credentials: @config['credentials'])
617
+ _nat_ssh_key, _nat_ssh_user, nat_ssh_host, _canonical_ip, _ssh_user, _ssh_key_name = getSSHConfig
618
+ if !nat_ssh_host and !MU::Cloud::Google::VPC.haveRouteToInstance?(cloud_desc, credentials: @config['credentials'])
614
619
  # XXX check if canonical_ip is in the private ranges
615
620
  # raise MuError, "#{node} has no NAT host configured, and I have no other route to it"
616
621
  end
@@ -641,8 +646,8 @@ next if !create
641
646
  # Locate an existing instance or instances and return an array containing matching AWS resource descriptors for those that match.
642
647
  # @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching instances
643
648
  def self.find(**args)
644
- args[:project] ||= args[:habitat]
645
- args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
649
+ args = MU::Cloud::Google.findLocationArgs(args)
650
+
646
651
  if !args[:region].nil? and MU::Cloud::Google.listRegions.include?(args[:region])
647
652
  regions = [args[:region]]
648
653
  else
@@ -720,9 +725,6 @@ next if !create
720
725
  # Return a description of this resource appropriate for deployment
721
726
  # metadata. Arguments reflect the return values of the MU::Cloud::[Resource].describe method
722
727
  def notify
723
- node, config, deploydata = describe(cloud_id: @cloud_id, update_cache: true)
724
- deploydata = {} if deploydata.nil?
725
-
726
728
  if cloud_desc.nil?
727
729
  raise MuError, "Failed to load instance metadata for #{@config['mu_name']}/#{@cloud_id}"
728
730
  end
@@ -783,7 +785,7 @@ next if !create
783
785
 
784
786
  MU::MommaCat.lock(@cloud_id+"-groom")
785
787
 
786
- node, config, deploydata = describe(cloud_id: @cloud_id)
788
+ node, _config, deploydata = describe(cloud_id: @cloud_id)
787
789
 
788
790
  if node.nil? or node.empty?
789
791
  raise MuError, "MU::Cloud::Google::Server.groom was called without a mu_name"
@@ -859,9 +861,9 @@ next if !create
859
861
  project: @project_id,
860
862
  exclude_storage: img_cfg['image_exclude_storage'],
861
863
  make_public: img_cfg['public'],
862
- tags: @config['tags'],
864
+ tags: @tags,
863
865
  zone: @config['availability_zone'],
864
- family: @config['family'],
866
+ family: img_cfg['family'],
865
867
  credentials: @config['credentials']
866
868
  )
867
869
  @deploy.notify("images", @config['name'], {"image_id" => image_id})
@@ -897,50 +899,50 @@ next if !create
897
899
  raise MuError, "Failed to find instance '#{instance_id}' in createImage"
898
900
  end
899
901
 
900
- labels = {}
901
- MU::MommaCat.listStandardTags.each_pair { |key, value|
902
- if !value.nil?
903
- labels[key.downcase] = value.downcase.gsub(/[^a-z0-9\-\_]/i, "_")
904
- end
905
- }
902
+ labels = Hash[tags.keys.map { |k|
903
+ [k.downcase, tags[k].downcase.gsub(/[^-_a-z0-9]/, '-')] }
904
+ ]
905
+ labels["name"] = name
906
906
 
907
907
  bootdisk = nil
908
908
  threads = []
909
909
  parent_thread_id = Thread.current.object_id
910
- instance[instance_id].disks.each { |disk|
911
- threads << Thread.new {
912
- Thread.abort_on_exception = false
913
- MU.dupGlobals(parent_thread_id)
914
- if disk.boot
915
- bootdisk = disk.source
916
- else
917
- snapobj = MU::Cloud::Google.compute(:Snapshot).new(
918
- name: name+"-"+disk.device_name,
919
- description: "Mu image created from #{name} (#{disk.device_name})"
920
- )
921
- diskname = disk.source.gsub(/.*?\//, "")
922
- MU.log "Creating snapshot of #{diskname} in #{zone}", MU::NOTICE, details: snapobj
923
- snap = MU::Cloud::Google.compute(credentials: credentials).create_disk_snapshot(
924
- project,
925
- zone,
926
- diskname,
927
- snapobj
928
- )
929
- MU::Cloud::Google.compute(credentials: credentials).set_snapshot_labels(
930
- project,
931
- snap.name,
932
- MU::Cloud::Google.compute(:GlobalSetLabelsRequest).new(
933
- label_fingerprint: snap.label_fingerprint,
934
- labels: labels.merge({
935
- "mu-device-name" => disk.device_name,
936
- "mu-parent-image" => name,
937
- "mu-orig-zone" => zone
938
- })
910
+ if !exclude_storage
911
+ instance[instance_id].disks.each { |disk|
912
+ threads << Thread.new {
913
+ Thread.abort_on_exception = false
914
+ MU.dupGlobals(parent_thread_id)
915
+ if disk.boot
916
+ bootdisk = disk.source
917
+ else
918
+ snapobj = MU::Cloud::Google.compute(:Snapshot).new(
919
+ name: name+"-"+disk.device_name,
920
+ description: "Mu image created from #{name} (#{disk.device_name})"
939
921
  )
940
- )
941
- end
922
+ diskname = disk.source.gsub(/.*?\//, "")
923
+ MU.log "Creating snapshot of #{diskname} in #{zone}", MU::NOTICE, details: snapobj
924
+ snap = MU::Cloud::Google.compute(credentials: credentials).create_disk_snapshot(
925
+ project,
926
+ zone,
927
+ diskname,
928
+ snapobj
929
+ )
930
+ MU::Cloud::Google.compute(credentials: credentials).set_snapshot_labels(
931
+ project,
932
+ snap.name,
933
+ MU::Cloud::Google.compute(:GlobalSetLabelsRequest).new(
934
+ label_fingerprint: snap.label_fingerprint,
935
+ labels: labels.merge({
936
+ "mu-device-name" => disk.device_name,
937
+ "mu-parent-image" => name,
938
+ "mu-orig-zone" => zone
939
+ })
940
+ )
941
+ )
942
+ end
943
+ }
942
944
  }
943
- }
945
+ end
944
946
  threads.each do |t|
945
947
  t.join
946
948
  end
@@ -954,10 +956,28 @@ next if !create
954
956
  }
955
957
  image_desc[:family] = family if family
956
958
 
957
- newimage = MU::Cloud::Google.compute(credentials: @config['credentials']).insert_image(
959
+ MU.log "Creating image of #{name}", MU::NOTICE, details: image_desc
960
+ newimage = MU::Cloud::Google.compute(credentials: credentials).insert_image(
958
961
  project,
959
962
  MU::Cloud::Google.compute(:Image).new(image_desc)
960
963
  )
964
+
965
+ if make_public
966
+ MU.log "Making image #{newimage.name} public"
967
+ MU::Cloud::Google.compute(credentials: credentials).set_image_iam_policy(
968
+ project,
969
+ newimage.name,
970
+ MU::Cloud::Google.compute(:GlobalSetPolicyRequest).new(
971
+ bindings: [
972
+ MU::Cloud::Google.compute(:Binding).new(
973
+ members: ["allAuthenticatedUsers"],
974
+ role: "roles/compute.imageUser"
975
+ )
976
+ ],
977
+ )
978
+ )
979
+ end
980
+
961
981
  newimage.name
962
982
  end
963
983
 
@@ -966,7 +986,7 @@ next if !create
966
986
  # bastion hosts that may be in the path, see getSSHConfig if that's what
967
987
  # you need.
968
988
  def canonicalIP
969
- mu_name, config, deploydata = describe(cloud_id: @cloud_id)
989
+ describe(cloud_id: @cloud_id)
970
990
 
971
991
  if !cloud_desc
972
992
  raise MuError, "Couldn't retrieve cloud descriptor for server #{self}"
@@ -1017,7 +1037,7 @@ next if !create
1017
1037
  description: description,
1018
1038
  zone: @config['availability_zone'],
1019
1039
  # type: "projects/#{config['project']}/zones/#{config['availability_zone']}/diskTypes/pd-ssd",
1020
- type: "projects/#{@project_id}/zones/#{@config['availability_zone']}/diskTypes/pd-standard",
1040
+ type: "projects/#{@project_id}/zones/#{@config['availability_zone']}/diskTypes/#{type}",
1021
1041
  # Other values include pd-ssd and local-ssd
1022
1042
  name: resname
1023
1043
  )
@@ -1045,7 +1065,7 @@ next if !create
1045
1065
  )
1046
1066
 
1047
1067
  MU.log "Attaching disk #{resname} to #{@cloud_id} at #{devname}"
1048
- attachment = MU::Cloud::Google.compute(credentials: @config['credentials']).attach_disk(
1068
+ MU::Cloud::Google.compute(credentials: @config['credentials']).attach_disk(
1049
1069
  @project_id,
1050
1070
  @config['availability_zone'],
1051
1071
  @cloud_id,
@@ -1064,7 +1084,7 @@ next if !create
1064
1084
  # Reverse-map our cloud description into a runnable config hash.
1065
1085
  # We assume that any values we have in +@config+ are placeholders, and
1066
1086
  # calculate our own accordingly based on what's live in the cloud.
1067
- def toKitten(rootparent: nil, billing: nil, habitats: nil)
1087
+ def toKitten(**_args)
1068
1088
  bok = {
1069
1089
  "cloud" => "Google",
1070
1090
  "credentials" => @config['credentials'],
@@ -1189,16 +1209,19 @@ next if !create
1189
1209
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
1190
1210
  flags["project"] ||= MU::Cloud::Google.defaultProject(credentials)
1191
1211
  return if !MU::Cloud::Google::Habitat.isLive?(flags["project"], credentials)
1192
- skipsnapshots = flags["skipsnapshots"]
1193
- onlycloud = flags["onlycloud"]
1212
+
1194
1213
  # XXX make damn sure MU.deploy_id is set
1214
+ filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
1215
+ if !ignoremaster and MU.mu_public_ip
1216
+ filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
1217
+ end
1195
1218
 
1196
1219
  MU::Cloud::Google.listAZs(region).each { |az|
1197
1220
  disks = []
1198
1221
  resp = MU::Cloud::Google.compute(credentials: credentials).list_instances(
1199
1222
  flags["project"],
1200
1223
  az,
1201
- filter: "description eq #{MU.deploy_id}"
1224
+ filter: filter
1202
1225
  )
1203
1226
  if !resp.items.nil? and resp.items.size > 0
1204
1227
  resp.items.each { |instance|
@@ -1209,7 +1232,7 @@ next if !create
1209
1232
  disks << disk if !disk.auto_delete
1210
1233
  }
1211
1234
  end
1212
- deletia = MU::Cloud::Google.compute(credentials: credentials).delete_instance(
1235
+ MU::Cloud::Google.compute(credentials: credentials).delete_instance(
1213
1236
  flags["project"],
1214
1237
  az,
1215
1238
  instance.name
@@ -1247,6 +1270,10 @@ next if !create
1247
1270
  toplevel_required = []
1248
1271
  schema = {
1249
1272
  "roles" => MU::Cloud::Google::User.schema(config)[1]["roles"],
1273
+ "windows_admin_username" => {
1274
+ "type" => "string",
1275
+ "default" => "Administrator"
1276
+ },
1250
1277
  "create_image" => {
1251
1278
  "properties" => {
1252
1279
  "family" => {
@@ -1419,32 +1446,7 @@ next if !create
1419
1446
  ok = false
1420
1447
  end
1421
1448
  else
1422
- user = {
1423
- "name" => server['name'],
1424
- "cloud" => "Google",
1425
- "project" => server["project"],
1426
- "credentials" => server["credentials"],
1427
- "type" => "service"
1428
- }
1429
- if user["name"].length < 6
1430
- user["name"] += Password.pronounceable(6)
1431
- end
1432
- if server['roles']
1433
- user['roles'] = server['roles'].dup
1434
- end
1435
- configurator.insertKitten(user, "users", true)
1436
- server['dependencies'] ||= []
1437
- server['service_account'] = MU::Config::Ref.get(
1438
- type: "users",
1439
- cloud: "Google",
1440
- name: user["name"],
1441
- project: user["project"],
1442
- credentials: user["credentials"]
1443
- )
1444
- server['dependencies'] << {
1445
- "type" => "user",
1446
- "name" => user["name"]
1447
- }
1449
+ server = MU::Cloud::Google::User.genericServiceAccount(server, configurator)
1448
1450
  end
1449
1451
 
1450
1452
  subnets = nil
@@ -1509,7 +1511,7 @@ next if !create
1509
1511
  img_project = Regexp.last_match[1]
1510
1512
  img_name = Regexp.last_match[2]
1511
1513
  begin
1512
- img = MU::Cloud::Google.compute(credentials: server['credentials']).get_image(img_project, img_name)
1514
+ MU::Cloud::Google.compute(credentials: server['credentials']).get_image(img_project, img_name)
1513
1515
  snaps = MU::Cloud::Google.compute(credentials: server['credentials']).list_snapshots(
1514
1516
  img_project,
1515
1517
  filter: "name eq #{img_name}-.*"
@@ -1548,8 +1550,6 @@ next if !create
1548
1550
  ok
1549
1551
  end
1550
1552
 
1551
- private
1552
-
1553
1553
  end #class
1554
1554
  end #class
1555
1555
  end
@@ -64,10 +64,9 @@ module MU
64
64
  size = @config['basis']['launch_config']['size']
65
65
  @config['image_id'] = @config['basis']['launch_config']['image_id']
66
66
  end
67
- az = @config['availability_zone']
68
- if az.nil?
69
- az = MU::Cloud::Google.listAZs(@config['region']).sample
70
- end
67
+ # XXX this should create a non-regional instance group
68
+ # az = @config['availability_zone']
69
+ # az ||= MU::Cloud::Google.listAZs(@config['region']).sample
71
70
 
72
71
  metadata = { # :items?
73
72
  "startup-script" => @userdata
@@ -170,8 +169,7 @@ module MU
170
169
  # Locate an existing ServerPool or ServerPools and return an array containing matching Google resource descriptors for those that match.
171
170
  # @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching ServerPools
172
171
  def self.find(**args)
173
- args[:project] ||= args[:habitat]
174
- args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
172
+ args = MU::Cloud::Google.findLocationArgs(args)
175
173
 
176
174
  regions = if args[:region]
177
175
  [args[:region]]
@@ -213,7 +211,7 @@ module MU
213
211
  # Reverse-map our cloud description into a runnable config hash.
214
212
  # We assume that any values we have in +@config+ are placeholders, and
215
213
  # calculate our own accordingly based on what's live in the cloud.
216
- def toKitten(rootparent: nil, billing: nil, habitats: nil)
214
+ def toKitten(**_args)
217
215
  bok = {
218
216
  "cloud" => "Google",
219
217
  "credentials" => @credentials,
@@ -362,7 +360,7 @@ end
362
360
  # @return [Boolean]: True if validation succeeded, False otherwise
363
361
  def self.validateConfig(pool, configurator)
364
362
  ok = true
365
- start = Time.now
363
+ #start = Time.now
366
364
  pool['project'] ||= MU::Cloud::Google.defaultProject(pool['credentials'])
367
365
  if pool['service_account']
368
366
  pool['service_account']['cloud'] = "Google"
@@ -373,29 +371,7 @@ start = Time.now
373
371
  ok = false
374
372
  end
375
373
  else
376
- user = {
377
- "name" => pool['name'],
378
- "cloud" => "Google",
379
- "project" => pool["project"],
380
- "credentials" => pool["credentials"],
381
- "type" => "service"
382
- }
383
- if user["name"].length < 6
384
- user["name"] += Password.pronounceable(6)
385
- end
386
- configurator.insertKitten(user, "users", true)
387
- pool['dependencies'] ||= []
388
- pool['service_account'] = MU::Config::Ref.get(
389
- type: "users",
390
- cloud: "Google",
391
- name: pool["name"],
392
- project: pool["project"],
393
- credentials: pool["credentials"]
394
- )
395
- pool['dependencies'] << {
396
- "type" => "user",
397
- "name" => pool["name"]
398
- }
374
+ pool = MU::Cloud::Google::User.genericServiceAccount(pool, configurator)
399
375
  end
400
376
 
401
377
  pool['named_ports'] ||= []
@@ -458,6 +434,11 @@ start = Time.now
458
434
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
459
435
  flags["project"] ||= MU::Cloud::Google.defaultProject(credentials)
460
436
  return if !MU::Cloud::Google::Habitat.isLive?(flags["project"], credentials)
437
+ filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
438
+ if !ignoremaster and MU.mu_public_ip
439
+ filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
440
+ end
441
+ MU.log "Placeholder: Google ServerPool artifacts do not support labels, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: filter
461
442
 
462
443
  if !flags["global"]
463
444
  ["region_autoscaler", "region_instance_group_manager"].each { |type|