cloud-mu 3.1.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +15 -3
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +10 -13
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +135 -37
- data/cloud-mu.gemspec +22 -20
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +3 -2
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +6 -16
- data/modules/mu.rb +165 -111
- data/modules/mu/adoption.rb +401 -68
- data/modules/mu/cleanup.rb +199 -306
- data/modules/mu/cloud.rb +100 -1632
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +46 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +920 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +165 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +4 -4
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +83 -104
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +6 -6
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +4 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +3 -3
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/loadbalancer.rb +60 -14
- data/modules/mu/config/log.rb +4 -4
- data/modules/mu/config/msg_queue.rb +4 -4
- data/modules/mu/config/nosqldb.rb +4 -4
- data/modules/mu/config/notifier.rb +3 -3
- data/modules/mu/config/ref.rb +365 -0
- data/modules/mu/config/role.rb +4 -4
- data/modules/mu/config/schema_helpers.rb +509 -0
- data/modules/mu/config/search_domain.rb +4 -4
- data/modules/mu/config/server.rb +97 -70
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +5 -9
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +200 -0
- data/modules/mu/config/user.rb +4 -4
- data/modules/mu/config/vpc.rb +70 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +83 -60
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +30 -26
- data/modules/mu/groomer.rb +17 -2
- data/modules/mu/groomers/ansible.rb +188 -41
- data/modules/mu/groomers/chef.rb +116 -55
- data/modules/mu/logger.rb +127 -148
- data/modules/mu/master.rb +389 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -3
- data/modules/mu/mommacat.rb +217 -2612
- data/modules/mu/mommacat/daemon.rb +397 -0
- data/modules/mu/mommacat/naming.rb +473 -0
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +722 -0
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +271 -112
- data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
- data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
- data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
- data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
- data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
- data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
- data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
- data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
- data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
- data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
- data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +29 -9
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
- data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
- data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
- data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
- data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +67 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
- data/modules/mu/{clouds → providers}/google/database.rb +10 -20
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
- data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
- data/modules/mu/{clouds → providers}/google/function.rb +139 -167
- data/modules/mu/{clouds → providers}/google/group.rb +29 -34
- data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
- data/modules/mu/{clouds → providers}/google/role.rb +92 -58
- data/modules/mu/{clouds → providers}/google/server.rb +242 -155
- data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
- data/modules/mu/{clouds → providers}/google/user.rb +95 -31
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +11 -0
- data/modules/tests/centos7.yaml +11 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -0
- data/modules/tests/super_simple_bok.yml +1 -3
- data/modules/tests/win2k12.yaml +17 -5
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +232 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
@@ -25,14 +25,7 @@ module MU
|
|
25
25
|
@config["groomer"] = MU::Config.defaultGroomer unless @config["groomer"]
|
26
26
|
@groomclass = MU::Groomer.loadGroomer(@config["groomer"])
|
27
27
|
|
28
|
-
@mu_name ||=
|
29
|
-
if @config and @config['engine'] and @config["engine"].match(/^sqlserver/)
|
30
|
-
@deploy.getResourceName(@config["name"], max_length: 15)
|
31
|
-
else
|
32
|
-
@deploy.getResourceName(@config["name"], max_length: 63)
|
33
|
-
end
|
34
|
-
|
35
|
-
@mu_name.gsub(/(--|-$)/i, "").gsub(/(_)/, "-").gsub!(/^[^a-z]/i, "")
|
28
|
+
@mu_name ||= @deploy.getResourceName(@config["name"], max_length: 63)
|
36
29
|
end
|
37
30
|
|
38
31
|
# Called automatically by {MU::Deploy#createResources}
|
@@ -68,8 +61,7 @@ module MU
|
|
68
61
|
# Locate an existing Database or Databases and return an array containing matching GCP resource descriptors for those that match.
|
69
62
|
# @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching Databases
|
70
63
|
def self.find(**args)
|
71
|
-
args
|
72
|
-
args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
|
64
|
+
args = MU::Cloud::Google.findLocationArgs(args)
|
73
65
|
end
|
74
66
|
|
75
67
|
# Called automatically by {MU::Deploy#createResources}
|
@@ -109,21 +101,21 @@ module MU
|
|
109
101
|
# @param region [String]: The cloud provider region in which to operate
|
110
102
|
# @return [void]
|
111
103
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
112
|
-
flags["
|
113
|
-
|
114
|
-
# instances = MU::Cloud::Google.sql(credentials: credentials).list_instances(flags['
|
104
|
+
flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
|
105
|
+
|
106
|
+
# instances = MU::Cloud::Google.sql(credentials: credentials).list_instances(flags['habitat'], filter: %Q{userLabels.mu-id:"#{MU.deploy_id.downcase}"})
|
115
107
|
# if instances and instances.items
|
116
108
|
# instances.items.each { |instance|
|
117
109
|
# MU.log "Deleting Cloud SQL instance #{instance.name}"
|
118
|
-
# MU::Cloud::Google.sql(credentials: credentials).delete_instance(flags['
|
110
|
+
# MU::Cloud::Google.sql(credentials: credentials).delete_instance(flags['habitat'], instance.name) if !noop
|
119
111
|
# }
|
120
112
|
# end
|
121
113
|
end
|
122
114
|
|
123
115
|
# Cloud-specific configuration properties.
|
124
|
-
# @param
|
116
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
125
117
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
126
|
-
def self.schema(
|
118
|
+
def self.schema(_config)
|
127
119
|
toplevel_required = []
|
128
120
|
schema = {}
|
129
121
|
[toplevel_required, schema]
|
@@ -131,9 +123,9 @@ module MU
|
|
131
123
|
|
132
124
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::databases}, bare and unvalidated.
|
133
125
|
# @param db [Hash]: The resource to process and validate
|
134
|
-
# @param
|
126
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
135
127
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
136
|
-
def self.validateConfig(db,
|
128
|
+
def self.validateConfig(db, _configurator)
|
137
129
|
ok = true
|
138
130
|
|
139
131
|
if db["create_cluster"]
|
@@ -144,8 +136,6 @@ module MU
|
|
144
136
|
ok
|
145
137
|
end
|
146
138
|
|
147
|
-
private
|
148
|
-
|
149
139
|
end #class
|
150
140
|
end #class
|
151
141
|
end
|
@@ -172,8 +172,7 @@ end
|
|
172
172
|
# @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
|
173
173
|
# @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
|
174
174
|
def self.find(**args)
|
175
|
-
args
|
176
|
-
args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
|
175
|
+
args = MU::Cloud::Google.findLocationArgs(args)
|
177
176
|
|
178
177
|
found = {}
|
179
178
|
resp = begin
|
@@ -207,15 +206,19 @@ end
|
|
207
206
|
# Remove all security groups (firewall rulesets) associated with the currently loaded deployment.
|
208
207
|
# @param noop [Boolean]: If true, will only print what would be done
|
209
208
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
210
|
-
# @param region [String]: The cloud provider region
|
211
209
|
# @return [void]
|
212
|
-
def self.cleanup(noop: false, ignoremaster: false,
|
213
|
-
flags["
|
214
|
-
return if !MU::Cloud
|
210
|
+
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
211
|
+
flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
|
212
|
+
return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
|
213
|
+
filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
|
214
|
+
if !ignoremaster and MU.mu_public_ip
|
215
|
+
filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
|
216
|
+
end
|
217
|
+
MU.log "Placeholder: Google FirewallRule artifacts do not support labels, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: filter
|
215
218
|
|
216
219
|
MU::Cloud::Google.compute(credentials: credentials).delete(
|
217
220
|
"firewall",
|
218
|
-
flags["
|
221
|
+
flags["habitat"],
|
219
222
|
nil,
|
220
223
|
noop
|
221
224
|
)
|
@@ -224,7 +227,7 @@ end
|
|
224
227
|
# Reverse-map our cloud description into a runnable config hash.
|
225
228
|
# We assume that any values we have in +@config+ are placeholders, and
|
226
229
|
# calculate our own accordingly based on what's live in the cloud.
|
227
|
-
def toKitten(
|
230
|
+
def toKitten(**_args)
|
228
231
|
|
229
232
|
if cloud_desc.name.match(/^[a-f0-9]+$/)
|
230
233
|
gke_ish = true
|
@@ -362,9 +365,9 @@ end
|
|
362
365
|
end
|
363
366
|
|
364
367
|
# Cloud-specific configuration properties.
|
365
|
-
# @param
|
368
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
366
369
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
367
|
-
def self.schema(
|
370
|
+
def self.schema(_config = nil)
|
368
371
|
toplevel_required = []
|
369
372
|
schema = {
|
370
373
|
"rules" => {
|
@@ -437,7 +440,7 @@ end
|
|
437
440
|
elsif acl['vpc']['habitat'] and acl['vpc']['habitat']['name']
|
438
441
|
acl['vpc']['project'] = acl['vpc']['habitat']['name']
|
439
442
|
end
|
440
|
-
correct_vpc = MU::Cloud
|
443
|
+
correct_vpc = MU::Cloud.resourceClass("Google", "VPC").pickVPC(
|
441
444
|
acl['vpc'],
|
442
445
|
acl,
|
443
446
|
"firewall_rule",
|
@@ -523,7 +526,7 @@ end
|
|
523
526
|
end
|
524
527
|
}
|
525
528
|
|
526
|
-
rules_by_class.reject! { |
|
529
|
+
rules_by_class.reject! { |_k, v| v.size == 0 }
|
527
530
|
|
528
531
|
# Generate other firewall rule objects to cover the other behaviors
|
529
532
|
# we've requested, if indeed we've done so.
|
@@ -543,8 +546,6 @@ end
|
|
543
546
|
ok
|
544
547
|
end
|
545
548
|
|
546
|
-
private
|
547
|
-
|
548
549
|
end #class
|
549
550
|
end #class
|
550
551
|
end
|
@@ -48,7 +48,7 @@ module MU
|
|
48
48
|
folder_obj = MU::Cloud::Google.folder(:Folder).new(params)
|
49
49
|
|
50
50
|
MU.log "Creating folder #{name_string} under #{parent}", details: folder_obj
|
51
|
-
|
51
|
+
MU::Cloud::Google.folder(credentials: @config['credentials']).create_folder(folder_obj, parent: parent)
|
52
52
|
|
53
53
|
# Wait for list_folders output to be consistent (for the folder we
|
54
54
|
# just created to show up)
|
@@ -125,10 +125,12 @@ module MU
|
|
125
125
|
nil
|
126
126
|
end
|
127
127
|
|
128
|
+
@cached_cloud_desc = nil
|
128
129
|
# Return the cloud descriptor for the Folder
|
129
130
|
# @return [Google::Apis::Core::Hashable]
|
130
|
-
def cloud_desc
|
131
|
-
@cached_cloud_desc
|
131
|
+
def cloud_desc(use_cache: true)
|
132
|
+
return @cached_cloud_desc if @cached_cloud_desc and use_cache
|
133
|
+
@cached_cloud_desc = MU::Cloud::Google::Folder.find(cloud_id: @cloud_id, credentials: @config['credentials']).values.first
|
132
134
|
@habitat_id ||= @cached_cloud_desc.parent.sub(/^(folders|organizations)\//, "")
|
133
135
|
@cached_cloud_desc
|
134
136
|
end
|
@@ -136,7 +138,7 @@ module MU
|
|
136
138
|
# Return the metadata for this folders's configuration
|
137
139
|
# @return [Hash]
|
138
140
|
def notify
|
139
|
-
desc = MU.structToHash(
|
141
|
+
desc = MU.structToHash(cloud_desc)
|
140
142
|
desc["mu_name"] = @mu_name
|
141
143
|
desc["parent"] = @parent
|
142
144
|
desc["cloud_id"] = @cloud_id
|
@@ -160,7 +162,12 @@ module MU
|
|
160
162
|
# @param noop [Boolean]: If true, will only print what would be done
|
161
163
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
162
164
|
# @return [void]
|
163
|
-
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {}
|
165
|
+
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
166
|
+
filter = %Q{(labels.mu-id = "#{MU.deploy_id.downcase}")}
|
167
|
+
if !ignoremaster and MU.mu_public_ip
|
168
|
+
filter += %Q{ AND (labels.mu-master-ip = "#{MU.mu_public_ip.gsub(/\./, "_")}")}
|
169
|
+
end
|
170
|
+
MU.log "Placeholder: Google Folder artifacts do not support labels, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: filter
|
164
171
|
# We can't label GCP folders, and their names are too short to encode
|
165
172
|
# Mu deploy IDs, so all we can do is rely on flags['known'] passed in
|
166
173
|
# from cleanup, which relies on our metadata to know what's ours.
|
@@ -229,10 +236,10 @@ module MU
|
|
229
236
|
# @return [Hash<String,OpenStruct>]: The cloud provider's complete descriptions of matching resources
|
230
237
|
def self.find(**args)
|
231
238
|
found = {}
|
232
|
-
|
233
239
|
# Recursively search a GCP folder hierarchy for a folder matching our
|
234
240
|
# supplied name or identifier.
|
235
241
|
def self.find_matching_folder(parent, name: nil, id: nil, credentials: nil)
|
242
|
+
|
236
243
|
resp = MU::Cloud::Google.folder(credentials: credentials).list_folders(parent: parent)
|
237
244
|
if resp and resp.folders
|
238
245
|
resp.folders.each { |f|
|
@@ -271,6 +278,7 @@ module MU
|
|
271
278
|
end
|
272
279
|
else
|
273
280
|
resp = MU::Cloud::Google.folder(credentials: args[:credentials]).list_folders(parent: parent)
|
281
|
+
|
274
282
|
if resp and resp.folders
|
275
283
|
resp.folders.each { |folder|
|
276
284
|
next if folder.lifecycle_state == "DELETE_REQUESTED"
|
@@ -293,7 +301,7 @@ module MU
|
|
293
301
|
# Reverse-map our cloud description into a runnable config hash.
|
294
302
|
# We assume that any values we have in +@config+ are placeholders, and
|
295
303
|
# calculate our own accordingly based on what's live in the cloud.
|
296
|
-
def toKitten(
|
304
|
+
def toKitten(**args)
|
297
305
|
bok = {
|
298
306
|
"cloud" => "Google",
|
299
307
|
"credentials" => @config['credentials']
|
@@ -303,16 +311,15 @@ module MU
|
|
303
311
|
bok['cloud_id'] = cloud_desc.name
|
304
312
|
bok['name'] = cloud_desc.display_name#+bok['cloud_id'] # only way to guarantee uniqueness
|
305
313
|
if cloud_desc.parent.match(/^folders\/(.*)/)
|
306
|
-
MU.log bok['display_name']+" generating reference", MU::NOTICE, details: cloud_desc.parent
|
307
314
|
bok['parent'] = MU::Config::Ref.get(
|
308
315
|
id: cloud_desc.parent,
|
309
316
|
cloud: "Google",
|
310
317
|
credentials: @config['credentials'],
|
311
318
|
type: "folders"
|
312
319
|
)
|
313
|
-
elsif rootparent
|
320
|
+
elsif args[:rootparent]
|
314
321
|
bok['parent'] = {
|
315
|
-
'id' => rootparent.is_a?(String) ? rootparent : rootparent.cloud_desc.name
|
322
|
+
'id' => args[:rootparent].is_a?(String) ? args[:rootparent] : args[:rootparent].cloud_desc.name
|
316
323
|
}
|
317
324
|
else
|
318
325
|
bok['parent'] = { 'id' => cloud_desc.parent }
|
@@ -322,9 +329,9 @@ MU.log bok['display_name']+" generating reference", MU::NOTICE, details: cloud_d
|
|
322
329
|
end
|
323
330
|
|
324
331
|
# Cloud-specific configuration properties.
|
325
|
-
# @param
|
332
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
326
333
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
327
|
-
def self.schema(
|
334
|
+
def self.schema(_config)
|
328
335
|
toplevel_required = []
|
329
336
|
schema = {
|
330
337
|
"display_name" => {
|
@@ -348,11 +355,7 @@ MU.log bok['display_name']+" generating reference", MU::NOTICE, details: cloud_d
|
|
348
355
|
end
|
349
356
|
|
350
357
|
if folder['parent'] and folder['parent']['name'] and !folder['parent']['deploy_id'] and configurator.haveLitterMate?(folder['parent']['name'], "folders")
|
351
|
-
folder[
|
352
|
-
folder["dependencies"] << {
|
353
|
-
"type" => "folder",
|
354
|
-
"name" => folder['parent']['name']
|
355
|
-
}
|
358
|
+
MU::Config.addDependency(folder, folder['parent']['name'], "folder")
|
356
359
|
end
|
357
360
|
|
358
361
|
ok
|
@@ -108,98 +108,9 @@ module example.com/cloudfunction
|
|
108
108
|
|
109
109
|
# Called automatically by {MU::Deploy#createResources}
|
110
110
|
def create
|
111
|
-
labels = Hash[@tags.keys.map { |k|
|
112
|
-
[k.downcase, @tags[k].downcase.gsub(/[^-_a-z0-9]/, '-')] }
|
113
|
-
]
|
114
|
-
labels["name"] = MU::Cloud::Google.nameStr(@mu_name)
|
115
111
|
|
116
112
|
location = "projects/"+@config['project']+"/locations/"+@config['region']
|
117
|
-
|
118
|
-
retries = 0
|
119
|
-
begin
|
120
|
-
sa_ref = MU::Config::Ref.get(@config['service_account'])
|
121
|
-
sa = @deploy.findLitterMate(name: sa_ref.name, type: "users")
|
122
|
-
if !sa or !sa.cloud_desc
|
123
|
-
sleep 10
|
124
|
-
end
|
125
|
-
rescue ::Google::Apis::ClientError => e
|
126
|
-
if e.message.match(/notFound:/)
|
127
|
-
sleep 10
|
128
|
-
retries += 1
|
129
|
-
retry
|
130
|
-
end
|
131
|
-
end while !sa or !sa.cloud_desc and retries < 5
|
132
|
-
|
133
|
-
if !sa or !sa.cloud_desc
|
134
|
-
raise MuError, "Failed to get service account cloud id from #{@config['service_account'].to_s}"
|
135
|
-
end
|
136
|
-
|
137
|
-
desc = {
|
138
|
-
name: location+"/functions/"+@mu_name.downcase,
|
139
|
-
runtime: @config['runtime'],
|
140
|
-
timeout: @config['timeout'].to_s+"s",
|
141
|
-
# entry_point: "hello_world",
|
142
|
-
entry_point: @config['handler'],
|
143
|
-
description: @deploy.deploy_id,
|
144
|
-
service_account_email: sa.cloud_desc.email,
|
145
|
-
labels: labels,
|
146
|
-
available_memory_mb: @config['memory']
|
147
|
-
}
|
148
|
-
|
149
|
-
# XXX This network argument is deprecated in favor of using VPC
|
150
|
-
# Connectors. Which would be fine, except there's no API support for
|
151
|
-
# interacting with VPC Connectors. Can't create them, can't list them,
|
152
|
-
# can't do anything except pass their ids into Cloud Functions or
|
153
|
-
# AppEngine and hope for the best.
|
154
|
-
if @config['vpc_connector']
|
155
|
-
desc[:vpc_connector] = @config['vpc_connector']
|
156
|
-
elsif @vpc
|
157
|
-
desc[:network] = @vpc.url.sub(/^.*?\/projects\//, 'projects/')
|
158
|
-
end
|
159
|
-
|
160
|
-
if @config['triggers']
|
161
|
-
desc[:event_trigger] = MU::Cloud::Google.function(:EventTrigger).new(
|
162
|
-
event_type: @config['triggers'].first['event'],
|
163
|
-
resource: @config['triggers'].first['resource']
|
164
|
-
)
|
165
|
-
else
|
166
|
-
desc[:https_trigger] = MU::Cloud::Google.function(:HttpsTrigger).new
|
167
|
-
end
|
168
|
-
|
169
|
-
|
170
|
-
if @config['environment_variable']
|
171
|
-
@config['environment_variable'].each { |var|
|
172
|
-
desc[:environment_variables] ||= {}
|
173
|
-
desc[:environment_variables][var["key"].to_s] = var["value"].to_s
|
174
|
-
}
|
175
|
-
end
|
176
|
-
|
177
|
-
# hello_code = nil
|
178
|
-
# HELLO_WORLDS.each_pair { |runtime, code|
|
179
|
-
# if @config['runtime'].match(/^#{Regexp.quote(runtime)}/)
|
180
|
-
# hello_code = code
|
181
|
-
# break
|
182
|
-
# end
|
183
|
-
# }
|
184
|
-
if @config['code']['gs_url']
|
185
|
-
desc[:source_archive_url] = @config['code']['gs_url']
|
186
|
-
elsif @config['code']['zip_file']
|
187
|
-
desc[:source_archive_url] = MU::Cloud::Google::Function.uploadPackage(@config['code']['zip_file'], @mu_name+"-cloudfunction.zip", credentials: @credentials)
|
188
|
-
end
|
189
|
-
|
190
|
-
# Dir.mktmpdir(@mu_name) { |dir|
|
191
|
-
# hello_code.each_pair { |file, contents|
|
192
|
-
# f = File.open(dir+"/"+file, "w")
|
193
|
-
# f.puts contents
|
194
|
-
# f.close
|
195
|
-
# Zip::File.open(dir+"/function.zip", Zip::File::CREATE) { |z|
|
196
|
-
# z.add(file, dir+"/"+file)
|
197
|
-
# }
|
198
|
-
# }
|
199
|
-
# desc[:source_archive_url] = MU::Cloud::Google::Function.uploadPackage(dir+"/function.zip", @mu_name+"-cloudfunction.zip", credentials: @credentials)
|
200
|
-
# }
|
201
|
-
|
202
|
-
func_obj = MU::Cloud::Google.function(:CloudFunction).new(desc)
|
113
|
+
func_obj = buildDesc
|
203
114
|
MU.log "Creating Cloud Function #{@mu_name} in #{location}", details: func_obj
|
204
115
|
resp = MU::Cloud::Google.function(credentials: @credentials).create_project_location_function(location, func_obj)
|
205
116
|
@cloud_id = resp.name
|
@@ -214,27 +125,26 @@ module example.com/cloudfunction
|
|
214
125
|
labels["name"] = MU::Cloud::Google.nameStr(@mu_name)
|
215
126
|
|
216
127
|
if cloud_desc.labels != labels
|
217
|
-
|
128
|
+
need_update = true
|
218
129
|
end
|
219
130
|
|
220
131
|
if cloud_desc.runtime != @config['runtime']
|
221
|
-
|
132
|
+
need_update = true
|
222
133
|
end
|
223
134
|
if cloud_desc.timeout != @config['timeout'].to_s+"s"
|
224
|
-
|
135
|
+
need_update = true
|
225
136
|
end
|
226
137
|
if cloud_desc.entry_point != @config['handler']
|
227
|
-
|
138
|
+
need_update = true
|
228
139
|
end
|
229
140
|
if cloud_desc.available_memory_mb != @config['memory']
|
230
|
-
|
141
|
+
need_update = true
|
231
142
|
end
|
232
143
|
if @config['environment_variable']
|
233
144
|
@config['environment_variable'].each { |var|
|
234
145
|
if !cloud_desc.environment_variables or
|
235
146
|
cloud_desc.environment_variables[var["key"].to_s] != var["value"].to_s
|
236
|
-
|
237
|
-
desc[:environment_variables][var["key"].to_s] = var["value"].to_s
|
147
|
+
need_update = true
|
238
148
|
end
|
239
149
|
}
|
240
150
|
end
|
@@ -242,10 +152,7 @@ module example.com/cloudfunction
|
|
242
152
|
if !cloud_desc.event_trigger or
|
243
153
|
cloud_desc.event_trigger.event_type != @config['triggers'].first['event'] or
|
244
154
|
cloud_desc.event_trigger.resource != @config['triggers'].first['resource']
|
245
|
-
|
246
|
-
event_type: @config['triggers'].first['event'],
|
247
|
-
resource: @config['triggers'].first['resource']
|
248
|
-
)
|
155
|
+
need_update = true
|
249
156
|
end
|
250
157
|
end
|
251
158
|
|
@@ -254,7 +161,6 @@ module example.com/cloudfunction
|
|
254
161
|
File.read("#{dir}/current.zip")
|
255
162
|
}
|
256
163
|
|
257
|
-
source_url = nil
|
258
164
|
new = if @config['code']['zip_file']
|
259
165
|
File.read(@config['code']['zip_file'])
|
260
166
|
elsif @config['code']['gs_url']
|
@@ -269,37 +175,21 @@ module example.com/cloudfunction
|
|
269
175
|
if @config['code']['gs_url'] and
|
270
176
|
(@config['code']['gs_url'] != cloud_desc.source_archive_url or
|
271
177
|
current != new)
|
272
|
-
|
178
|
+
need_update = true
|
273
179
|
elsif @config['code']['zip_file'] and current != new
|
180
|
+
need_update = true
|
274
181
|
desc[:source_archive_url] = MU::Cloud::Google::Function.uploadPackage(@config['code']['zip_file'], @mu_name+"-cloudfunction.zip", credentials: @credentials)
|
275
182
|
end
|
276
183
|
|
277
|
-
if
|
278
|
-
|
279
|
-
# endpoint hangs indefinitely if either is missing. Charming.
|
280
|
-
if !desc[:https_trigger] and !desc[:event_trigger]
|
281
|
-
if cloud_desc.https_trigger
|
282
|
-
desc[:https_trigger] = MU::Cloud::Google.function(:HttpsTrigger).new
|
283
|
-
else
|
284
|
-
desc[:event_trigger] = cloud_desc.event_trigger
|
285
|
-
end
|
286
|
-
end
|
287
|
-
if !desc[:source_archive_url] and !desc[:source_upload_url]
|
288
|
-
if cloud_desc.source_archive_url
|
289
|
-
desc[:source_archive_url] = cloud_desc.source_archive_url
|
290
|
-
else
|
291
|
-
desc[:source_upload_url] = cloud_desc.source_upload_url
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
func_obj = MU::Cloud::Google.function(:CloudFunction).new(desc)
|
184
|
+
if need_update
|
185
|
+
func_obj = buildDesc
|
296
186
|
MU.log "Updating Cloud Function #{@mu_name}", MU::NOTICE, details: func_obj
|
297
187
|
begin
|
298
|
-
MU::Cloud::Google.function(credentials: @credentials).patch_project_location_function(
|
299
|
-
@cloud_id,
|
300
|
-
func_obj
|
301
|
-
)
|
302
|
-
rescue ::Google::Apis::ClientError
|
188
|
+
# MU::Cloud::Google.function(credentials: @credentials).patch_project_location_function(
|
189
|
+
# @cloud_id,
|
190
|
+
# func_obj
|
191
|
+
# )
|
192
|
+
rescue ::Google::Apis::ClientError
|
303
193
|
MU.log "Error updating Cloud Function #{@mu_name}.", MU::ERR
|
304
194
|
if desc[:source_archive_url]
|
305
195
|
main_file = nil
|
@@ -344,13 +234,13 @@ module example.com/cloudfunction
|
|
344
234
|
# @param region [String]: The cloud provider region
|
345
235
|
# @return [void]
|
346
236
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
347
|
-
flags["
|
348
|
-
return if !MU::Cloud
|
237
|
+
flags["habitat"] ||= MU::Cloud::Google.defaultProject(credentials)
|
238
|
+
return if !MU::Cloud.resourceClass("Google", "Habitat").isLive?(flags["habitat"], credentials)
|
349
239
|
# Make sure we catch regional *and* zone functions
|
350
|
-
found = MU::Cloud::Google::Function.find(credentials: credentials, region: region, project: flags["
|
240
|
+
found = MU::Cloud::Google::Function.find(credentials: credentials, region: region, project: flags["habitat"])
|
351
241
|
found.each_pair { |cloud_id, desc|
|
352
242
|
if (desc.description and desc.description == MU.deploy_id) or
|
353
|
-
(desc.labels and desc.labels["mu-id"] == MU.deploy_id.downcase) or
|
243
|
+
(desc.labels and desc.labels["mu-id"] == MU.deploy_id.downcase and (ignoremaster or desc.labels["mu-master-ip"] == MU.mu_public_ip.gsub(/\./, "_"))) or
|
354
244
|
(flags["known"] and flags["known"].include?(cloud_id))
|
355
245
|
MU.log "Deleting Cloud Function #{desc.name}"
|
356
246
|
if !noop
|
@@ -364,9 +254,7 @@ module example.com/cloudfunction
|
|
364
254
|
# Locate an existing project
|
365
255
|
# @return [Hash<OpenStruct>]: The cloud provider's complete descriptions of matching project
|
366
256
|
def self.find(**args)
|
367
|
-
args
|
368
|
-
args[:project] ||= MU::Cloud::Google.defaultProject(args[:credentials])
|
369
|
-
location = args[:region] || args[:availability_zone] || "-"
|
257
|
+
args = MU::Cloud::Google.findLocationArgs(args)
|
370
258
|
|
371
259
|
found = {}
|
372
260
|
|
@@ -379,7 +267,7 @@ module example.com/cloudfunction
|
|
379
267
|
found[args[:cloud_id]] = resp if resp
|
380
268
|
else
|
381
269
|
resp = begin
|
382
|
-
MU::Cloud::Google.function(credentials: args[:credentials]).list_project_location_functions("projects/#{args[:project]}/locations/#{location}")
|
270
|
+
MU::Cloud::Google.function(credentials: args[:credentials]).list_project_location_functions("projects/#{args[:project]}/locations/#{args[:location]}")
|
383
271
|
rescue ::Google::Apis::ClientError => e
|
384
272
|
raise e if !e.message.match(/forbidden:/)
|
385
273
|
end
|
@@ -397,7 +285,7 @@ module example.com/cloudfunction
|
|
397
285
|
# Reverse-map our cloud description into a runnable config hash.
|
398
286
|
# We assume that any values we have in +@config+ are placeholders, and
|
399
287
|
# calculate our own accordingly based on what's live in the cloud.
|
400
|
-
def toKitten(
|
288
|
+
def toKitten(**_args)
|
401
289
|
bok = {
|
402
290
|
"cloud" => "Google",
|
403
291
|
"cloud_id" => @cloud_id,
|
@@ -452,7 +340,7 @@ module example.com/cloudfunction
|
|
452
340
|
end
|
453
341
|
|
454
342
|
codefile = bok["project"]+"_"+bok["region"]+"_"+bok["name"]+".zip"
|
455
|
-
MU::Cloud::Google::Function.downloadPackage(@cloud_id, codefile, credentials: @config['credentials'])
|
343
|
+
return nil if !MU::Cloud::Google::Function.downloadPackage(@cloud_id, codefile, credentials: @config['credentials'])
|
456
344
|
bok['code'] = {
|
457
345
|
'zip_file' => codefile
|
458
346
|
}
|
@@ -460,7 +348,6 @@ module example.com/cloudfunction
|
|
460
348
|
bok
|
461
349
|
end
|
462
350
|
|
463
|
-
|
464
351
|
# Cloud-specific configuration properties.
|
465
352
|
# @param config [MU::Config]: The calling MU::Config object
|
466
353
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
@@ -486,7 +373,7 @@ module example.com/cloudfunction
|
|
486
373
|
}
|
487
374
|
}
|
488
375
|
},
|
489
|
-
"service_account" => MU::Cloud
|
376
|
+
"service_account" => MU::Cloud.resourceClass("Google", "Server").schema(config)[1]["service_account"],
|
490
377
|
"runtime" => {
|
491
378
|
"type" => "string",
|
492
379
|
"enum" => %w{nodejs go python nodejs8 nodejs10 python37 go111 go113},
|
@@ -495,8 +382,14 @@ module example.com/cloudfunction
|
|
495
382
|
"type" => "string",
|
496
383
|
"description" => "+DEPRECATED+ VPC Connector to attach, of the form +projects/my-project/locations/some-region/connectors/my-connector+. This option will be removed once proper google-cloud-sdk support for VPC Connectors becomes available, at which point we will piggyback on the normal +vpc+ stanza and resolve connectors as needed."
|
497
384
|
},
|
385
|
+
"vpc_connector_allow_all_egress" => {
|
386
|
+
"type" => "boolean",
|
387
|
+
"default" => false,
|
388
|
+
"description" => "+DEPRECATED+ Allow VPC connector egress traffic to any IP range, instead of just private IPs. This option will be removed once proper google-cloud-sdk support for VPC Connectors becomes available, at which point we will piggyback on the normal +vpc+ stanza and resolve connectors as needed."
|
389
|
+
},
|
498
390
|
"code" => {
|
499
391
|
"type" => "object",
|
392
|
+
"description" => "Zipped deployment package to upload to our function.",
|
500
393
|
"properties" => {
|
501
394
|
"gs_url" => {
|
502
395
|
"type" => "string",
|
@@ -523,8 +416,13 @@ module example.com/cloudfunction
|
|
523
416
|
cloud_desc.source_archive_url.match(/^gs:\/\/([^\/]+)\/(.*)/)
|
524
417
|
bucket = Regexp.last_match[1]
|
525
418
|
path = Regexp.last_match[2]
|
526
|
-
|
527
|
-
|
419
|
+
|
420
|
+
begin
|
421
|
+
MU::Cloud::Google.storage(credentials: credentials).get_object(bucket, path, download_dest: zipfile)
|
422
|
+
rescue ::Google::Apis::ClientError => e
|
423
|
+
MU.log "Couldn't retrieve gs://#{bucket}/#{path} for #{function_id}", MU::WARN, details: e.inspect
|
424
|
+
return false
|
425
|
+
end
|
528
426
|
elsif cloud_desc.source_upload_url
|
529
427
|
resp = MU::Cloud::Google.function(credentials: credentials).generate_function_download_url(
|
530
428
|
function_id
|
@@ -535,6 +433,7 @@ module example.com/cloudfunction
|
|
535
433
|
f.close
|
536
434
|
end
|
537
435
|
end
|
436
|
+
true
|
538
437
|
end
|
539
438
|
|
540
439
|
# Upload a zipfile to our admin Cloud Storage bucket, for use by
|
@@ -625,32 +524,7 @@ module example.com/cloudfunction
|
|
625
524
|
ok = false
|
626
525
|
end
|
627
526
|
else
|
628
|
-
|
629
|
-
"name" => function['name'],
|
630
|
-
"cloud" => "Google",
|
631
|
-
"project" => function["project"],
|
632
|
-
"credentials" => function["credentials"],
|
633
|
-
"type" => "service"
|
634
|
-
}
|
635
|
-
if user["name"].length < 6
|
636
|
-
user["name"] += Password.pronounceable(6)
|
637
|
-
end
|
638
|
-
if function['roles']
|
639
|
-
user['roles'] = function['roles'].dup
|
640
|
-
end
|
641
|
-
configurator.insertKitten(user, "users", true)
|
642
|
-
function['dependencies'] ||= []
|
643
|
-
function['service_account'] = MU::Config::Ref.get(
|
644
|
-
type: "users",
|
645
|
-
cloud: "Google",
|
646
|
-
name: user["name"],
|
647
|
-
project: user["project"],
|
648
|
-
credentials: user["credentials"]
|
649
|
-
)
|
650
|
-
function['dependencies'] << {
|
651
|
-
"type" => "user",
|
652
|
-
"name" => user["name"]
|
653
|
-
}
|
527
|
+
function = MU::Cloud.resourceClass("Google", "User").genericServiceAccount(function, configurator)
|
654
528
|
end
|
655
529
|
|
656
530
|
# siblings = configurator.haveLitterMate?(nil, "vpcs", has_multiple: true)
|
@@ -673,6 +547,104 @@ module example.com/cloudfunction
|
|
673
547
|
ok
|
674
548
|
end
|
675
549
|
|
550
|
+
private
|
551
|
+
|
552
|
+
def buildDesc
|
553
|
+
labels = Hash[@tags.keys.map { |k|
|
554
|
+
[k.downcase, @tags[k].downcase.gsub(/[^-_a-z0-9]/, '-')] }
|
555
|
+
]
|
556
|
+
labels["name"] = MU::Cloud::Google.nameStr(@mu_name)
|
557
|
+
|
558
|
+
location = "projects/"+@config['project']+"/locations/"+@config['region']
|
559
|
+
sa = nil
|
560
|
+
retries = 0
|
561
|
+
begin
|
562
|
+
sa_ref = MU::Config::Ref.get(@config['service_account'])
|
563
|
+
sa = @deploy.findLitterMate(name: sa_ref.name, type: "users")
|
564
|
+
if !sa or !sa.cloud_desc
|
565
|
+
sleep 10
|
566
|
+
end
|
567
|
+
rescue ::Google::Apis::ClientError => e
|
568
|
+
if e.message.match(/notFound:/)
|
569
|
+
sleep 10
|
570
|
+
retries += 1
|
571
|
+
retry
|
572
|
+
end
|
573
|
+
end while !sa or !sa.cloud_desc and retries < 5
|
574
|
+
|
575
|
+
if !sa or !sa.cloud_desc
|
576
|
+
raise MuError, "Failed to get service account cloud id from #{@config['service_account'].to_s}"
|
577
|
+
end
|
578
|
+
|
579
|
+
desc = {
|
580
|
+
name: location+"/functions/"+@mu_name.downcase,
|
581
|
+
runtime: @config['runtime'],
|
582
|
+
timeout: @config['timeout'].to_s+"s",
|
583
|
+
# entry_point: "hello_world",
|
584
|
+
entry_point: @config['handler'],
|
585
|
+
description: @deploy.deploy_id,
|
586
|
+
service_account_email: sa.cloud_desc.email,
|
587
|
+
labels: labels,
|
588
|
+
available_memory_mb: @config['memory']
|
589
|
+
}
|
590
|
+
|
591
|
+
# XXX This network argument is deprecated in favor of using VPC
|
592
|
+
# Connectors. Which would be fine, except there's no API support for
|
593
|
+
# interacting with VPC Connectors. Can't create them, can't list them,
|
594
|
+
# can't do anything except pass their ids into Cloud Functions or
|
595
|
+
# AppEngine and hope for the best.
|
596
|
+
if @config['vpc_connector']
|
597
|
+
desc[:vpc_connector] = @config['vpc_connector']
|
598
|
+
desc[:vpc_connector_egress_settings] = @config['vpc_connector_allow_all_egress'] ? "ALL_TRAFFIC" : "PRIVATE_RANGES_ONLY"
|
599
|
+
pp desc
|
600
|
+
elsif @vpc
|
601
|
+
desc[:network] = @vpc.url.sub(/^.*?\/projects\//, 'projects/')
|
602
|
+
end
|
603
|
+
|
604
|
+
if @config['triggers']
|
605
|
+
desc[:event_trigger] = MU::Cloud::Google.function(:EventTrigger).new(
|
606
|
+
event_type: @config['triggers'].first['event'],
|
607
|
+
resource: @config['triggers'].first['resource']
|
608
|
+
)
|
609
|
+
else
|
610
|
+
desc[:https_trigger] = MU::Cloud::Google.function(:HttpsTrigger).new
|
611
|
+
end
|
612
|
+
|
613
|
+
|
614
|
+
if @config['environment_variable']
|
615
|
+
@config['environment_variable'].each { |var|
|
616
|
+
desc[:environment_variables] ||= {}
|
617
|
+
desc[:environment_variables][var["key"].to_s] = var["value"].to_s
|
618
|
+
}
|
619
|
+
end
|
620
|
+
|
621
|
+
# hello_code = nil
|
622
|
+
# HELLO_WORLDS.each_pair { |runtime, code|
|
623
|
+
# if @config['runtime'].match(/^#{Regexp.quote(runtime)}/)
|
624
|
+
# hello_code = code
|
625
|
+
# break
|
626
|
+
# end
|
627
|
+
# }
|
628
|
+
if @config['code']['gs_url']
|
629
|
+
desc[:source_archive_url] = @config['code']['gs_url']
|
630
|
+
elsif @config['code']['zip_file']
|
631
|
+
desc[:source_archive_url] = MU::Cloud::Google::Function.uploadPackage(@config['code']['zip_file'], @mu_name+"-cloudfunction.zip", credentials: @credentials)
|
632
|
+
end
|
633
|
+
|
634
|
+
# Dir.mktmpdir(@mu_name) { |dir|
|
635
|
+
# hello_code.each_pair { |file, contents|
|
636
|
+
# f = File.open(dir+"/"+file, "w")
|
637
|
+
# f.puts contents
|
638
|
+
# f.close
|
639
|
+
# Zip::File.open(dir+"/function.zip", Zip::File::CREATE) { |z|
|
640
|
+
# z.add(file, dir+"/"+file)
|
641
|
+
# }
|
642
|
+
# }
|
643
|
+
# desc[:source_archive_url] = MU::Cloud::Google::Function.uploadPackage(dir+"/function.zip", @mu_name+"-cloudfunction.zip", credentials: @credentials)
|
644
|
+
# }
|
645
|
+
MU::Cloud::Google.function(:CloudFunction).new(desc)
|
646
|
+
end
|
647
|
+
|
676
648
|
end
|
677
649
|
end
|
678
650
|
end
|