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
@@ -203,6 +203,9 @@ module MU
|
|
203
203
|
# @param region [String]: The cloud provider region
|
204
204
|
# @return [void]
|
205
205
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
206
|
+
MU.log "AWS::Log.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
207
|
+
MU.log "Placeholder: AWS Log artifacts do not support tags, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: ignoremaster
|
208
|
+
|
206
209
|
log_groups = self.find(credentials: credentials, region: region).values
|
207
210
|
if !log_groups.empty?
|
208
211
|
log_groups.each{ |lg|
|
@@ -227,13 +230,13 @@ module MU
|
|
227
230
|
}
|
228
231
|
end
|
229
232
|
|
230
|
-
unless noop
|
231
|
-
MU::Cloud::AWS.iam(credentials: credentials).list_roles.roles.each{ |role|
|
232
|
-
match_string = "#{MU.deploy_id}.*CloudTrail"
|
233
|
-
# Maybe we should have a more generic way to delete IAM profiles and policies. The call itself should be moved from MU::Cloud
|
234
|
-
# MU::Cloud
|
235
|
-
}
|
236
|
-
end
|
233
|
+
# unless noop
|
234
|
+
# MU::Cloud::AWS.iam(credentials: credentials).list_roles.roles.each{ |role|
|
235
|
+
# match_string = "#{MU.deploy_id}.*CloudTrail"
|
236
|
+
# Maybe we should have a more generic way to delete IAM profiles and policies. The call itself should be moved from MU::Cloud.resourceClass("AWS", "Server").
|
237
|
+
# MU::Cloud.resourceClass("AWS", "Server").removeIAMProfile(role.role_name) if role.role_name.match(match_string)
|
238
|
+
# }
|
239
|
+
# end
|
237
240
|
end
|
238
241
|
|
239
242
|
# Locate an existing log group.
|
@@ -264,7 +267,7 @@ module MU
|
|
264
267
|
# Reverse-map our cloud description into a runnable config hash.
|
265
268
|
# We assume that any values we have in +@config+ are placeholders, and
|
266
269
|
# calculate our own accordingly based on what's live in the cloud.
|
267
|
-
def toKitten(
|
270
|
+
def toKitten(**_args)
|
268
271
|
bok = {
|
269
272
|
"cloud" => "AWS",
|
270
273
|
"credentials" => @config['credentials'],
|
@@ -304,9 +307,9 @@ module MU
|
|
304
307
|
|
305
308
|
|
306
309
|
# Cloud-specific configuration properties.
|
307
|
-
# @param
|
310
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
308
311
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
309
|
-
def self.schema(
|
312
|
+
def self.schema(_config)
|
310
313
|
toplevel_required = []
|
311
314
|
schema = {
|
312
315
|
"retention_period" => {
|
@@ -357,9 +360,9 @@ module MU
|
|
357
360
|
|
358
361
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::logs}, bare and unvalidated.
|
359
362
|
# @param log [Hash]: The resource to process and validate
|
360
|
-
# @param
|
363
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
361
364
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
362
|
-
def self.validateConfig(log,
|
365
|
+
def self.validateConfig(log, _configurator)
|
363
366
|
ok = true
|
364
367
|
|
365
368
|
if log["filters"] && !log["filters"].empty?
|
@@ -53,14 +53,14 @@ module MU
|
|
53
53
|
new_attrs = genQueueAttrs
|
54
54
|
|
55
55
|
changed = false
|
56
|
-
new_attrs.each_pair { |k,
|
56
|
+
new_attrs.each_pair { |k, _v|
|
57
57
|
if !cur_attrs.has_key?(k) or cur_attrs[k] != new_attrs[k]
|
58
58
|
changed = true
|
59
59
|
end
|
60
60
|
}
|
61
61
|
if changed
|
62
62
|
MU.log "Updating SQS queue #{@mu_name}", MU::NOTICE, details: new_attrs
|
63
|
-
|
63
|
+
MU::Cloud::AWS.sqs(region: @config['region'], credentials: @config['credentials']).set_queue_attributes(
|
64
64
|
queue_url: @cloud_id,
|
65
65
|
attributes: new_attrs
|
66
66
|
)
|
@@ -74,10 +74,13 @@ module MU
|
|
74
74
|
"arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":sqs:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":"+@cloud_id
|
75
75
|
end
|
76
76
|
|
77
|
+
@cloud_desc_cache = nil
|
77
78
|
# Retrieve the AWS descriptor for this SQS queue. AWS doesn't exactly
|
78
79
|
# provide one; if you want real information for SQS ask notify()
|
79
80
|
# @return [Hash]: AWS doesn't return anything but the SQS URL, so supplement with attributes
|
80
|
-
def cloud_desc
|
81
|
+
def cloud_desc(use_cache: true)
|
82
|
+
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
83
|
+
|
81
84
|
if !@cloud_id
|
82
85
|
resp = MU::Cloud::AWS.sqs(region: @config['region'], credentials: @config['credentials']).list_queues(
|
83
86
|
queue_name_prefix: @mu_name
|
@@ -92,11 +95,12 @@ module MU
|
|
92
95
|
end
|
93
96
|
|
94
97
|
return nil if !@cloud_id
|
95
|
-
MU::Cloud::AWS::MsgQueue.find(
|
98
|
+
@cloud_desc_cache = MU::Cloud::AWS::MsgQueue.find(
|
96
99
|
cloud_id: @cloud_id.dup,
|
97
100
|
region: @config['region'],
|
98
101
|
credentials: @config['credentials']
|
99
102
|
)
|
103
|
+
@cloud_desc_cache
|
100
104
|
end
|
101
105
|
|
102
106
|
# Return the metadata for this MsgQueue rule
|
@@ -130,6 +134,9 @@ module MU
|
|
130
134
|
# @param region [String]: The cloud provider region
|
131
135
|
# @return [void]
|
132
136
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
137
|
+
MU.log "AWS::MsgQueue.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
138
|
+
MU.log "Placeholder: AWS MsgQueue artifacts do not support tags, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: ignoremaster
|
139
|
+
|
133
140
|
resp = MU::Cloud::AWS.sqs(credentials: credentials, region: region).list_queues(
|
134
141
|
queue_name_prefix: MU.deploy_id
|
135
142
|
)
|
@@ -182,7 +189,7 @@ module MU
|
|
182
189
|
args[:cloud_id] = resp.queue_url if resp and resp.queue_url
|
183
190
|
end
|
184
191
|
end
|
185
|
-
rescue ::Aws::SQS::Errors::NonExistentQueue
|
192
|
+
rescue ::Aws::SQS::Errors::NonExistentQueue
|
186
193
|
end
|
187
194
|
|
188
195
|
# Go fetch its attributes
|
@@ -211,9 +218,9 @@ module MU
|
|
211
218
|
end
|
212
219
|
|
213
220
|
# Cloud-specific configuration properties.
|
214
|
-
# @param
|
221
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
215
222
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
216
|
-
def self.schema(
|
223
|
+
def self.schema(_config)
|
217
224
|
toplevel_required = []
|
218
225
|
schema = {
|
219
226
|
"max_msg_size" => {
|
@@ -320,16 +327,10 @@ module MU
|
|
320
327
|
failq.delete("failqueue")
|
321
328
|
ok = false if !configurator.insertKitten(failq, "msg_queues")
|
322
329
|
queue['failqueue']['name'] = failq['name']
|
323
|
-
queue[
|
324
|
-
"name" => failq['name'],
|
325
|
-
"type" => "msg_queue"
|
326
|
-
}
|
330
|
+
MU::Config.addDependency(queue, failq["name"], "msg_queue")
|
327
331
|
else
|
328
332
|
if configurator.haveLitterMate?(queue['failqueue']['name'], "msg_queue")
|
329
|
-
queue['
|
330
|
-
"name" => queue['failqueue']['name'],
|
331
|
-
"type" => "msg_queue"
|
332
|
-
}
|
333
|
+
MU::Config.addDependency(queue, queue['failqueue']['name'], "msg_queue")
|
333
334
|
else
|
334
335
|
failq = MU::Cloud::AWS::MsgQueue.find(cloud_id: queue['failqueue']['name'])
|
335
336
|
if !failq
|
@@ -382,7 +383,7 @@ module MU
|
|
382
383
|
end
|
383
384
|
begin
|
384
385
|
MU::Cloud::AWS.kms(region: queue['region']).describe_key(key_id: queue['kms']['key_id'])
|
385
|
-
rescue Aws::KMS::Errors::NotFoundException
|
386
|
+
rescue Aws::KMS::Errors::NotFoundException
|
386
387
|
MU.log "KMS key '#{queue['kms']['key_id']}' specified in Queue '#{queue['name']}' was not found.", MU::ERR, details: "Key IDs are of the form bf64a093-2c3d-46fa-0d4f-8232fa7ed53. Keys can be created at https://console.aws.amazon.com/iam/home#/encryptionKeys/#{queue['region']}"
|
387
388
|
ok = false
|
388
389
|
end
|
@@ -164,6 +164,8 @@ module MU
|
|
164
164
|
# @param region [String]: The cloud provider region
|
165
165
|
# @return [void]
|
166
166
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
167
|
+
MU.log "AWS::NoSQLDb.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
168
|
+
|
167
169
|
resp = MU::Cloud::AWS.dynamo(credentials: credentials, region: region).list_tables
|
168
170
|
if resp and resp.table_names
|
169
171
|
resp.table_names.each { |table|
|
@@ -178,16 +180,23 @@ module MU
|
|
178
180
|
begin
|
179
181
|
tags = MU::Cloud::AWS.dynamo(credentials: credentials, region: region).list_tags_of_resource(resource_arn: desc.table_arn)
|
180
182
|
if tags and tags.tags
|
183
|
+
deploy_match = false
|
184
|
+
master_match = false
|
181
185
|
tags.tags.each { |tag|
|
182
186
|
if tag.key == "MU-ID" and tag.value == MU.deploy_id
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
+
deploy_match = true
|
188
|
+
elsif tag.key == "MU-MASTER-IP" and tag.value == MU.mu_public_ip
|
189
|
+
master_match = true
|
187
190
|
end
|
188
191
|
}
|
192
|
+
if deploy_match and (master_match or ignoremaster)
|
193
|
+
MU.log "Deleting DynamoDB table #{desc.table_name}"
|
194
|
+
if !noop
|
195
|
+
MU::Cloud::AWS.dynamo(credentials: credentials, region: region).delete_table(table_name: desc.table_name)
|
196
|
+
end
|
197
|
+
end
|
189
198
|
end
|
190
|
-
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
|
199
|
+
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
|
191
200
|
end
|
192
201
|
|
193
202
|
}
|
@@ -236,9 +245,9 @@ module MU
|
|
236
245
|
end
|
237
246
|
|
238
247
|
# Cloud-specific configuration properties.
|
239
|
-
# @param
|
248
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
240
249
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
241
|
-
def self.schema(
|
250
|
+
def self.schema(_config)
|
242
251
|
toplevel_required = ["attributes"]
|
243
252
|
|
244
253
|
|
@@ -360,9 +369,9 @@ module MU
|
|
360
369
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::nosqldbs}, bare and unvalidated.
|
361
370
|
|
362
371
|
# @param db [Hash]: The resource to process and validate
|
363
|
-
# @param
|
372
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
364
373
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
365
|
-
def self.validateConfig(db,
|
374
|
+
def self.validateConfig(db, _configurator)
|
366
375
|
ok = true
|
367
376
|
|
368
377
|
partition = nil
|
@@ -399,8 +408,6 @@ module MU
|
|
399
408
|
ok
|
400
409
|
end
|
401
410
|
|
402
|
-
private
|
403
|
-
|
404
411
|
end
|
405
412
|
end
|
406
413
|
end
|
@@ -66,12 +66,17 @@ module MU
|
|
66
66
|
# @param region [String]: The cloud provider region
|
67
67
|
# @return [void]
|
68
68
|
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
69
|
+
MU.log "AWS::Notifier.cleanup: need to support flags['known']", MU::DEBUG, details: flags
|
70
|
+
MU.log "Placeholder: AWS Notifier artifacts do not support tags, so ignoremaster cleanup flag has no effect", MU::DEBUG, details: ignoremaster
|
71
|
+
|
69
72
|
MU::Cloud::AWS.sns(region: region, credentials: credentials).list_topics.topics.each { |topic|
|
70
73
|
if topic.topic_arn.match(MU.deploy_id)
|
71
74
|
# We don't have a way to tag our SNS topics, so we will delete any topic that has the MU-ID in its ARN.
|
72
75
|
# This may fail to find notifier groups in some cases (eg. cache_cluster) so we might want to delete from each API as well.
|
73
|
-
MU
|
74
|
-
|
76
|
+
MU.log "Deleting SNS topic: #{topic.topic_arn}"
|
77
|
+
if !noop
|
78
|
+
MU::Cloud::AWS.sns(region: region, credentials: credentials).delete_topic(topic_arn: topic.topic_arn)
|
79
|
+
end
|
75
80
|
end
|
76
81
|
}
|
77
82
|
end
|
@@ -116,9 +121,9 @@ module MU
|
|
116
121
|
end
|
117
122
|
|
118
123
|
# Cloud-specific configuration properties.
|
119
|
-
# @param
|
124
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
120
125
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
121
|
-
def self.schema(
|
126
|
+
def self.schema(_config)
|
122
127
|
toplevel_required = []
|
123
128
|
schema = {
|
124
129
|
"subscriptions" => {
|
@@ -143,9 +148,9 @@ module MU
|
|
143
148
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::notifier}, bare and unvalidated.
|
144
149
|
|
145
150
|
# @param notifier [Hash]: The resource to process and validate
|
146
|
-
# @param
|
151
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
147
152
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
148
|
-
def self.validateConfig(notifier,
|
153
|
+
def self.validateConfig(notifier, _configurator)
|
149
154
|
ok = true
|
150
155
|
|
151
156
|
if notifier['subscriptions']
|
@@ -43,7 +43,7 @@ module MU
|
|
43
43
|
|
44
44
|
policy_name = @mu_name+"-"+policy.keys.first.upcase
|
45
45
|
MU.log "Creating IAM policy #{policy_name}"
|
46
|
-
|
46
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_policy(
|
47
47
|
policy_name: policy_name,
|
48
48
|
path: "/"+@deploy.deploy_id+"/",
|
49
49
|
policy_document: JSON.generate(policy.values.first),
|
@@ -56,8 +56,8 @@ module MU
|
|
56
56
|
MU.log "Creating IAM role #{@mu_name}"
|
57
57
|
@cloud_id = @mu_name
|
58
58
|
path = @config['strip_path'] ? nil : "/"+@deploy.deploy_id+"/"
|
59
|
-
|
60
|
-
path:
|
59
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_role(
|
60
|
+
path: path,
|
61
61
|
role_name: @mu_name,
|
62
62
|
description: "Generated by Mu",
|
63
63
|
assume_role_policy_document: gen_assume_role_policy_doc,
|
@@ -89,7 +89,6 @@ module MU
|
|
89
89
|
end
|
90
90
|
|
91
91
|
if @config['raw_policies'] or @config['attachable_policies']
|
92
|
-
attached_policies = []
|
93
92
|
configured_policies = []
|
94
93
|
|
95
94
|
if @config['raw_policies']
|
@@ -128,7 +127,7 @@ module MU
|
|
128
127
|
|
129
128
|
# XXX not sure we're binding these sanely, validate that
|
130
129
|
if @config['raw_policies']
|
131
|
-
|
130
|
+
MU::Cloud::AWS::Role.manageRawPolicies(
|
132
131
|
@config['raw_policies'],
|
133
132
|
basename: @deploy.getResourceName(@config['name']),
|
134
133
|
credentials: @credentials
|
@@ -183,7 +182,7 @@ module MU
|
|
183
182
|
desc
|
184
183
|
end
|
185
184
|
|
186
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
185
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
187
186
|
MU.log "Creating IAM policy #{policy_name}", details: policy.values.first
|
188
187
|
MU::Cloud::AWS.iam(credentials: credentials).create_policy(
|
189
188
|
policy_name: policy_name,
|
@@ -202,65 +201,72 @@ module MU
|
|
202
201
|
def arn
|
203
202
|
desc = cloud_desc
|
204
203
|
if desc["role"]
|
205
|
-
desc[
|
204
|
+
if desc['role'].is_a?(Hash)
|
205
|
+
desc["role"][:arn] # why though
|
206
|
+
else
|
207
|
+
desc["role"].arn
|
208
|
+
end
|
206
209
|
else
|
207
210
|
nil
|
208
211
|
end
|
209
212
|
end
|
210
213
|
|
214
|
+
@cloud_desc_cache = nil
|
211
215
|
# Return a hash containing a +role+ element and a +policies+ element,
|
212
216
|
# populated with one or both depending on what this resource has
|
213
217
|
# defined.
|
214
|
-
def cloud_desc
|
215
|
-
|
218
|
+
def cloud_desc(use_cache: true)
|
219
|
+
return @cloud_desc_cache if @cloud_desc_cache and use_cache
|
220
|
+
|
221
|
+
@cloud_desc_cache = {}
|
216
222
|
if @config['bare_policies']
|
217
223
|
if @cloud_id
|
218
224
|
pol_desc = MU::Cloud::AWS::Role.find(credentials: @credentials, cloud_id: @cloud_id).values.first
|
219
225
|
if pol_desc
|
220
|
-
|
221
|
-
return
|
226
|
+
@cloud_desc_cache['policies'] = [pol_desc]
|
227
|
+
return @cloud_desc_cache
|
222
228
|
end
|
223
229
|
end
|
224
230
|
|
225
231
|
if @deploy and @deploy.deploy_id
|
226
|
-
|
232
|
+
@cloud_desc_cache["policies"] = MU::Cloud::AWS.iam(credentials: @credentials).list_policies(
|
227
233
|
path_prefix: "/"+@deploy.deploy_id+"/"
|
228
234
|
).policies
|
229
|
-
|
235
|
+
@cloud_desc_cache["policies"].reject! { |p|
|
230
236
|
!p.policy_name.match(/^#{Regexp.quote(@mu_name)}-/)
|
231
237
|
}
|
232
238
|
# this is quasi-wrong because we can be mulitple cloud is, but
|
233
239
|
# we can't really set this type to has_multiples because that's
|
234
240
|
# just how managed policies work not anything else, goddammit
|
235
241
|
# AWS why can't you just bundle everything in roles
|
236
|
-
if
|
237
|
-
@cloud_id ||=
|
242
|
+
if @cloud_desc_cache["policies"] and @cloud_desc_cache["policies"].size > 0
|
243
|
+
@cloud_id ||= @cloud_desc_cache["policies"].first.arn
|
238
244
|
end
|
239
245
|
end
|
240
246
|
else
|
241
247
|
if @cloud_id.match(/^arn:aws(:?-us-gov)?:[^:]*:[^:]*:\d*:policy\//)
|
242
248
|
pol_desc = MU::Cloud::AWS::Role.find(credentials: @credentials, cloud_id: @cloud_id).values.first
|
243
249
|
if pol_desc
|
244
|
-
|
245
|
-
return
|
250
|
+
@cloud_desc_cache['policies'] = [pol_desc]
|
251
|
+
return @cloud_desc_cache
|
246
252
|
end
|
247
253
|
end
|
248
254
|
begin
|
249
|
-
|
250
|
-
|
255
|
+
@cloud_desc_cache['role'] = MU::Cloud::AWS::Role.find(credentials: @credentials, cloud_id: @cloud_id).values.first
|
256
|
+
@cloud_desc_cache['role'] ||= MU::Cloud::AWS::Role.find(credentials: @credentials, cloud_id: @mu_name).values.first
|
251
257
|
MU::Cloud::AWS.iam(credentials: @credentials).list_attached_role_policies(
|
252
258
|
role_name: @mu_name
|
253
259
|
).attached_policies.each { |p|
|
254
|
-
|
255
|
-
|
260
|
+
@cloud_desc_cache["policies"] ||= []
|
261
|
+
@cloud_desc_cache["policies"] << MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
|
256
262
|
policy_arn: p.policy_arn
|
257
263
|
).policy
|
258
264
|
}
|
259
265
|
|
260
266
|
inline = MU::Cloud::AWS.iam(credentials: @credentials).list_role_policies(role_name: @mu_name).policy_names
|
261
267
|
inline.each { |pol_name|
|
262
|
-
|
263
|
-
|
268
|
+
@cloud_desc_cache["policies"] ||= []
|
269
|
+
@cloud_desc_cache["policies"] << MU::Cloud::AWS.iam(credentials: @credentials).get_role_policy(
|
264
270
|
role_name: @mu_name,
|
265
271
|
policy_name: pol_name
|
266
272
|
)
|
@@ -270,9 +276,9 @@ rescue ::Aws::IAM::Errors::ValidationError => e
|
|
270
276
|
MU.log @cloud_id+" "+@mu_name, MU::WARN, details: e.inspect
|
271
277
|
end
|
272
278
|
end
|
273
|
-
|
279
|
+
@cloud_desc_cache['cloud_id'] ||= @cloud_id
|
274
280
|
|
275
|
-
|
281
|
+
@cloud_desc_cache
|
276
282
|
end
|
277
283
|
|
278
284
|
# Return the metadata for this user cofiguration
|
@@ -284,26 +290,25 @@ end
|
|
284
290
|
# Insert a new target entity into an existing policy.
|
285
291
|
# @param policy [String]: The name of the policy to which we're appending, which must already exist as part of this role resource
|
286
292
|
# @param targets [Array<String>]: The target resource. If +target_type+ isn't specified, this should be a fully-resolved ARN.
|
287
|
-
|
288
|
-
def injectPolicyTargets(policy, targets, mu_type = nil)
|
293
|
+
def injectPolicyTargets(policy, targets)
|
289
294
|
if !policy.match(/^#{@deploy.deploy_id}/)
|
290
295
|
policy = @mu_name+"-"+policy.upcase
|
291
296
|
end
|
292
|
-
|
293
|
-
my_policies = cloud_desc["policies"]
|
297
|
+
my_policies = cloud_desc(use_cache: false)["policies"]
|
294
298
|
my_policies ||= []
|
295
|
-
|
299
|
+
|
300
|
+
seen_policy = false
|
296
301
|
my_policies.each { |p|
|
297
302
|
if p.policy_name == policy
|
303
|
+
seen_policy = true
|
298
304
|
old = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy_version(
|
299
305
|
policy_arn: p.arn,
|
300
306
|
version_id: p.default_version_id
|
301
307
|
).policy_version
|
302
308
|
|
303
309
|
doc = JSON.parse URI.decode_www_form_component old.document
|
304
|
-
|
305
310
|
need_update = false
|
306
|
-
|
311
|
+
|
307
312
|
doc["Statement"].each { |s|
|
308
313
|
targets.each { |target|
|
309
314
|
target_string = target
|
@@ -332,6 +337,10 @@ end
|
|
332
337
|
end
|
333
338
|
end
|
334
339
|
}
|
340
|
+
|
341
|
+
if !seen_policy
|
342
|
+
MU.log "Was given new targets for policy #{policy}, but I don't see any such policy attached to role #{@cloud_id}", MU::WARN, details: targets
|
343
|
+
end
|
335
344
|
end
|
336
345
|
|
337
346
|
# Delete an IAM policy, along with attendant versions and attachments.
|
@@ -409,9 +418,8 @@ end
|
|
409
418
|
# Remove all roles associated with the currently loaded deployment.
|
410
419
|
# @param noop [Boolean]: If true, will only print what would be done
|
411
420
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
412
|
-
# @param region [String]: The cloud provider region
|
413
421
|
# @return [void]
|
414
|
-
def self.cleanup(noop: false, ignoremaster: false,
|
422
|
+
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
415
423
|
|
416
424
|
resp = MU::Cloud::AWS.iam(credentials: credentials).list_policies(
|
417
425
|
path_prefix: "/"+MU.deploy_id+"/"
|
@@ -438,12 +446,18 @@ end
|
|
438
446
|
# check tags. Hardly seems efficient.
|
439
447
|
desc = MU::Cloud::AWS.iam(credentials: credentials).get_role(role_name: r.role_name)
|
440
448
|
if desc.role and desc.role.tags and desc.role.tags
|
449
|
+
master_match = false
|
450
|
+
deploy_match = false
|
441
451
|
desc.role.tags.each { |t|
|
442
452
|
if t.key == "MU-ID" and t.value == MU.deploy_id
|
443
|
-
|
444
|
-
|
453
|
+
deploy_match = true
|
454
|
+
elsif t.key == "MU-MASTER-IP" and t.value == MU.mu_public_ip
|
455
|
+
master_match = true
|
445
456
|
end
|
446
457
|
}
|
458
|
+
if deploy_match and (master_match or ignoremaster)
|
459
|
+
deleteme << r
|
460
|
+
end
|
447
461
|
end
|
448
462
|
}
|
449
463
|
|
@@ -481,7 +495,7 @@ end
|
|
481
495
|
MU::Cloud::AWS.iam(credentials: credentials).delete_instance_profile(instance_profile_name: r.role_name)
|
482
496
|
rescue Aws::IAM::Errors::ValidationError => e
|
483
497
|
MU.log "Cleaning up IAM role #{r.role_name}: #{e.inspect}", MU::WARN
|
484
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
498
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
485
499
|
end
|
486
500
|
|
487
501
|
MU::Cloud::AWS.iam(credentials: credentials).delete_role(
|
@@ -519,7 +533,7 @@ end
|
|
519
533
|
end
|
520
534
|
rescue ::Aws::IAM::Errors::NoSuchEntity
|
521
535
|
end
|
522
|
-
|
536
|
+
|
523
537
|
else
|
524
538
|
marker = nil
|
525
539
|
begin
|
@@ -552,7 +566,7 @@ end
|
|
552
566
|
# Reverse-map our cloud description into a runnable config hash.
|
553
567
|
# We assume that any values we have in +@config+ are placeholders, and
|
554
568
|
# calculate our own accordingly based on what's live in the cloud.
|
555
|
-
def toKitten(
|
569
|
+
def toKitten(**_args)
|
556
570
|
bok = {
|
557
571
|
"cloud" => "AWS",
|
558
572
|
"credentials" => @config['credentials'],
|
@@ -601,14 +615,13 @@ end
|
|
601
615
|
)
|
602
616
|
JSON.parse(URI.decode(version.policy_version.document))
|
603
617
|
end
|
604
|
-
|
605
618
|
bok["policies"] = MU::Cloud::AWS::Role.doc2MuPolicies(pol.policy_name, doc, bok["policies"])
|
606
619
|
end
|
607
620
|
}
|
608
621
|
|
609
622
|
return bok if @config['bare_policies']
|
610
623
|
end
|
611
|
-
|
624
|
+
|
612
625
|
if desc.tags and desc.tags.size > 0
|
613
626
|
bok["tags"] = MU.structToHash(desc.tags, stringify_keys: true)
|
614
627
|
end
|
@@ -681,6 +694,7 @@ end
|
|
681
694
|
end
|
682
695
|
|
683
696
|
bok["attachable_policies"].uniq! if bok["attachable_policies"]
|
697
|
+
bok["name"].gsub!(/[^a-zA-Z0-9_\-]/, "_")
|
684
698
|
|
685
699
|
bok
|
686
700
|
end
|
@@ -693,6 +707,10 @@ end
|
|
693
707
|
def self.doc2MuPolicies(basename, doc, policies = [])
|
694
708
|
policies ||= []
|
695
709
|
|
710
|
+
if !doc["Statement"].is_a?(Array)
|
711
|
+
doc["Statement"] = [doc["Statement"]]
|
712
|
+
end
|
713
|
+
|
696
714
|
doc["Statement"].each { |s|
|
697
715
|
if !s["Action"]
|
698
716
|
MU.log "Statement in policy document for #{basename} didn't have an Action field", MU::WARN, details: doc
|
@@ -721,7 +739,7 @@ end
|
|
721
739
|
"targets" => s["Resource"].map { |r|
|
722
740
|
if r.match(/^arn:aws(-us-gov)?:([^:]+):.*?:([^:]*)$/)
|
723
741
|
# XXX which cases even count for blind references to sibling resources?
|
724
|
-
|
742
|
+
if Regexp.last_match[1] == "s3"
|
725
743
|
"bucket"
|
726
744
|
elsif Regexp.last_match[1]
|
727
745
|
MU.log "Service #{Regexp.last_match[1]} to type...", MU::WARN, details: r
|
@@ -741,7 +759,7 @@ end
|
|
741
759
|
|
742
760
|
# Attach this role or group of loose policies to the specified entity.
|
743
761
|
# @param entitytype [String]: The type of entity (user, group or role for policies; instance_profile for roles)
|
744
|
-
def bindTo(entitytype, entityname
|
762
|
+
def bindTo(entitytype, entityname)
|
745
763
|
if entitytype == "instance_profile"
|
746
764
|
begin
|
747
765
|
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(
|
@@ -754,7 +772,7 @@ end
|
|
754
772
|
role_name: @mu_name
|
755
773
|
)
|
756
774
|
end
|
757
|
-
rescue
|
775
|
+
rescue StandardError => e
|
758
776
|
MU.log "Error binding role #{@mu_name} to instance profile #{entityname}: #{e.message}", MU::ERR
|
759
777
|
raise e
|
760
778
|
end
|
@@ -783,7 +801,6 @@ end
|
|
783
801
|
rescue Aws::IAM::Errors::NoSuchEntity => e
|
784
802
|
if subpaths.size > 0
|
785
803
|
p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/#{subpaths.shift}/"+policy
|
786
|
-
retried = true
|
787
804
|
retry
|
788
805
|
end
|
789
806
|
raise e
|
@@ -833,6 +850,7 @@ end
|
|
833
850
|
else
|
834
851
|
raise MuError, "Invalid entitytype '#{entitytype}' passed to MU::Cloud::AWS::Role.bindTo. Must be be one of: user, group, role, instance_profile"
|
835
852
|
end
|
853
|
+
cloud_desc(use_cache: false)
|
836
854
|
end
|
837
855
|
|
838
856
|
# Create an instance profile for EC2 instances, named identically and
|
@@ -847,7 +865,7 @@ end
|
|
847
865
|
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_instance_profile(
|
848
866
|
instance_profile_name: @mu_name
|
849
867
|
)
|
850
|
-
rescue Aws::IAM::Errors::EntityAlreadyExists
|
868
|
+
rescue Aws::IAM::Errors::EntityAlreadyExists
|
851
869
|
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(
|
852
870
|
instance_profile_name: @mu_name
|
853
871
|
)
|
@@ -905,13 +923,13 @@ end
|
|
905
923
|
end
|
906
924
|
|
907
925
|
# Cloud-specific configuration properties.
|
908
|
-
# @param
|
926
|
+
# @param _config [MU::Config]: The calling MU::Config object
|
909
927
|
# @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
|
910
|
-
def self.schema(
|
928
|
+
def self.schema(_config)
|
911
929
|
toplevel_required = []
|
912
930
|
aws_resource_types = MU::Cloud.resource_types.keys.reject { |t|
|
913
931
|
begin
|
914
|
-
MU::Cloud.
|
932
|
+
MU::Cloud.resourceClass("AWS", t)
|
915
933
|
false
|
916
934
|
rescue MuCloudResourceNotImplemented
|
917
935
|
true
|
@@ -1012,10 +1030,9 @@ end
|
|
1012
1030
|
subpaths = ["service-role", "aws-service-role", "job-function"]
|
1013
1031
|
begin
|
1014
1032
|
MU::Cloud::AWS.iam(credentials: credentials).get_policy(policy_arn: arn)
|
1015
|
-
rescue Aws::IAM::Errors::NoSuchEntity
|
1033
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
1016
1034
|
if subpaths.size > 0
|
1017
1035
|
arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(region) ? "aws-us-gov" : "aws")+":iam::aws:policy/#{subpaths.shift}/"+ref["id"]
|
1018
|
-
retried = true
|
1019
1036
|
retry
|
1020
1037
|
end
|
1021
1038
|
MU.log "No such canned AWS IAM policy '#{arn}'", MU::ERR
|
@@ -1029,9 +1046,9 @@ end
|
|
1029
1046
|
|
1030
1047
|
# Cloud-specific pre-processing of {MU::Config::BasketofKittens::roles}, bare and unvalidated.
|
1031
1048
|
# @param role [Hash]: The resource to process and validate
|
1032
|
-
# @param
|
1049
|
+
# @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
|
1033
1050
|
# @return [Boolean]: True if validation succeeded, False otherwise
|
1034
|
-
def self.validateConfig(role,
|
1051
|
+
def self.validateConfig(role, _configurator)
|
1035
1052
|
ok = true
|
1036
1053
|
|
1037
1054
|
# munge things declared with the deprecated import keyword into
|
@@ -1074,11 +1091,7 @@ end
|
|
1074
1091
|
role['policies'].each { |policy|
|
1075
1092
|
policy['targets'].each { |target|
|
1076
1093
|
if target['type']
|
1077
|
-
role['
|
1078
|
-
role['dependencies'] << {
|
1079
|
-
"name" => target['identifier'],
|
1080
|
-
"type" => target['type']
|
1081
|
-
}
|
1094
|
+
MU::Config.addDependency(role, target['identifier'], target['type'])
|
1082
1095
|
end
|
1083
1096
|
}
|
1084
1097
|
}
|
@@ -1094,9 +1107,7 @@ end
|
|
1094
1107
|
# @param policies [Array<Hash>]: One or more policy chunks
|
1095
1108
|
# @param deploy_obj [MU::MommaCat]: Deployment object to use when looking up sibling Mu resources
|
1096
1109
|
# @return [Array<Hash>]
|
1097
|
-
def self.genPolicyDocument(policies, deploy_obj: nil)
|
1098
|
-
iam_policies = []
|
1099
|
-
|
1110
|
+
def self.genPolicyDocument(policies, deploy_obj: nil, bucket_style: false)
|
1100
1111
|
if policies
|
1101
1112
|
name = nil
|
1102
1113
|
doc = {
|
@@ -1134,12 +1145,21 @@ end
|
|
1134
1145
|
)
|
1135
1146
|
if sibling
|
1136
1147
|
id = sibling.cloudobj.arn
|
1137
|
-
|
1148
|
+
if bucket_style
|
1149
|
+
statement["Principal"] << { "AWS" => id }
|
1150
|
+
else
|
1151
|
+
statement["Principal"] << id
|
1152
|
+
end
|
1138
1153
|
else
|
1139
1154
|
raise MuError, "Couldn't find a #{grantee["type"]} named #{grantee["identifier"]} when generating IAM policy"
|
1140
1155
|
end
|
1141
1156
|
else
|
1142
|
-
|
1157
|
+
bucket_prefix = grantee["identifier"].match(/^[^\.]+\.amazonaws\.com$/) ? "Service" : "AWS"
|
1158
|
+
if bucket_style
|
1159
|
+
statement["Principal"] << { bucket_prefix => grantee["identifier"] }
|
1160
|
+
else
|
1161
|
+
statement["Principal"] << grantee["identifier"]
|
1162
|
+
end
|
1143
1163
|
end
|
1144
1164
|
}
|
1145
1165
|
if policy["grant_to"].size == 1
|
@@ -1162,9 +1182,11 @@ end
|
|
1162
1182
|
stream_id = id.sub(/:([^:]+)$/, ":log-stream:*")
|
1163
1183
|
# "arn:aws:logs:us-east-2:accountID:log-group:log_group_name:log-stream:CloudTrail_log_stream_name_prefix*"
|
1164
1184
|
statement["Resource"] << stream_id
|
1185
|
+
elsif id.match(/:s3:/)
|
1186
|
+
statement["Resource"] << id+"/*"
|
1165
1187
|
end
|
1166
1188
|
else
|
1167
|
-
raise MuError, "Couldn't find a #{target["
|
1189
|
+
raise MuError, "Couldn't find a #{target["type"]} named #{target["identifier"]} when generating IAM policy"
|
1168
1190
|
end
|
1169
1191
|
else
|
1170
1192
|
target["identifier"] += target["path"] if target["path"]
|
@@ -1180,6 +1202,32 @@ end
|
|
1180
1202
|
[]
|
1181
1203
|
end
|
1182
1204
|
|
1205
|
+
# Update a policy, handling deletion of old versions as needed
|
1206
|
+
# @param arn [String]:
|
1207
|
+
# @param doc [Hash]:
|
1208
|
+
# @param credentials [String]:
|
1209
|
+
def self.update_policy(arn, doc, credentials: nil)
|
1210
|
+
# XXX this is just blindly replacing identical versions, when it should check
|
1211
|
+
# and guard
|
1212
|
+
begin
|
1213
|
+
MU::Cloud::AWS.iam(credentials: credentials).create_policy_version(
|
1214
|
+
policy_arn: arn,
|
1215
|
+
set_as_default: true,
|
1216
|
+
policy_document: JSON.generate(doc)
|
1217
|
+
)
|
1218
|
+
rescue Aws::IAM::Errors::LimitExceeded
|
1219
|
+
delete_version = MU::Cloud::AWS.iam(credentials: credentials).list_policy_versions(
|
1220
|
+
policy_arn: arn,
|
1221
|
+
).versions.last.version_id
|
1222
|
+
MU.log "Purging oldest version (#{delete_version}) of IAM policy #{arn}", MU::NOTICE
|
1223
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_policy_version(
|
1224
|
+
policy_arn: arn,
|
1225
|
+
version_id: delete_version
|
1226
|
+
)
|
1227
|
+
retry
|
1228
|
+
end
|
1229
|
+
end
|
1230
|
+
|
1183
1231
|
private
|
1184
1232
|
|
1185
1233
|
# Convert entries from the cloud-neutral @config['policies'] list into
|
@@ -1261,28 +1309,6 @@ end
|
|
1261
1309
|
MU::Cloud::AWS::Role.update_policy(arn, doc, credentials: @credentials)
|
1262
1310
|
end
|
1263
1311
|
|
1264
|
-
# Update a policy, handling deletion of old versions as needed
|
1265
|
-
def self.update_policy(arn, doc, credentials: nil)
|
1266
|
-
# XXX this is just blindly replacing identical versions, when it should check
|
1267
|
-
# and guard
|
1268
|
-
begin
|
1269
|
-
MU::Cloud::AWS.iam(credentials: credentials).create_policy_version(
|
1270
|
-
policy_arn: arn,
|
1271
|
-
set_as_default: true,
|
1272
|
-
policy_document: JSON.generate(doc)
|
1273
|
-
)
|
1274
|
-
rescue Aws::IAM::Errors::LimitExceeded => e
|
1275
|
-
delete_version = MU::Cloud::AWS.iam(credentials: credentials).list_policy_versions(
|
1276
|
-
policy_arn: arn,
|
1277
|
-
).versions.last.version_id
|
1278
|
-
MU.log "Purging oldest version (#{delete_version}) of IAM policy #{arn}", MU::NOTICE
|
1279
|
-
MU::Cloud::AWS.iam(credentials: credentials).delete_policy_version(
|
1280
|
-
policy_arn: arn,
|
1281
|
-
version_id: delete_version
|
1282
|
-
)
|
1283
|
-
retry
|
1284
|
-
end
|
1285
|
-
end
|
1286
1312
|
|
1287
1313
|
end
|
1288
1314
|
end
|