cloud-mu 2.0.0.pre.alpha9 → 2.0.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Berksfile.lock +1 -1
- data/README.md +2 -0
- data/bin/mu-configure +2 -58
- data/bin/mu-gen-docs +29 -4
- data/bin/mu-load-config.rb +0 -1
- data/bin/mu-user-manage +4 -0
- data/cloud-mu.gemspec +2 -2
- data/cookbooks/mu-master/recipes/default.rb +3 -4
- data/cookbooks/mu-master/recipes/init.rb +3 -3
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +15 -15
- data/cookbooks/mu-tools/libraries/helper.rb +1 -1
- data/cookbooks/mu-tools/recipes/eks.rb +3 -3
- data/cookbooks/mu-tools/recipes/set_local_fw.rb +1 -1
- data/cookbooks/mu-utility/recipes/remi.rb +1 -1
- data/cookbooks/nagios/libraries/base.rb +4 -4
- data/cookbooks/nagios/libraries/contact.rb +1 -1
- data/cookbooks/nagios/libraries/contactgroup.rb +1 -1
- data/cookbooks/nagios/libraries/host.rb +2 -2
- data/cookbooks/nagios/libraries/hostdependency.rb +3 -3
- data/cookbooks/nagios/libraries/hostescalation.rb +3 -3
- data/cookbooks/nagios/libraries/hostgroup.rb +2 -2
- data/cookbooks/nagios/libraries/nagios.rb +5 -5
- data/cookbooks/nagios/libraries/service.rb +3 -3
- data/cookbooks/nagios/libraries/servicedependency.rb +2 -2
- data/cookbooks/nagios/libraries/serviceescalation.rb +2 -2
- data/cookbooks/nagios/libraries/servicegroup.rb +2 -2
- data/cookbooks/nagios/libraries/timeperiod.rb +1 -1
- data/install/installer +1 -1
- data/modules/mu/cleanup.rb +1 -1
- data/modules/mu/cloud.rb +43 -1
- data/modules/mu/clouds/aws.rb +55 -35
- data/modules/mu/clouds/aws/bucket.rb +287 -0
- data/modules/mu/clouds/aws/database.rb +65 -11
- data/modules/mu/clouds/aws/endpoint.rb +592 -0
- data/modules/mu/clouds/aws/firewall_rule.rb +4 -0
- data/modules/mu/clouds/aws/function.rb +138 -93
- data/modules/mu/clouds/aws/nosqldb.rb +387 -0
- data/modules/mu/clouds/aws/role.rb +1 -1
- data/modules/mu/clouds/aws/server.rb +5 -5
- data/modules/mu/clouds/aws/server_pool.rb +60 -3
- data/modules/mu/clouds/azure.rb +0 -1
- data/modules/mu/clouds/google.rb +34 -12
- data/modules/mu/clouds/google/bucket.rb +179 -0
- data/modules/mu/config.rb +1 -1
- data/modules/mu/config/bucket.rb +69 -0
- data/modules/mu/config/bucket.yml +10 -0
- data/modules/mu/config/database.rb +1 -1
- data/modules/mu/config/endpoint.rb +71 -0
- data/modules/mu/config/function.rb +6 -0
- data/modules/mu/config/nosqldb.rb +49 -0
- data/modules/mu/config/nosqldb.yml +44 -0
- data/modules/mu/config/notifier.yml +2 -2
- data/modules/mu/config/vpc.rb +0 -1
- data/modules/mu/defaults/amazon_images.yaml +32 -30
- data/modules/mu/groomers/chef.rb +1 -1
- data/modules/mu/kittens.rb +2430 -1511
- data/modules/mu/master/ldap.rb +1 -1
- data/modules/tests/super_complex_bok.yml +7 -0
- data/modules/tests/super_simple_bok.yml +7 -0
- metadata +11 -2
@@ -93,7 +93,7 @@ module MU
|
|
93
93
|
end
|
94
94
|
|
95
95
|
if @config['import']
|
96
|
-
MU.log "Attaching canned #{@config['import'].size > 1 ? "policies" : "policy"} #{@config['import'].join(", ")} to role #{@mu_name}", MU::NOTICE
|
96
|
+
MU.log "Attaching canned #{@config['import'].size > 1 ? "policies" : "policy"} #{@config['import'].join(", ")} to role #{@mu_name}", MU::NOTICE
|
97
97
|
configured_policies.concat(@config['import'].map { |p| p.gsub(/.*?\/([^:\/]+)$/, '\1') })
|
98
98
|
end
|
99
99
|
|
@@ -1356,7 +1356,7 @@ module MU
|
|
1356
1356
|
MU.log "Creating AMI from #{name}", details: ami_descriptor
|
1357
1357
|
resp = nil
|
1358
1358
|
begin
|
1359
|
-
resp = MU::Cloud::AWS.ec2(region: region).create_image(ami_descriptor)
|
1359
|
+
resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).create_image(ami_descriptor)
|
1360
1360
|
rescue Aws::EC2::Errors::InvalidAMINameDuplicate => e
|
1361
1361
|
MU.log "AMI #{name} already exists, skipping", MU::WARN
|
1362
1362
|
return nil
|
@@ -1367,7 +1367,7 @@ module MU
|
|
1367
1367
|
MU.log "AMI of #{name} in region #{region}: #{ami}"
|
1368
1368
|
if make_public
|
1369
1369
|
MU::Cloud::AWS::Server.waitForAMI(ami, region: region, credentials: credentials)
|
1370
|
-
MU::Cloud::AWS.ec2(region: region).modify_image_attribute(
|
1370
|
+
MU::Cloud::AWS.ec2(region: region, credentials: credentials).modify_image_attribute(
|
1371
1371
|
image_id: ami,
|
1372
1372
|
launch_permission: {add: [{group: "all"}]},
|
1373
1373
|
attribute: "launchPermission"
|
@@ -1381,7 +1381,7 @@ module MU
|
|
1381
1381
|
next if r == region
|
1382
1382
|
copythreads << Thread.new {
|
1383
1383
|
MU.dupGlobals(parent_thread_id)
|
1384
|
-
copy = MU::Cloud::AWS.ec2(region: r).copy_image(
|
1384
|
+
copy = MU::Cloud::AWS.ec2(region: r, credentials: credentials).copy_image(
|
1385
1385
|
source_region: region,
|
1386
1386
|
source_image_id: ami,
|
1387
1387
|
name: name,
|
@@ -1389,7 +1389,7 @@ module MU
|
|
1389
1389
|
)
|
1390
1390
|
MU.log "Initiated copy of #{ami} from #{region} to #{r}: #{copy.image_id}"
|
1391
1391
|
|
1392
|
-
MU::MommaCat.createStandardTags(copy.image_id, region: r)
|
1392
|
+
MU::MommaCat.createStandardTags(copy.image_id, region: r, credentials: credentials)
|
1393
1393
|
MU::MommaCat.createTag(copy.image_id, "Name", name, region: r, credentials: credentials)
|
1394
1394
|
if !tags.nil?
|
1395
1395
|
tags.each { |tag|
|
@@ -1398,7 +1398,7 @@ module MU
|
|
1398
1398
|
end
|
1399
1399
|
MU::Cloud::AWS::Server.waitForAMI(copy.image_id, region: r, credentials: credentials)
|
1400
1400
|
if make_public
|
1401
|
-
MU::Cloud::AWS.ec2(region: r).modify_image_attribute(
|
1401
|
+
MU::Cloud::AWS.ec2(region: r, credentials: credentials).modify_image_attribute(
|
1402
1402
|
image_id: copy.image_id,
|
1403
1403
|
launch_permission: {add: [{group: "all"}]},
|
1404
1404
|
attribute: "launchPermission"
|
@@ -212,6 +212,29 @@ module MU
|
|
212
212
|
|
213
213
|
# Called automatically by {MU::Deploy#createResources}
|
214
214
|
def groom
|
215
|
+
if @config['notifications'] and @config['notifications']['topic']
|
216
|
+
# XXX expand to a full reference block for a Notification resource
|
217
|
+
arn = if @config['notifications']['topic'].match(/^arn:/)
|
218
|
+
@config['notifications']['topic']
|
219
|
+
else
|
220
|
+
"arn:#{MU::Cloud::AWS.isGovCloud?(@config['region']) ? "aws-us-gov" : "aws"}:sns:#{@config['region']}:#{MU::Cloud::AWS.credToAcct(@config['credentials'])}:#{@config['notifications']['topic']}"
|
221
|
+
end
|
222
|
+
eventmap = {
|
223
|
+
"launch" => "autoscaling:EC2_INSTANCE_LAUNCH",
|
224
|
+
"failed_launch" => "autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
|
225
|
+
"terminate" => "autoscaling:EC2_INSTANCE_TERMINATE",
|
226
|
+
"failed_terminate" => "autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
|
227
|
+
}
|
228
|
+
MU.log "Sending simple notifications (#{@config['notifications']['events'].join(", ")}) to #{arn}"
|
229
|
+
MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_notification_configuration(
|
230
|
+
auto_scaling_group_name: @mu_name,
|
231
|
+
topic_arn: arn,
|
232
|
+
notification_types: @config['notifications']['events'].map { |e|
|
233
|
+
eventmap[e]
|
234
|
+
}
|
235
|
+
)
|
236
|
+
end
|
237
|
+
|
215
238
|
if @config['schedule']
|
216
239
|
ext_actions = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_scheduled_actions(
|
217
240
|
auto_scaling_group_name: @mu_name
|
@@ -357,6 +380,7 @@ module MU
|
|
357
380
|
newhash
|
358
381
|
end
|
359
382
|
policy_params[:target_tracking_configuration] = strToSym(policy['target_tracking_configuration'])
|
383
|
+
policy_params[:target_tracking_configuration].delete(:preferred_target_group)
|
360
384
|
if policy_params[:target_tracking_configuration][:predefined_metric_specification] and
|
361
385
|
policy_params[:target_tracking_configuration][:predefined_metric_specification][:predefined_metric_type] == "ALBRequestCountPerTarget"
|
362
386
|
lb_path = nil
|
@@ -364,10 +388,18 @@ module MU
|
|
364
388
|
if @deploy.deployment["loadbalancers"].size > 1
|
365
389
|
MU.log "Multiple load balancers attached to Autoscale group #{@mu_name}, guessing wildly which one to use for TargetTrackingScaling policy", MU::WARN
|
366
390
|
end
|
367
|
-
if lb["targetgroups"].size > 1
|
368
|
-
|
391
|
+
lb_path = if lb["targetgroups"].size > 1
|
392
|
+
if policy['target_tracking_configuration']["preferred_target_group"] and
|
393
|
+
lb["targetgroups"][policy['target_tracking_configuration']["preferred_target_group"]]
|
394
|
+
lb["arn"].split(/:/)[5].sub(/^loadbalancer\//, "")+"/"+lb["targetgroups"][policy['target_tracking_configuration']["preferred_target_group"]].split(/:/)[5]
|
395
|
+
else
|
396
|
+
if policy['target_tracking_configuration']["preferred_target_group"]
|
397
|
+
MU.log "preferred_target_group was set to '#{policy["preferred_target_group"]}' but I don't see a target group by that name", MU::WARN
|
398
|
+
end
|
399
|
+
MU.log "Multiple target groups attached to Autoscale group #{@mu_name}, guessing wildly which one to use for TargetTrackingScaling policy", MU::WARN, details: lb["targetgroups"].keys
|
400
|
+
lb["arn"].split(/:/)[5].sub(/^loadbalancer\//, "")+"/"+lb["targetgroups"].values.first.split(/:/)[5]
|
401
|
+
end
|
369
402
|
end
|
370
|
-
lb_path = lb["arn"].split(/:/)[5].sub(/^loadbalancer\//, "")+"/"+lb["targetgroups"].values.first.split(/:/)[5]
|
371
403
|
|
372
404
|
policy_params[:target_tracking_configuration][:predefined_metric_specification][:resource_label] = lb_path
|
373
405
|
end
|
@@ -457,6 +489,26 @@ module MU
|
|
457
489
|
toplevel_required = []
|
458
490
|
|
459
491
|
schema = {
|
492
|
+
"notifications" => {
|
493
|
+
"type" => "object",
|
494
|
+
"description" => "Send notifications to an SNS topic for basic AutoScaling events",
|
495
|
+
"properties" => {
|
496
|
+
"topic" => {
|
497
|
+
"type" => "string",
|
498
|
+
"description" => "The short name or ARN of an SNS topic which should receive notifications for basic Autoscaling events"
|
499
|
+
},
|
500
|
+
"events" => {
|
501
|
+
"type" => "array",
|
502
|
+
"description" => "The AutoScaling events which should generate a notification",
|
503
|
+
"items" => {
|
504
|
+
"type" => "string",
|
505
|
+
"description" => "The AutoScaling events which should generate a notification",
|
506
|
+
"enum" => ["launch", "failed_launch", "terminate", "failed_terminate"]
|
507
|
+
},
|
508
|
+
"default" => ["launch", "failed_launch", "terminate", "failed_terminate"]
|
509
|
+
}
|
510
|
+
}
|
511
|
+
},
|
460
512
|
"generate_iam_role" => {
|
461
513
|
"type" => "boolean",
|
462
514
|
"default" => true,
|
@@ -625,6 +677,10 @@ module MU
|
|
625
677
|
"type" => "float",
|
626
678
|
"description" => "The target value for the metric."
|
627
679
|
},
|
680
|
+
"preferred_target_group" => {
|
681
|
+
"type" => "string",
|
682
|
+
"description" => "If our load balancer has multiple target groups, prefer the one with this name instead of choosing one arbitrarily"
|
683
|
+
},
|
628
684
|
"disable_scale_in" => {
|
629
685
|
"type" => "boolean",
|
630
686
|
"description" => "If set to true, new instances created by this policy will not be subject to termination by scaling in.",
|
@@ -665,6 +721,7 @@ module MU
|
|
665
721
|
"type" => "object",
|
666
722
|
"additionalProperties" => false,
|
667
723
|
"required" => ["name", "value"],
|
724
|
+
"description" => "What resource to monitor with the alarm we are implicitly declaring",
|
668
725
|
"properties" => {
|
669
726
|
"name" => {
|
670
727
|
"type" => "string",
|
data/modules/mu/clouds/azure.rb
CHANGED
@@ -110,7 +110,6 @@ module MU
|
|
110
110
|
|
111
111
|
|
112
112
|
# Fetch an Azure instance metadata parameter (example: public-ipv4).
|
113
|
-
# @param param [String]: The parameter name to fetch
|
114
113
|
# @return [String, nil]
|
115
114
|
def self.get_metadata()
|
116
115
|
base_url = "http://169.254.169.254/metadata/instance"
|
data/modules/mu/clouds/google.rb
CHANGED
@@ -71,12 +71,20 @@ module MU
|
|
71
71
|
$MU_CFG['google'].keys
|
72
72
|
end
|
73
73
|
|
74
|
+
# Resolve the administrative Cloud Storage bucket for a given credential
|
75
|
+
# set, or return a default.
|
76
|
+
# @param credentials [String]
|
77
|
+
# @return [String]
|
74
78
|
def self.adminBucketName(credentials = nil)
|
75
79
|
#XXX find a default if this particular account doesn't have a log_bucket_name configured
|
76
80
|
cfg = credConfig(credentials)
|
77
81
|
cfg['log_bucket_name']
|
78
82
|
end
|
79
83
|
|
84
|
+
# Resolve the administrative Cloud Storage bucket for a given credential
|
85
|
+
# set, or return a default.
|
86
|
+
# @param credentials [String]
|
87
|
+
# @return [String]
|
80
88
|
def self.adminBucketUrl(credentials = nil)
|
81
89
|
"gs://"+adminBucketName(credentials)+"/"
|
82
90
|
end
|
@@ -121,7 +129,7 @@ module MU
|
|
121
129
|
return name_only ? name : @@acct_to_profile_map[name.to_s]
|
122
130
|
end
|
123
131
|
# XXX whatever process might lead us to populate @@acct_to_profile_map with some mappings, like projectname -> account profile, goes here
|
124
|
-
|
132
|
+
return nil
|
125
133
|
end
|
126
134
|
end
|
127
135
|
|
@@ -532,7 +540,7 @@ module MU
|
|
532
540
|
require 'google/apis/compute_beta'
|
533
541
|
|
534
542
|
if subclass.nil?
|
535
|
-
@@compute_api[credentials] ||= MU::Cloud::Google::
|
543
|
+
@@compute_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "ComputeBeta::ComputeService", scopes: ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute.readonly'], credentials: credentials)
|
536
544
|
return @@compute_api[credentials]
|
537
545
|
elsif subclass.is_a?(Symbol)
|
538
546
|
return Object.const_get("::Google").const_get("Apis").const_get("ComputeBeta").const_get(subclass)
|
@@ -545,7 +553,7 @@ module MU
|
|
545
553
|
require 'google/apis/storage_v1'
|
546
554
|
|
547
555
|
if subclass.nil?
|
548
|
-
@@storage_api[credentials] ||= MU::Cloud::Google::
|
556
|
+
@@storage_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "StorageV1::StorageService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
549
557
|
return @@storage_api[credentials]
|
550
558
|
elsif subclass.is_a?(Symbol)
|
551
559
|
return Object.const_get("::Google").const_get("Apis").const_get("StorageV1").const_get(subclass)
|
@@ -558,7 +566,7 @@ module MU
|
|
558
566
|
require 'google/apis/iam_v1'
|
559
567
|
|
560
568
|
if subclass.nil?
|
561
|
-
@@iam_api[credentials] ||= MU::Cloud::Google::
|
569
|
+
@@iam_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "IamV1::IamService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
562
570
|
return @@iam_api[credentials]
|
563
571
|
elsif subclass.is_a?(Symbol)
|
564
572
|
return Object.const_get("::Google").const_get("Apis").const_get("IamV1").const_get(subclass)
|
@@ -572,7 +580,7 @@ module MU
|
|
572
580
|
|
573
581
|
if subclass.nil?
|
574
582
|
begin
|
575
|
-
@@admin_directory_api[credentials] ||= MU::Cloud::Google::
|
583
|
+
@@admin_directory_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "AdminDirectoryV1::DirectoryService", scopes: ['https://www.googleapis.com/auth/admin.directory.group.member.readonly', 'https://www.googleapis.com/auth/admin.directory.group.readonly', 'https://www.googleapis.com/auth/admin.directory.user.readonly', 'https://www.googleapis.com/auth/admin.directory.domain.readonly', 'https://www.googleapis.com/auth/admin.directory.orgunit.readonly', 'https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly', 'https://www.googleapis.com/auth/admin.directory.customer.readonly'], masquerade: MU::Cloud::Google.credConfig(credentials)['masquerade_as'], credentials: credentials)
|
576
584
|
rescue Signet::AuthorizationError => e
|
577
585
|
MU.log "Cannot masquerade as #{MU::Cloud::Google.credConfig(credentials)['masquerade_as']}", MU::ERROR, details: "You can only use masquerade_as with GSuite. For more information on delegating GSuite authority to a service account, see:\nhttps://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority"
|
578
586
|
raise e
|
@@ -589,7 +597,7 @@ module MU
|
|
589
597
|
require 'google/apis/cloudresourcemanager_v1'
|
590
598
|
|
591
599
|
if subclass.nil?
|
592
|
-
@@resource_api[credentials] ||= MU::Cloud::Google::
|
600
|
+
@@resource_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "CloudresourcemanagerV1::CloudResourceManagerService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
593
601
|
return @@resource_api[credentials]
|
594
602
|
elsif subclass.is_a?(Symbol)
|
595
603
|
return Object.const_get("::Google").const_get("Apis").const_get("CloudresourcemanagerV1").const_get(subclass)
|
@@ -602,7 +610,7 @@ module MU
|
|
602
610
|
require 'google/apis/cloudresourcemanager_v2beta1'
|
603
611
|
|
604
612
|
if subclass.nil?
|
605
|
-
@@resource2_api[credentials] ||= MU::Cloud::Google::
|
613
|
+
@@resource2_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "CloudresourcemanagerV2beta1::CloudResourceManagerService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
606
614
|
return @@resource2_api[credentials]
|
607
615
|
elsif subclass.is_a?(Symbol)
|
608
616
|
return Object.const_get("::Google").const_get("Apis").const_get("CloudresourcemanagerV2beta1").const_get(subclass)
|
@@ -615,7 +623,7 @@ module MU
|
|
615
623
|
require 'google/apis/container_v1'
|
616
624
|
|
617
625
|
if subclass.nil?
|
618
|
-
@@container_api[credentials] ||= MU::Cloud::Google::
|
626
|
+
@@container_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "ContainerV1::ContainerService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
619
627
|
return @@container_api[credentials]
|
620
628
|
elsif subclass.is_a?(Symbol)
|
621
629
|
return Object.const_get("::Google").const_get("Apis").const_get("ContainerV1").const_get(subclass)
|
@@ -628,7 +636,7 @@ module MU
|
|
628
636
|
require 'google/apis/servicemanagement_v1'
|
629
637
|
|
630
638
|
if subclass.nil?
|
631
|
-
@@service_api[credentials] ||= MU::Cloud::Google::
|
639
|
+
@@service_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "ServicemanagementV1::ServiceManagementService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
632
640
|
return @@service_api[credentials]
|
633
641
|
elsif subclass.is_a?(Symbol)
|
634
642
|
return Object.const_get("::Google").const_get("Apis").const_get("ServicemanagementV1").const_get(subclass)
|
@@ -641,20 +649,33 @@ module MU
|
|
641
649
|
require 'google/apis/sqladmin_v1beta4'
|
642
650
|
|
643
651
|
if subclass.nil?
|
644
|
-
@@sql_api[credentials] ||= MU::Cloud::Google::
|
652
|
+
@@sql_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "SqladminV1beta4::SQLAdminService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
645
653
|
return @@sql_api[credentials]
|
646
654
|
elsif subclass.is_a?(Symbol)
|
647
655
|
return Object.const_get("::Google").const_get("Apis").const_get("SqladminV1beta4").const_get(subclass)
|
648
656
|
end
|
649
657
|
end
|
650
658
|
|
659
|
+
# Google's Firestore (NoSQL) Service API
|
660
|
+
# @param subclass [<Google::Apis::FirestoreV1>]: If specified, will return the class ::Google::Apis::FirestoreV1::subclass instead of an API client instance
|
661
|
+
def self.firestore(subclass = nil, credentials: nil)
|
662
|
+
require 'google/apis/firestore_v1'
|
663
|
+
|
664
|
+
if subclass.nil?
|
665
|
+
@@firestore_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "FirestoreV1::FirestoreService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
666
|
+
return @@firestore_api[credentials]
|
667
|
+
elsif subclass.is_a?(Symbol)
|
668
|
+
return Object.const_get("::Google").const_get("Apis").const_get("FirestoreV1").const_get(subclass)
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
651
672
|
# Google's StackDriver Logging Service API
|
652
673
|
# @param subclass [<Google::Apis::LoggingV2>]: If specified, will return the class ::Google::Apis::LoggingV2::subclass instead of an API client instance
|
653
674
|
def self.logging(subclass = nil, credentials: nil)
|
654
675
|
require 'google/apis/logging_v2'
|
655
676
|
|
656
677
|
if subclass.nil?
|
657
|
-
@@logging_api[credentials] ||= MU::Cloud::Google::
|
678
|
+
@@logging_api[credentials] ||= MU::Cloud::Google::GoogleEndpoint.new(api: "LoggingV2::LoggingService", scopes: ['https://www.googleapis.com/auth/cloud-platform'], credentials: credentials)
|
658
679
|
return @@logging_api[credentials]
|
659
680
|
elsif subclass.is_a?(Symbol)
|
660
681
|
return Object.const_get("::Google").const_get("Apis").const_get("LoggingV2").const_get(subclass)
|
@@ -667,7 +688,7 @@ module MU
|
|
667
688
|
# Wrapper class for Google APIs, so that we can catch some common
|
668
689
|
# transient endpoint errors without having to spray rescues all over the
|
669
690
|
# codebase.
|
670
|
-
class
|
691
|
+
class GoogleEndpoint
|
671
692
|
@api = nil
|
672
693
|
@credentials = nil
|
673
694
|
attr_reader :issuer
|
@@ -945,6 +966,7 @@ module MU
|
|
945
966
|
@@resource_api = {}
|
946
967
|
@@resource2_api = {}
|
947
968
|
@@service_api = {}
|
969
|
+
@@firestore_api = {}
|
948
970
|
@@admin_directory_api = {}
|
949
971
|
end
|
950
972
|
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# Copyright:: Copyright (c) 2019 eGlobalTech, Inc., all rights reserved
|
2
|
+
#
|
3
|
+
# Licensed under the BSD-3 license (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License in the root of the project or at
|
6
|
+
#
|
7
|
+
# http://egt-labs.com/mu/LICENSE.html
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module MU
|
16
|
+
class Cloud
|
17
|
+
class Google
|
18
|
+
# Support for Google Cloud Storage
|
19
|
+
class Bucket < MU::Cloud::Bucket
|
20
|
+
@deploy = nil
|
21
|
+
@config = nil
|
22
|
+
|
23
|
+
attr_reader :mu_name
|
24
|
+
attr_reader :config
|
25
|
+
attr_reader :cloud_id
|
26
|
+
|
27
|
+
# @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
|
28
|
+
# @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::logs}
|
29
|
+
def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
|
30
|
+
@deploy = mommacat
|
31
|
+
@config = MU::Config.manxify(kitten_cfg)
|
32
|
+
@cloud_id ||= cloud_id
|
33
|
+
@mu_name ||= @deploy.getResourceName(@config["name"])
|
34
|
+
end
|
35
|
+
|
36
|
+
# Called automatically by {MU::Deploy#createResources}
|
37
|
+
def create
|
38
|
+
MU::Cloud::Google.storage(credentials: credentials).insert_bucket(@config['project'], bucket_descriptor)
|
39
|
+
@cloud_id = @mu_name.downcase
|
40
|
+
end
|
41
|
+
|
42
|
+
# Called automatically by {MU::Deploy#createResources}
|
43
|
+
def groom
|
44
|
+
current = cloud_desc
|
45
|
+
changed = false
|
46
|
+
|
47
|
+
if !current.versioning.enabled and @config['versioning']
|
48
|
+
MU.log "Enabling versioning on Cloud Storage bucket #{@cloud_id}", MU::NOTICE
|
49
|
+
changed = true
|
50
|
+
elsif current.versioning.enabled and !@config['versioning']
|
51
|
+
MU.log "Disabling versioning on Cloud Storage bucket #{@cloud_id}", MU::NOTICE
|
52
|
+
changed = true
|
53
|
+
end
|
54
|
+
|
55
|
+
if current.website.nil? and @config['web']
|
56
|
+
MU.log "Enabling website service on Cloud Storage bucket #{@cloud_id}", MU::NOTICE
|
57
|
+
changed = true
|
58
|
+
elsif !current.website.nil? and !@config['web']
|
59
|
+
MU.log "Disabling website service on Cloud Storage bucket #{@cloud_id}", MU::NOTICE
|
60
|
+
changed = true
|
61
|
+
end
|
62
|
+
|
63
|
+
if changed
|
64
|
+
MU::Cloud::Google.storage(credentials: credentials).patch_bucket(@cloud_id, bucket_descriptor)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Does this resource type exist as a global (cloud-wide) artifact, or
|
69
|
+
# is it localized to a region/zone?
|
70
|
+
# @return [Boolean]
|
71
|
+
def self.isGlobal?
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
# Remove all buckets associated with the currently loaded deployment.
|
76
|
+
# @param noop [Boolean]: If true, will only print what would be done
|
77
|
+
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
78
|
+
# @param region [String]: The cloud provider region
|
79
|
+
# @return [void]
|
80
|
+
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
81
|
+
flags["project"] ||= MU::Cloud::Google.defaultProject(credentials)
|
82
|
+
|
83
|
+
resp = MU::Cloud::Google.storage(credentials: credentials).list_buckets(flags['project'])
|
84
|
+
if resp and resp.items
|
85
|
+
resp.items.each { |bucket|
|
86
|
+
if bucket.labels and bucket.labels["mu-id"] == MU.deploy_id.downcase
|
87
|
+
MU.log "Deleting Cloud Storage bucket #{bucket.name}"
|
88
|
+
if !noop
|
89
|
+
MU::Cloud::Google.storage(credentials: credentials).delete_bucket(bucket.name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Return the metadata for this user cofiguration
|
97
|
+
# @return [Hash]
|
98
|
+
def notify
|
99
|
+
MU.structToHash(cloud_desc)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Locate an existing bucket.
|
103
|
+
# @param cloud_id [String]: The cloud provider's identifier for this resource.
|
104
|
+
# @param region [String]: The cloud provider region.
|
105
|
+
# @param flags [Hash]: Optional flags
|
106
|
+
# @return [OpenStruct]: The cloud provider's complete descriptions of matching bucket.
|
107
|
+
def self.find(cloud_id: nil, region: MU.curRegion, credentials: nil, flags: {})
|
108
|
+
found = {}
|
109
|
+
if cloud_id
|
110
|
+
found[cloud_id] = MU::Cloud::Google.storage(credentials: credentials).get_bucket(cloud_id)
|
111
|
+
end
|
112
|
+
found
|
113
|
+
end
|
114
|
+
|
115
|
+
# Cloud-specific configuration properties.
|
116
|
+
# @param config [MU::Config]: The calling MU::Config object
|
117
|
+
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
118
|
+
def self.schema(config)
|
119
|
+
toplevel_required = []
|
120
|
+
schema = {
|
121
|
+
"storage_class" => {
|
122
|
+
"type" => "string",
|
123
|
+
"enum" => ["MULTI_REGIONAL", "REGIONAL", "STANDARD", "NEARLINE", "COLDLINE", "DURABLE_REDUCED_AVAILABILITY"],
|
124
|
+
"default" => "STANDARD"
|
125
|
+
}
|
126
|
+
}
|
127
|
+
[toplevel_required, schema]
|
128
|
+
end
|
129
|
+
|
130
|
+
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::bucket}, bare and unvalidated.
|
131
|
+
|
132
|
+
# @param bucket [Hash]: The resource to process and validate
|
133
|
+
# @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
134
|
+
# @return [Boolean]: True if validation succeeded, False otherwise
|
135
|
+
def self.validateConfig(bucket, configurator)
|
136
|
+
ok = true
|
137
|
+
|
138
|
+
ok
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# create and return the Google::Apis::StorageV1::Bucket object used by
|
144
|
+
# both +insert_bucket+ and +patch_bucket+
|
145
|
+
def bucket_descriptor
|
146
|
+
labels = {}
|
147
|
+
MU::MommaCat.listStandardTags.each_pair { |name, value|
|
148
|
+
if !value.nil?
|
149
|
+
labels[name.downcase] = value.downcase.gsub(/[^a-z0-9\-\_]/i, "_")
|
150
|
+
end
|
151
|
+
}
|
152
|
+
labels["name"] = @mu_name.downcase
|
153
|
+
|
154
|
+
params = {
|
155
|
+
:name => @mu_name.downcase,
|
156
|
+
:labels => labels,
|
157
|
+
:storage_class => @config['storage_class'],
|
158
|
+
}
|
159
|
+
|
160
|
+
if @config['web']
|
161
|
+
params[:website] = MU::Cloud::Google.storage(:Bucket)::Website.new(
|
162
|
+
main_page_suffix: @config['web_index_object'],
|
163
|
+
not_found_page: @config['web_error_object']
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
if @config['versioning']
|
168
|
+
params[:versioning] = MU::Cloud::Google.storage(:Bucket)::Versioning.new(enabled: true)
|
169
|
+
else
|
170
|
+
params[:versioning] = MU::Cloud::Google.storage(:Bucket)::Versioning.new(enabled: false)
|
171
|
+
end
|
172
|
+
|
173
|
+
MU::Cloud::Google.storage(:Bucket).new(params)
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|