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.
- checksums.yaml +4 -4
- data/Dockerfile +10 -2
- data/bin/mu-adopt +5 -1
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-run-tests +112 -27
- data/cloud-mu.gemspec +20 -20
- data/cookbooks/mu-tools/libraries/helper.rb +2 -1
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +5 -15
- data/modules/mu.rb +10 -14
- data/modules/mu/adoption.rb +20 -14
- data/modules/mu/cleanup.rb +13 -9
- data/modules/mu/cloud.rb +26 -26
- data/modules/mu/clouds/aws.rb +100 -59
- data/modules/mu/clouds/aws/alarm.rb +4 -2
- data/modules/mu/clouds/aws/bucket.rb +25 -21
- data/modules/mu/clouds/aws/cache_cluster.rb +25 -23
- data/modules/mu/clouds/aws/collection.rb +21 -20
- data/modules/mu/clouds/aws/container_cluster.rb +47 -26
- data/modules/mu/clouds/aws/database.rb +57 -68
- data/modules/mu/clouds/aws/dnszone.rb +14 -14
- data/modules/mu/clouds/aws/endpoint.rb +20 -16
- data/modules/mu/clouds/aws/firewall_rule.rb +19 -16
- data/modules/mu/clouds/aws/folder.rb +7 -7
- data/modules/mu/clouds/aws/function.rb +15 -12
- data/modules/mu/clouds/aws/group.rb +14 -10
- data/modules/mu/clouds/aws/habitat.rb +16 -13
- data/modules/mu/clouds/aws/loadbalancer.rb +16 -15
- data/modules/mu/clouds/aws/log.rb +13 -10
- data/modules/mu/clouds/aws/msg_queue.rb +15 -8
- data/modules/mu/clouds/aws/nosqldb.rb +18 -11
- data/modules/mu/clouds/aws/notifier.rb +11 -6
- data/modules/mu/clouds/aws/role.rb +87 -70
- data/modules/mu/clouds/aws/search_domain.rb +30 -19
- data/modules/mu/clouds/aws/server.rb +102 -72
- data/modules/mu/clouds/aws/server_pool.rb +47 -28
- data/modules/mu/clouds/aws/storage_pool.rb +5 -6
- data/modules/mu/clouds/aws/user.rb +13 -10
- data/modules/mu/clouds/aws/vpc.rb +135 -121
- data/modules/mu/clouds/azure.rb +16 -9
- data/modules/mu/clouds/azure/container_cluster.rb +2 -3
- data/modules/mu/clouds/azure/firewall_rule.rb +10 -10
- data/modules/mu/clouds/azure/habitat.rb +8 -6
- data/modules/mu/clouds/azure/loadbalancer.rb +5 -5
- data/modules/mu/clouds/azure/role.rb +8 -10
- data/modules/mu/clouds/azure/server.rb +65 -25
- data/modules/mu/clouds/azure/user.rb +5 -7
- data/modules/mu/clouds/azure/vpc.rb +12 -15
- data/modules/mu/clouds/cloudformation.rb +8 -7
- data/modules/mu/clouds/cloudformation/vpc.rb +2 -4
- data/modules/mu/clouds/google.rb +39 -24
- data/modules/mu/clouds/google/bucket.rb +9 -11
- data/modules/mu/clouds/google/container_cluster.rb +27 -42
- data/modules/mu/clouds/google/database.rb +6 -9
- data/modules/mu/clouds/google/firewall_rule.rb +11 -10
- data/modules/mu/clouds/google/folder.rb +16 -9
- data/modules/mu/clouds/google/function.rb +127 -161
- data/modules/mu/clouds/google/group.rb +21 -18
- data/modules/mu/clouds/google/habitat.rb +18 -15
- data/modules/mu/clouds/google/loadbalancer.rb +14 -16
- data/modules/mu/clouds/google/role.rb +48 -31
- data/modules/mu/clouds/google/server.rb +105 -105
- data/modules/mu/clouds/google/server_pool.rb +12 -31
- data/modules/mu/clouds/google/user.rb +67 -13
- data/modules/mu/clouds/google/vpc.rb +58 -65
- data/modules/mu/config.rb +89 -1738
- data/modules/mu/config/bucket.rb +3 -3
- data/modules/mu/config/collection.rb +3 -3
- data/modules/mu/config/container_cluster.rb +2 -2
- data/modules/mu/config/dnszone.rb +5 -5
- data/modules/mu/config/doc_helpers.rb +517 -0
- data/modules/mu/config/endpoint.rb +3 -3
- data/modules/mu/config/firewall_rule.rb +118 -3
- data/modules/mu/config/folder.rb +3 -3
- data/modules/mu/config/function.rb +2 -2
- data/modules/mu/config/group.rb +3 -3
- data/modules/mu/config/habitat.rb +3 -3
- data/modules/mu/config/loadbalancer.rb +3 -3
- data/modules/mu/config/log.rb +3 -3
- data/modules/mu/config/msg_queue.rb +3 -3
- data/modules/mu/config/nosqldb.rb +3 -3
- data/modules/mu/config/notifier.rb +2 -2
- data/modules/mu/config/ref.rb +333 -0
- data/modules/mu/config/role.rb +3 -3
- data/modules/mu/config/schema_helpers.rb +508 -0
- data/modules/mu/config/search_domain.rb +3 -3
- data/modules/mu/config/server.rb +86 -58
- data/modules/mu/config/server_pool.rb +2 -2
- data/modules/mu/config/tail.rb +189 -0
- data/modules/mu/config/user.rb +3 -3
- data/modules/mu/config/vpc.rb +44 -4
- data/modules/mu/defaults/Google.yaml +2 -2
- data/modules/mu/deploy.rb +13 -10
- data/modules/mu/groomer.rb +1 -1
- data/modules/mu/groomers/ansible.rb +69 -24
- data/modules/mu/groomers/chef.rb +52 -44
- data/modules/mu/logger.rb +17 -14
- data/modules/mu/master.rb +317 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -2
- data/modules/mu/mommacat.rb +85 -1766
- data/modules/mu/mommacat/daemon.rb +394 -0
- data/modules/mu/mommacat/naming.rb +366 -0
- data/modules/mu/mommacat/storage.rb +689 -0
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/{win2k12.yaml → needwork/win2k12.yaml} +0 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- 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
|
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
|
-
|
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] =
|
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
|
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
|
-
#
|
466
|
-
def reboot(
|
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
|
-
|
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,
|
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
|
-
|
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
|
-
|
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::
|
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::
|
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::
|
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
|
-
|
613
|
-
if !nat_ssh_host and !MU::Cloud::Google::VPC.haveRouteToInstance?(cloud_desc,
|
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
|
645
|
-
|
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,
|
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: @
|
864
|
+
tags: @tags,
|
863
865
|
zone: @config['availability_zone'],
|
864
|
-
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
|
-
|
902
|
-
|
903
|
-
|
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
|
-
|
911
|
-
|
912
|
-
Thread.
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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(
|
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
|
-
|
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:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
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
|
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(
|
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
|
-
|
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|
|